summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/ipxe/src/include')
-rw-r--r--qemu/roms/ipxe/src/include/.gitignore1
-rw-r--r--qemu/roms/ipxe/src/include/assert.h2
-rw-r--r--qemu/roms/ipxe/src/include/big_bswap.h35
-rw-r--r--qemu/roms/ipxe/src/include/byteswap.h185
-rw-r--r--qemu/roms/ipxe/src/include/compiler.h203
-rw-r--r--qemu/roms/ipxe/src/include/ctype.h118
-rw-r--r--qemu/roms/ipxe/src/include/curses.h2
-rw-r--r--qemu/roms/ipxe/src/include/elf.h277
-rw-r--r--qemu/roms/ipxe/src/include/endian.h31
-rw-r--r--qemu/roms/ipxe/src/include/errno.h6
-rw-r--r--qemu/roms/ipxe/src/include/getopt.h2
-rw-r--r--qemu/roms/ipxe/src/include/hci/ifmgmt_cmd.h6
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/acpi.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/aes.h44
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ansicol.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ansiesc.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/aoe.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/api.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/arp.h6
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/asn1.h55
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ata.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/base16.h35
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/base64.h7
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/bigint.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/bitbash.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/bitmap.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/bitops.h6
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/blockdev.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/blocktrans.h38
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/bofm.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/cbc.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/cdc.h55
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/certstore.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/chap.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/cms.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/command.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/console.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/cpio.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/crc32.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/crypto.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/deflate.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/device.h33
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/dhcp.h12
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/dhcpopts.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/dhcppkt.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/dhcpv6.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/dns.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/downloader.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/drbg.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ecb.h55
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/edd.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/editbox.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/editstring.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/ProcessorBind.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/Protocol/Rng.h158
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_autoboot.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_driver.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_entropy.h35
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_hii.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_pci.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_pci_api.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_reboot.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_smbios.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_snp.h27
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_strings.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_time.h20
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_timer.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_uaccess.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_umalloc.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_utils.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_watchdog.h31
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/efi/efi_wrap.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/eisa.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/elf.h13
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/eltorito.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/entropy.h3
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/errfile.h37
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/errno/efi.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/errno/linux.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/errortab.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/eth_slow.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ethernet.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/fakedhcp.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/fault.h53
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/fbcon.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/fc.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/fcels.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/fcns.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/fcoe.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/fcp.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/features.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/fragment.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ftp.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/gdbserial.h13
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/gdbstub.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/gdbudp.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/hash_df.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/hidemem.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/hmac.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/hmac_drbg.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/http.h490
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/hyperv.h232
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/i2c.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ib_cm.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ib_mad.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ib_mcast.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ib_mi.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ib_packet.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ib_pathrec.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ib_sma.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ib_smc.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/icmp.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/icmpv6.h14
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/if_arp.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/if_ether.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/image.h3
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/in.h40
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/infiniband.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/init.h9
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/interface.h7
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/io.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/iobuf.h3
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ip.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ipoib.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ipstat.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ipv6.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/isa_ids.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/isapnp.h6
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/iscsi.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/iso9660.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/isqrt.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/job.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/jumpscroll.h50
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/keymap.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/keys.h4
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/linebuf.h14
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/lineconsole.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/linux/linux_entropy.h12
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/linux/linux_nap.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/linux/linux_pci.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/linux/linux_smbios.h4
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/linux/linux_time.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/linux/linux_timer.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/linux/linux_uaccess.h126
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/linux/linux_umalloc.h6
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/linux_compat.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/list.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/login_ui.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/malloc.h4
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/mca.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/md5.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/memblock.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/menu.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/mii.h4
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/monojob.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/mount.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/nap.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ndp.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/neighbour.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/net80211_err.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/netdevice.h41
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/nfs.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/nfs_open.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/nfs_uri.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/null_entropy.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/null_nap.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/null_reboot.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/null_sanboot.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/null_time.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/nvo.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/nvs.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/nvsvpd.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ocsp.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/oncrpc.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/oncrpc_iob.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/open.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/params.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/parseopt.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pccrc.h447
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pccrd.h47
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pccrr.h376
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pci.h382
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pci_ids.h351
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pci_io.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pcibackup.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pcivpd.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/peerblk.h144
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/peerdisc.h116
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/peermux.h73
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pending.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/ping.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pinger.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pixbuf.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/png.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pnm.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/pool.h127
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/portmap.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/posix_io.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/privkey.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/process.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/profile.h16
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/random_nz.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/rarp.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/rbg.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/reboot.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/refcnt.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/resolv.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/retry.h36
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/rndis.h370
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/rootcert.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/rotate.h22
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/rsa.h3
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/sanboot.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/script.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/scsi.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/segment.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/serial.h11
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/settings.h3
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/settings_ui.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/sha256.h17
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/sha512.h98
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/shell.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/smbios.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/socket.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/spi.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/spi_bit.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/stp.h76
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/string.h14
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/syslog.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/tables.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/tcp.h53
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/tcpip.h11
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/test.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/tftp.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/time.h3
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/timer.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/tls.h30
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/uaccess.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/uart.h132
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/udp.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/umalloc.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/uri.h4
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/usb.h1319
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/usbhid.h106
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/usbnet.h62
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/uuid.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/validator.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/version.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/vlan.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/vmbus.h634
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/vsprintf.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/x509.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/xen.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/xenbus.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/xenevent.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/xengrant.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/xenmem.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/xenstore.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/xenver.h2
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/xfer.h4
-rw-r--r--qemu/roms/ipxe/src/include/ipxe/xferbuf.h78
-rw-r--r--qemu/roms/ipxe/src/include/libgen.h2
-rw-r--r--qemu/roms/ipxe/src/include/little_bswap.h37
-rw-r--r--qemu/roms/ipxe/src/include/nic.h19
-rw-r--r--qemu/roms/ipxe/src/include/readline/readline.h2
-rw-r--r--qemu/roms/ipxe/src/include/stdarg.h2
-rw-r--r--qemu/roms/ipxe/src/include/stddef.h40
-rw-r--r--qemu/roms/ipxe/src/include/stdint.h2
-rw-r--r--qemu/roms/ipxe/src/include/stdio.h2
-rw-r--r--qemu/roms/ipxe/src/include/stdlib.h30
-rw-r--r--qemu/roms/ipxe/src/include/string.h83
-rw-r--r--qemu/roms/ipxe/src/include/strings.h145
-rw-r--r--qemu/roms/ipxe/src/include/sys/time.h2
-rw-r--r--qemu/roms/ipxe/src/include/syslog.h2
-rw-r--r--qemu/roms/ipxe/src/include/time.h2
-rw-r--r--qemu/roms/ipxe/src/include/unistd.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/autoboot.h4
-rw-r--r--qemu/roms/ipxe/src/include/usr/dhcpmgmt.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/fcmgmt.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/ifmgmt.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/imgmgmt.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/imgtrust.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/ipstat.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/lotest.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/neighmgmt.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/pingmgmt.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/profstat.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/prompt.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/route.h2
-rw-r--r--qemu/roms/ipxe/src/include/usr/sync.h2
-rw-r--r--qemu/roms/ipxe/src/include/valgrind/memcheck.h311
-rw-r--r--qemu/roms/ipxe/src/include/valgrind/valgrind.h4538
-rw-r--r--qemu/roms/ipxe/src/include/wchar.h2
293 files changed, 11862 insertions, 1583 deletions
diff --git a/qemu/roms/ipxe/src/include/.gitignore b/qemu/roms/ipxe/src/include/.gitignore
deleted file mode 100644
index de1598ef3..000000000
--- a/qemu/roms/ipxe/src/include/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-.buildserial.h
diff --git a/qemu/roms/ipxe/src/include/assert.h b/qemu/roms/ipxe/src/include/assert.h
index a33f6017c..07f3ecb8c 100644
--- a/qemu/roms/ipxe/src/include/assert.h
+++ b/qemu/roms/ipxe/src/include/assert.h
@@ -10,7 +10,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef NDEBUG
#define ASSERTING 0
diff --git a/qemu/roms/ipxe/src/include/big_bswap.h b/qemu/roms/ipxe/src/include/big_bswap.h
deleted file mode 100644
index 6c375a573..000000000
--- a/qemu/roms/ipxe/src/include/big_bswap.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef ETHERBOOT_BIG_BSWAP_H
-#define ETHERBOOT_BIG_BSWAP_H
-
-#define htonll(x) (x)
-#define ntohll(x) (x)
-#define ntohl(x) (x)
-#define htonl(x) (x)
-#define ntohs(x) (x)
-#define htons(x) (x)
-#define cpu_to_le64(x) __bswap_64(x)
-#define cpu_to_le32(x) __bswap_32(x)
-#define cpu_to_le16(x) __bswap_16(x)
-#define cpu_to_be64(x) (x)
-#define cpu_to_be32(x) (x)
-#define cpu_to_be16(x) (x)
-#define le64_to_cpu(x) __bswap_64(x)
-#define le32_to_cpu(x) __bswap_32(x)
-#define le16_to_cpu(x) __bswap_16(x)
-#define be64_to_cpu(x) (x)
-#define be32_to_cpu(x) (x)
-#define be16_to_cpu(x) (x)
-#define cpu_to_le64s(x) __bswap_64s(x)
-#define cpu_to_le32s(x) __bswap_32s(x)
-#define cpu_to_le16s(x) __bswap_16s(x)
-#define cpu_to_be64s(x) do {} while (0)
-#define cpu_to_be32s(x) do {} while (0)
-#define cpu_to_be16s(x) do {} while (0)
-#define le64_to_cpus(x) __bswap_64s(x)
-#define le32_to_cpus(x) __bswap_32s(x)
-#define le16_to_cpus(x) __bswap_16s(x)
-#define be64_to_cpus(x) do {} while (0)
-#define be32_to_cpus(x) do {} while (0)
-#define be16_to_cpus(x) do {} while (0)
-
-#endif /* ETHERBOOT_BIG_BSWAP_H */
diff --git a/qemu/roms/ipxe/src/include/byteswap.h b/qemu/roms/ipxe/src/include/byteswap.h
index 466759cf8..d1028c579 100644
--- a/qemu/roms/ipxe/src/include/byteswap.h
+++ b/qemu/roms/ipxe/src/include/byteswap.h
@@ -1,59 +1,138 @@
-#ifndef ETHERBOOT_BYTESWAP_H
-#define ETHERBOOT_BYTESWAP_H
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include "endian.h"
-#include "bits/byteswap.h"
-
-#define __bswap_constant_16(x) \
- ((uint16_t)((((uint16_t)(x) & 0x00ff) << 8) | \
- (((uint16_t)(x) & 0xff00) >> 8)))
-
-#define __bswap_constant_32(x) \
- ((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \
- (((uint32_t)(x) & 0x0000ff00U) << 8) | \
- (((uint32_t)(x) & 0x00ff0000U) >> 8) | \
- (((uint32_t)(x) & 0xff000000U) >> 24)))
-
-#define __bswap_constant_64(x) \
- ((uint64_t)((((uint64_t)(x) & 0x00000000000000ffULL) << 56) | \
- (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
- (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
- (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
- (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
- (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
- (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
- (((uint64_t)(x) & 0xff00000000000000ULL) >> 56)))
-
-#define __bswap_16(x) \
- ((uint16_t)(__builtin_constant_p(x) ? \
- __bswap_constant_16(x) : \
- __bswap_variable_16(x)))
-
-#define __bswap_32(x) \
- ((uint32_t)(__builtin_constant_p(x) ? \
- __bswap_constant_32(x) : \
- __bswap_variable_32(x)))
-
-#define __bswap_64(x) \
- ((uint64_t)(__builtin_constant_p(x) ? \
- __bswap_constant_64(x) : \
- __bswap_variable_64(x)))
+#ifndef BYTESWAP_H
+#define BYTESWAP_H
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <endian.h>
+#include <bits/byteswap.h>
+
+/**
+ * Byte-swap a 16-bit constant
+ *
+ * @v value Constant value
+ * @ret swapped Byte-swapped value
+ */
+#define __bswap_constant_16( value ) \
+ ( ( ( (value) & 0x00ff ) << 8 ) | \
+ ( ( (value) & 0xff00 ) >> 8 ) )
+
+/**
+ * Byte-swap a 32-bit constant
+ *
+ * @v value Constant value
+ * @ret swapped Byte-swapped value
+ */
+#define __bswap_constant_32( value ) \
+ ( ( ( (value) & 0x000000ffUL ) << 24 ) | \
+ ( ( (value) & 0x0000ff00UL ) << 8 ) | \
+ ( ( (value) & 0x00ff0000UL ) >> 8 ) | \
+ ( ( (value) & 0xff000000UL ) >> 24 ) )
+
+/**
+ * Byte-swap a 64-bit constant
+ *
+ * @v value Constant value
+ * @ret swapped Byte-swapped value
+ */
+#define __bswap_constant_64( value ) \
+ ( ( ( (value) & 0x00000000000000ffULL ) << 56 ) | \
+ ( ( (value) & 0x000000000000ff00ULL ) << 40 ) | \
+ ( ( (value) & 0x0000000000ff0000ULL ) << 24 ) | \
+ ( ( (value) & 0x00000000ff000000ULL ) << 8 ) | \
+ ( ( (value) & 0x000000ff00000000ULL ) >> 8 ) | \
+ ( ( (value) & 0x0000ff0000000000ULL ) >> 24 ) | \
+ ( ( (value) & 0x00ff000000000000ULL ) >> 40 ) | \
+ ( ( (value) & 0xff00000000000000ULL ) >> 56 ) )
+
+/**
+ * Byte-swap a 16-bit value
+ *
+ * @v value Value
+ * @ret swapped Byte-swapped value
+ */
+#define __bswap_16( value ) \
+ ( __builtin_constant_p (value) ? \
+ ( ( uint16_t ) __bswap_constant_16 ( ( uint16_t ) (value) ) ) \
+ : __bswap_variable_16 (value) )
+#define bswap_16( value ) __bswap_16 (value)
+
+/**
+ * Byte-swap a 32-bit value
+ *
+ * @v value Value
+ * @ret swapped Byte-swapped value
+ */
+#define __bswap_32( value ) \
+ ( __builtin_constant_p (value) ? \
+ ( ( uint32_t ) __bswap_constant_32 ( ( uint32_t ) (value) ) ) \
+ : __bswap_variable_32 (value) )
+#define bswap_32( value ) __bswap_32 (value)
+
+/**
+ * Byte-swap a 64-bit value
+ *
+ * @v value Value
+ * @ret swapped Byte-swapped value
+ */
+#define __bswap_64( value ) \
+ ( __builtin_constant_p (value) ? \
+ ( ( uint64_t ) __bswap_constant_64 ( ( uint64_t ) (value) ) ) \
+ : __bswap_variable_64 (value) )
+#define bswap_64( value ) __bswap_64 (value)
#if __BYTE_ORDER == __LITTLE_ENDIAN
-#include "little_bswap.h"
+#define __cpu_to_leNN( bits, value ) (value)
+#define __cpu_to_beNN( bits, value ) __bswap_ ## bits (value)
+#define __leNN_to_cpu( bits, value ) (value)
+#define __beNN_to_cpu( bits, value ) __bswap_ ## bits (value)
+#define __cpu_to_leNNs( bits, ptr ) do { } while ( 0 )
+#define __cpu_to_beNNs( bits, ptr ) __bswap_ ## bits ## s (ptr)
+#define __leNN_to_cpus( bits, ptr ) do { } while ( 0 )
+#define __beNN_to_cpus( bits, ptr ) __bswap_ ## bits ## s (ptr)
#endif
+
#if __BYTE_ORDER == __BIG_ENDIAN
-#include "big_bswap.h"
+#define __cpu_to_leNN( bits, value ) __bswap_ ## bits (value)
+#define __cpu_to_beNN( bits, value ) (value)
+#define __leNN_to_cpu( bits, value ) __bswap_ ## bits (value)
+#define __beNN_to_cpu( bits, value ) (value)
+#define __cpu_to_leNNs( bits, ptr ) __bswap_ ## bits ## s (ptr)
+#define __cpu_to_beNNs( bits, ptr ) do { } while ( 0 )
+#define __leNN_to_cpus( bits, ptr ) __bswap_ ## bits ## s (ptr)
+#define __beNN_to_cpus( bits, ptr ) do { } while ( 0 )
#endif
-/* Make routines available to all */
-#define swap64(x) __bswap_64(x)
-#define swap32(x) __bswap_32(x)
-#define swap16(x) __bswap_16(x)
-#define bswap_64(x) __bswap_64(x)
-#define bswap_32(x) __bswap_32(x)
-#define bswap_16(x) __bswap_16(x)
-
-#endif /* ETHERBOOT_BYTESWAP_H */
+#define cpu_to_le16( value ) __cpu_to_leNN ( 16, value )
+#define cpu_to_le32( value ) __cpu_to_leNN ( 32, value )
+#define cpu_to_le64( value ) __cpu_to_leNN ( 64, value )
+#define cpu_to_be16( value ) __cpu_to_beNN ( 16, value )
+#define cpu_to_be32( value ) __cpu_to_beNN ( 32, value )
+#define cpu_to_be64( value ) __cpu_to_beNN ( 64, value )
+#define le16_to_cpu( value ) __leNN_to_cpu ( 16, value )
+#define le32_to_cpu( value ) __leNN_to_cpu ( 32, value )
+#define le64_to_cpu( value ) __leNN_to_cpu ( 64, value )
+#define be16_to_cpu( value ) __beNN_to_cpu ( 16, value )
+#define be32_to_cpu( value ) __beNN_to_cpu ( 32, value )
+#define be64_to_cpu( value ) __beNN_to_cpu ( 64, value )
+#define cpu_to_le16s( ptr ) __cpu_to_leNNs ( 16, ptr )
+#define cpu_to_le32s( ptr ) __cpu_to_leNNs ( 32, ptr )
+#define cpu_to_le64s( ptr ) __cpu_to_leNNs ( 64, ptr )
+#define cpu_to_be16s( ptr ) __cpu_to_beNNs ( 16, ptr )
+#define cpu_to_be32s( ptr ) __cpu_to_beNNs ( 32, ptr )
+#define cpu_to_be64s( ptr ) __cpu_to_beNNs ( 64, ptr )
+#define le16_to_cpus( ptr ) __leNN_to_cpus ( 16, ptr )
+#define le32_to_cpus( ptr ) __leNN_to_cpus ( 32, ptr )
+#define le64_to_cpus( ptr ) __leNN_to_cpus ( 64, ptr )
+#define be16_to_cpus( ptr ) __beNN_to_cpus ( 16, ptr )
+#define be32_to_cpus( ptr ) __beNN_to_cpus ( 32, ptr )
+#define be64_to_cpus( ptr ) __beNN_to_cpus ( 64, ptr )
+
+#define htonll( value ) cpu_to_be64 (value)
+#define ntohll( value ) be64_to_cpu (value)
+#define htonl( value ) cpu_to_be32 (value)
+#define ntohl( value ) be32_to_cpu (value)
+#define htons( value ) cpu_to_be16 (value)
+#define ntohs( value ) be16_to_cpu (value)
+
+#endif /* BYTESWAP_H */
diff --git a/qemu/roms/ipxe/src/include/compiler.h b/qemu/roms/ipxe/src/include/compiler.h
index 3f5c913a0..ca82f9523 100644
--- a/qemu/roms/ipxe/src/include/compiler.h
+++ b/qemu/roms/ipxe/src/include/compiler.h
@@ -57,101 +57,100 @@
* @{
*/
-/** Provide a symbol within this object file */
+/**
+ * Provide a symbol within this object file
+ *
+ * @v symbol Symbol name
+ */
#ifdef ASSEMBLY
-#define PROVIDE_SYMBOL( _sym ) \
- .section ".provided", "a", @nobits ; \
- .hidden _sym ; \
- .globl _sym ; \
- _sym: ; \
+#define PROVIDE_SYMBOL( symbol ) \
+ .section ".provided", "a", @nobits ; \
+ .hidden symbol ; \
+ .globl symbol ; \
+ symbol: ; \
.previous
-#else /* ASSEMBLY */
-#define PROVIDE_SYMBOL( _sym ) \
- char _sym[0] \
+#else
+#define PROVIDE_SYMBOL( symbol ) \
+ char symbol[0] \
__attribute__ (( section ( ".provided" ) ))
-#endif /* ASSEMBLY */
+#endif
-/** Require a symbol within this object file
+/**
+ * Request a symbol
+ *
+ * @v symbol Symbol name
*
- * The symbol is referenced by a relocation in a discarded section, so
- * if it is not available at link time the link will fail.
+ * Request a symbol to be included within the link. If the symbol
+ * cannot be found, the link will succeed anyway.
*/
#ifdef ASSEMBLY
-#define REQUIRE_SYMBOL( _sym ) \
- .section ".discard", "a", @progbits ; \
- .extern _sym ; \
- .long _sym ; \
- .previous
-#else /* ASSEMBLY */
-#define REQUIRE_SYMBOL( _sym ) \
- extern char _sym; \
- static char * _C2 ( _C2 ( __require_, _sym ), _C2 ( _, __LINE__ ) ) \
- __attribute__ (( section ( ".discard" ), used )) \
- = &_sym
+#define REQUEST_SYMBOL( symbol ) \
+ .equ __request_ ## symbol, symbol
+#else
+#define REQUEST_SYMBOL( symbol ) \
+ __asm__ ( ".equ __request_" #symbol ", " #symbol )
#endif
-/** Request that a symbol be available at runtime
+/**
+ * Require a symbol
+ *
+ * @v symbol Symbol name
*
- * The requested symbol is entered as undefined into the symbol table
- * for this object, so the linker will pull in other object files as
- * necessary to satisfy the reference. However, the undefined symbol
- * is not referenced in any relocations, so the link can still succeed
- * if no file contains it.
+ * Require a symbol to be included within the link. If the symbol
+ * cannot be found, the link will fail.
*
- * A symbol passed to this macro may not be referenced anywhere
- * else in the file. If you want to do that, see IMPORT_SYMBOL().
+ * To use this macro within a file, you must also specify the file's
+ * "requiring symbol" using the REQUIRING_SYMBOL() or
+ * PROVIDE_REQUIRING_SYMBOL() macros.
*/
#ifdef ASSEMBLY
-#define REQUEST_SYMBOL( _sym ) \
- .equ __need_ ## _sym, _sym
-#else /* ASSEMBLY */
-#define REQUEST_SYMBOL( _sym ) \
- __asm__ ( ".equ\t__need_" #_sym ", " #_sym )
-#endif /* ASSEMBLY */
+#define REQUIRE_SYMBOL( symbol ) \
+ .reloc __requiring_symbol__, RELOC_TYPE_NONE, symbol
+#else
+#define REQUIRE_SYMBOL( symbol ) \
+ __asm__ ( ".reloc __requiring_symbol__, " \
+ _S2 ( RELOC_TYPE_NONE ) ", " #symbol )
+#endif
-/** Set up a symbol to be usable in another file by IMPORT_SYMBOL()
+/**
+ * Specify the file's requiring symbol
+ *
+ * @v symbol Symbol name
*
- * The symbol must already be marked as global.
+ * REQUIRE_SYMBOL() works by defining a dummy relocation record
+ * against a nominated "requiring symbol". The presence of the
+ * nominated requiring symbol will drag in all of the symbols
+ * specified using REQUIRE_SYMBOL().
*/
-#define EXPORT_SYMBOL( _sym ) PROVIDE_SYMBOL ( __export_ ## _sym )
+#ifdef ASSEMBLY
+#define REQUIRING_SYMBOL( symbol ) \
+ .equ __requiring_symbol__, symbol
+#else
+#define REQUIRING_SYMBOL( symbol ) \
+ __asm__ ( ".equ __requiring_symbol__, " #symbol )
+#endif
-/** Make a symbol usable to this file if available at link time
- *
- * If no file passed to the linker contains the symbol, it will have
- * @c NULL value to future uses. Keep in mind that the symbol value is
- * really the @e address of a variable or function; see the code
- * snippet below.
- *
- * In C using IMPORT_SYMBOL, you must specify the declaration as the
- * second argument, for instance
- *
- * @code
- * IMPORT_SYMBOL ( my_func, int my_func ( int arg ) );
- * IMPORT_SYMBOL ( my_var, int my_var );
- *
- * void use_imports ( void ) {
- * if ( my_func && &my_var )
- * my_var = my_func ( my_var );
- * }
- * @endcode
- *
- * GCC considers a weak declaration to override a strong one no matter
- * which comes first, so it is safe to include a header file declaring
- * the imported symbol normally, but providing the declaration to
- * IMPORT_SYMBOL is still required.
+/**
+ * Provide a file's requiring symbol
*
- * If no EXPORT_SYMBOL declaration exists for the imported symbol in
- * another file, the behavior will be most likely be identical to that
- * for an unavailable symbol.
+ * If the file contains no symbols that can be used as the requiring
+ * symbol, you can provide a dummy one-byte-long symbol using
+ * PROVIDE_REQUIRING_SYMBOL().
*/
#ifdef ASSEMBLY
-#define IMPORT_SYMBOL( _sym ) \
- REQUEST_SYMBOL ( __export_ ## _sym ) ; \
- .weak _sym
-#else /* ASSEMBLY */
-#define IMPORT_SYMBOL( _sym, _decl ) \
- REQUEST_SYMBOL ( __export_ ## _sym ) ; \
- extern _decl __attribute__ (( weak ))
+#define PROVIDE_REQUIRING_SYMBOL() \
+ .section ".tbl.requiring_symbols", "a", @progbits ; \
+ __requiring_symbol__: .byte 0 ; \
+ .size __requiring_symbol__, . - __requiring_symbol__ ; \
+ .previous
+#else
+#define PROVIDE_REQUIRING_SYMBOL() \
+ __asm__ ( ".section \".tbl.requiring_symbols\", " \
+ " \"a\", @progbits\n" \
+ "__requiring_symbol__:\t.byte 0\n" \
+ ".size __requiring_symbol__, " \
+ " . - __requiring_symbol__\n" \
+ ".previous" )
#endif
/** @} */
@@ -163,20 +162,33 @@
#define PREFIX_OBJECT( _prefix ) _C2 ( _prefix, OBJECT )
#define OBJECT_SYMBOL PREFIX_OBJECT ( obj_ )
-#define REQUEST_EXPANDED( _sym ) REQUEST_SYMBOL ( _sym )
-#define CONFIG_SYMBOL PREFIX_OBJECT ( obj_config_ )
/** Always provide the symbol for the current object (defined by -DOBJECT) */
PROVIDE_SYMBOL ( OBJECT_SYMBOL );
-/** Pull in an object-specific configuration file if available */
-REQUEST_EXPANDED ( CONFIG_SYMBOL );
-
-/** Explicitly require another object */
-#define REQUIRE_OBJECT( _obj ) REQUIRE_SYMBOL ( obj_ ## _obj )
+/**
+ * Request an object
+ *
+ * @v object Object name
+ *
+ * Request an object to be included within the link. If the object
+ * cannot be found, the link will succeed anyway.
+ */
+#define REQUEST_OBJECT( object ) REQUEST_SYMBOL ( obj_ ## object )
-/** Pull in another object if it exists */
-#define REQUEST_OBJECT( _obj ) REQUEST_SYMBOL ( obj_ ## _obj )
+/**
+ * Require an object
+ *
+ * @v object Object name
+ *
+ * Require an object to be included within the link. If the object
+ * cannot be found, the link will fail.
+ *
+ * To use this macro within a file, you must also specify the file's
+ * "requiring symbol" using the REQUIRING_SYMBOL() or
+ * PROVIDE_REQUIRING_SYMBOL() macros.
+ */
+#define REQUIRE_OBJECT( object ) REQUIRE_SYMBOL ( obj_ ## object )
/** @} */
@@ -195,14 +207,6 @@ REQUEST_EXPANDED ( CONFIG_SYMBOL );
*/
#define __weak __attribute__ (( weak, noinline ))
-/** Prevent a function from being optimized away without inlining
- *
- * Calls to functions with void return type that contain no code in their body
- * may be removed by gcc's optimizer even when inlining is inhibited. Placing
- * this macro in the body of the function prevents that from occurring.
- */
-#define __keepme asm("");
-
#endif
/** @defgroup dbg Debugging infrastructure
@@ -730,13 +734,24 @@ int __debug_disable;
#define FILE_LICENCE_MIT \
PROVIDE_SYMBOL ( PREFIX_OBJECT ( __licence__mit__ ) )
+/** Declare a file as being under GPLv2+ or UBDL
+ *
+ * This licence declaration is applicable when a file states itself to
+ * be licensed under the GNU GPL; "either version 2 of the License, or
+ * (at your option) any later version" and also states that it may be
+ * distributed under the terms of the Unmodified Binary Distribution
+ * Licence (as given in the file COPYING.UBDL).
+ */
+#define FILE_LICENCE_GPL2_OR_LATER_OR_UBDL \
+ PROVIDE_SYMBOL ( PREFIX_OBJECT ( __licence__gpl2_or_later_or_ubdl__ ) )
+
/** Declare a particular licence as applying to a file */
#define FILE_LICENCE( _licence ) FILE_LICENCE_ ## _licence
/** @} */
-/* This file itself is under GPLv2-or-later */
-FILE_LICENCE ( GPL2_OR_LATER );
+/* This file itself is under GPLv2+/UBDL */
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <bits/compiler.h>
diff --git a/qemu/roms/ipxe/src/include/ctype.h b/qemu/roms/ipxe/src/include/ctype.h
index e92ecb1c0..0d79ecd19 100644
--- a/qemu/roms/ipxe/src/include/ctype.h
+++ b/qemu/roms/ipxe/src/include/ctype.h
@@ -4,30 +4,114 @@
/** @file
*
* Character types
+ *
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-#define isdigit(c) ((c) >= '0' && (c) <= '9')
-#define islower(c) ((c) >= 'a' && (c) <= 'z')
-#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
-#define isxdigit(c) (isdigit(c) || ((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f'))
-#define isprint(c) ((c) >= ' ' && (c) <= '~' )
+/**
+ * Check if character is a decimal digit
+ *
+ * @v character ASCII character
+ * @ret is_digit Character is a decimal digit
+ */
+static inline int isdigit ( int character ) {
-static inline unsigned char tolower(unsigned char c)
-{
- if (isupper(c))
- c -= 'A'-'a';
- return c;
+ return ( ( character >= '0' ) && ( character <= '9' ) );
}
-static inline unsigned char toupper(unsigned char c)
-{
- if (islower(c))
- c -= 'a'-'A';
- return c;
+/**
+ * Check if character is a hexadecimal digit
+ *
+ * @v character ASCII character
+ * @ret is_xdigit Character is a hexadecimal digit
+ */
+static inline int isxdigit ( int character ) {
+
+ return ( ( ( character >= '0' ) && ( character <= '9' ) ) ||
+ ( ( character >= 'A' ) && ( character <= 'F' ) ) ||
+ ( ( character >= 'a' ) && ( character <= 'f' ) ) );
+}
+
+/**
+ * Check if character is an upper-case letter
+ *
+ * @v character ASCII character
+ * @ret is_upper Character is an upper-case letter
+ */
+static inline int isupper ( int character ) {
+
+ return ( ( character >= 'A' ) && ( character <= 'Z' ) );
+}
+
+/**
+ * Check if character is a lower-case letter
+ *
+ * @v character ASCII character
+ * @ret is_lower Character is a lower-case letter
+ */
+static inline int islower ( int character ) {
+
+ return ( ( character >= 'a' ) && ( character <= 'z' ) );
+}
+
+/**
+ * Check if character is alphabetic
+ *
+ * @v character ASCII character
+ * @ret is_alpha Character is alphabetic
+ */
+static inline int isalpha ( int character ) {
+
+ return ( isupper ( character ) || islower ( character ) );
+}
+
+/**
+ * Check if character is alphanumeric
+ *
+ * @v character ASCII character
+ * @ret is_alnum Character is alphanumeric
+ */
+static inline int isalnum ( int character ) {
+
+ return ( isalpha ( character ) || isdigit ( character ) );
+}
+
+/**
+ * Check if character is printable
+ *
+ * @v character ASCII character
+ * @ret is_print Character is printable
+ */
+static inline int isprint ( int character ) {
+
+ return ( ( character >= ' ' ) && ( character <= '~' ) );
+}
+
+/**
+ * Convert character to lower case
+ *
+ * @v character Character
+ * @v character Lower-case character
+ */
+static inline int tolower ( int character ) {
+
+ return ( isupper ( character ) ?
+ ( character - 'A' + 'a' ) : character );
+}
+
+/**
+ * Convert character to upper case
+ *
+ * @v character Character
+ * @v character Upper-case character
+ */
+static inline int toupper ( int character ) {
+
+ return ( islower ( character ) ?
+ ( character - 'a' + 'A' ) : character );
}
-extern int isspace ( int c );
+extern int isspace ( int character );
#endif /* _CTYPE_H */
diff --git a/qemu/roms/ipxe/src/include/curses.h b/qemu/roms/ipxe/src/include/curses.h
index f16f9d7d0..04060fe27 100644
--- a/qemu/roms/ipxe/src/include/curses.h
+++ b/qemu/roms/ipxe/src/include/curses.h
@@ -11,7 +11,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#undef ERR
#define ERR (-1)
diff --git a/qemu/roms/ipxe/src/include/elf.h b/qemu/roms/ipxe/src/include/elf.h
index 04022b687..18f755a21 100644
--- a/qemu/roms/ipxe/src/include/elf.h
+++ b/qemu/roms/ipxe/src/include/elf.h
@@ -1,234 +1,81 @@
#ifndef ELF_H
#define ELF_H
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#define EI_NIDENT 16 /* Size of e_ident array. */
-
-/* Values for e_type. */
-#define ET_NONE 0 /* No file type */
-#define ET_REL 1 /* Relocatable file */
-#define ET_EXEC 2 /* Executable file */
-#define ET_DYN 3 /* Shared object file */
-#define ET_CORE 4 /* Core file */
-
-/* Values for e_machine (architecute). */
-#define EM_NONE 0 /* No machine */
-#define EM_M32 1 /* AT&T WE 32100 */
-#define EM_SPARC 2 /* SUN SPARC */
-#define EM_386 3 /* Intel 80386+ */
-#define EM_68K 4 /* Motorola m68k family */
-#define EM_88K 5 /* Motorola m88k family */
-#define EM_486 6 /* Perhaps disused */
-#define EM_860 7 /* Intel 80860 */
-#define EM_MIPS 8 /* MIPS R3000 big-endian */
-#define EM_S370 9 /* IBM System/370 */
-#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
-
-#define EM_PARISC 15 /* HPPA */
-#define EM_VPP500 17 /* Fujitsu VPP500 */
-#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
-#define EM_960 19 /* Intel 80960 */
-#define EM_PPC 20 /* PowerPC */
-#define EM_PPC64 21 /* PowerPC 64-bit */
-#define EM_S390 22 /* IBM S390 */
-
-#define EM_V800 36 /* NEC V800 series */
-#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_FAKE_ALPHA 41 /* Digital Alpha */
-#define EM_SH 42 /* Hitachi SH */
-#define EM_SPARCV9 43 /* SPARC v9 64-bit */
-#define EM_TRICORE 44 /* Siemens Tricore */
-#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 Merced */
-#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 Multimedia Accelerator*/
-#define EM_PCP 55 /* Siemens PCP */
-#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
-#define EM_NDR1 57 /* Denso NDR1 microprocessor */
-#define EM_STARCORE 58 /* Motorola Start*Core processor */
-#define EM_ME16 59 /* Toyota ME16 processor */
-#define EM_ST100 60 /* STMicroelectronic ST100 processor */
-#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
-#define EM_X86_64 62 /* AMD x86-64 architecture */
-#define EM_PDSP 63 /* Sony DSP Processor */
-
-#define EM_FX66 66 /* Siemens FX66 microcontroller */
-#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
-#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
-#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_AT19 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 processor */
-#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_NUM 95
-
-/* 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. */
-
-/* Values for p_flags. */
-#define PF_X 0x1 /* Executable. */
-#define PF_W 0x2 /* Writable. */
-#define PF_R 0x4 /* Readable. */
-
-
-#define ELF_PROGRAM_RETURNS_BIT 0x8000000 /* e_flags bit 31 */
-
-#define EI_MAG0 0
-#define ELFMAG0 0x7f
-
-#define EI_MAG1 1
-#define ELFMAG1 'E'
-
-#define EI_MAG2 2
-#define ELFMAG2 'L'
-
-#define EI_MAG3 3
-#define ELFMAG3 'F'
-
-#define ELFMAG "\177ELF"
-#define SELFMAG 4
-
-#define EI_CLASS 4 /* File class byte index */
-#define ELFCLASSNONE 0 /* Invalid class */
-#define ELFCLASS32 1 /* 32-bit objects */
-#define ELFCLASS64 2 /* 64-bit objects */
+/**
+ * @file
+ *
+ * ELF headers
+ *
+ */
-#define EI_DATA 5 /* Data encodeing byte index */
-#define ELFDATANONE 0 /* Invalid data encoding */
-#define ELFDATA2LSB 1 /* 2's complement little endian */
-#define ELFDATA2MSB 2 /* 2's complement big endian */
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-#define EI_VERSION 6 /* File version byte index */
- /* Value must be EV_CURRENT */
+#include <stdint.h>
-#define EV_NONE 0 /* Invalid ELF Version */
-#define EV_CURRENT 1 /* Current version */
+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;
-#define ELF32_PHDR_SIZE (8*4) /* Size of an elf program header */
+/** Length of ELF identifier */
+#define EI_NIDENT 16
-#ifndef ASSEMBLY
+/** ELF header */
+typedef struct {
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry;
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
-#include <stdint.h>
+/* ELF identifier indexes */
+#define EI_MAG0 0
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
-/*
- * ELF definitions common to all 32-bit architectures.
- */
+/* ELF magic signature bytes */
+#define ELFMAG0 0x7f
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
-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 uint32_t Elf32_Size;
+/* ELF classes */
+#define ELFCLASS32 1
-typedef uint64_t Elf64_Addr;
-typedef uint16_t Elf64_Half;
-typedef uint64_t Elf64_Off;
-typedef int32_t Elf64_Sword;
-typedef uint32_t Elf64_Word;
-typedef uint64_t Elf64_Size;
+/* ELF data encodings */
+#define ELFDATA2LSB 1
-/*
- * 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;
-
-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;
+/* ELF versions */
+#define EV_CURRENT 1
-/*
- * Program header.
- */
+/** ELF program header */
typedef struct {
- Elf32_Word p_type; /* Entry type. */
- Elf32_Off p_offset; /* File offset of contents. */
- Elf32_Addr p_vaddr; /* Virtual address (not used). */
- Elf32_Addr p_paddr; /* Physical address. */
- Elf32_Size p_filesz; /* Size of contents in file. */
- Elf32_Size p_memsz; /* Size of contents in memory. */
- Elf32_Word p_flags; /* Access permission flags. */
- Elf32_Size p_align; /* Alignment in memory and file. */
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
} Elf32_Phdr;
-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 (not used). */
- Elf64_Addr p_paddr; /* Physical address. */
- Elf64_Size p_filesz; /* Size of contents in file. */
- Elf64_Size p_memsz; /* Size of contents in memory. */
- Elf64_Size p_align; /* Alignment in memory and file. */
-} Elf64_Phdr;
-
-/* Standardized Elf image notes for booting... The name for all of these is ELFBoot */
-
-#endif /* ASSEMBLY */
+/* ELF segment types */
+#define PT_LOAD 1
#endif /* ELF_H */
diff --git a/qemu/roms/ipxe/src/include/endian.h b/qemu/roms/ipxe/src/include/endian.h
index 9682cf9b4..79c3163ee 100644
--- a/qemu/roms/ipxe/src/include/endian.h
+++ b/qemu/roms/ipxe/src/include/endian.h
@@ -1,21 +1,22 @@
-#ifndef ETHERBOOT_ENDIAN_H
-#define ETHERBOOT_ENDIAN_H
+#ifndef _ENDIAN_H
+#define _ENDIAN_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-/* Definitions for byte order, according to significance of bytes,
- from low addresses to high addresses. The value is what you get by
- putting '4' in the most significant byte, '3' in the second most
- significant byte, '2' in the second least significant byte, and '1'
- in the least significant byte, and then writing down one digit for
- each byte, starting with the byte at the lowest address at the left,
- and proceeding to the byte with the highest address at the right. */
+/** Constant representing little-endian byte order
+ *
+ * Little-endian systems should define BYTE_ORDER as LITTLE_ENDIAN.
+ * This constant is intended to be used only at compile time.
+ */
+#define __LITTLE_ENDIAN 0x44332211UL
-#define __LITTLE_ENDIAN 1234
-#define __BIG_ENDIAN 4321
-#define __PDP_ENDIAN 3412
+/** Constant representing big-endian byte order
+ *
+ * Big-endian systems should define BYTE_ORDER as BIG_ENDIAN.
+ * This constant is intended to be used only at compile time.
+ */
+#define __BIG_ENDIAN 0x11223344UL
#include "bits/endian.h"
-
-#endif /* ETHERBOOT_ENDIAN_H */
+#endif /* _ENDIAN_H */
diff --git a/qemu/roms/ipxe/src/include/errno.h b/qemu/roms/ipxe/src/include/errno.h
index bcc4a8816..036479aff 100644
--- a/qemu/roms/ipxe/src/include/errno.h
+++ b/qemu/roms/ipxe/src/include/errno.h
@@ -15,12 +15,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef ERRNO_H
#define ERRNO_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/include/getopt.h b/qemu/roms/ipxe/src/include/getopt.h
index 0fe43567e..db3de1786 100644
--- a/qemu/roms/ipxe/src/include/getopt.h
+++ b/qemu/roms/ipxe/src/include/getopt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
diff --git a/qemu/roms/ipxe/src/include/hci/ifmgmt_cmd.h b/qemu/roms/ipxe/src/include/hci/ifmgmt_cmd.h
index 913b911d8..5debf85c2 100644
--- a/qemu/roms/ipxe/src/include/hci/ifmgmt_cmd.h
+++ b/qemu/roms/ipxe/src/include/hci/ifmgmt_cmd.h
@@ -15,12 +15,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _IFMGMT_CMD_H
#define _IFMGMT_CMD_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/parseopt.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/acpi.h b/qemu/roms/ipxe/src/include/ipxe/acpi.h
index 282b6d92d..2ccd691ed 100644
--- a/qemu/roms/ipxe/src/include/ipxe/acpi.h
+++ b/qemu/roms/ipxe/src/include/ipxe/acpi.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/interface.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/aes.h b/qemu/roms/ipxe/src/include/ipxe/aes.h
index 4e44f9853..0432e43ee 100644
--- a/qemu/roms/ipxe/src/include/ipxe/aes.h
+++ b/qemu/roms/ipxe/src/include/ipxe/aes.h
@@ -1,31 +1,51 @@
#ifndef _IPXE_AES_H
#define _IPXE_AES_H
-FILE_LICENCE ( GPL2_OR_LATER );
+/** @file
+ *
+ * AES algorithm
+ *
+ */
-struct cipher_algorithm;
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-/** Basic AES blocksize */
+#include <ipxe/crypto.h>
+
+/** AES blocksize */
#define AES_BLOCKSIZE 16
-#include "crypto/axtls/crypto.h"
+/** Maximum number of AES rounds */
+#define AES_MAX_ROUNDS 15
+
+/** AES matrix */
+union aes_matrix {
+ /** Viewed as an array of bytes */
+ uint8_t byte[16];
+ /** Viewed as an array of four-byte columns */
+ uint32_t column[4];
+} __attribute__ (( packed ));
+
+/** AES round keys */
+struct aes_round_keys {
+ /** Round keys */
+ union aes_matrix key[AES_MAX_ROUNDS];
+};
/** AES context */
struct aes_context {
- /** AES context for AXTLS */
- AES_CTX axtls_ctx;
- /** Cipher is being used for decrypting */
- int decrypting;
+ /** Encryption keys */
+ struct aes_round_keys encrypt;
+ /** Decryption keys */
+ struct aes_round_keys decrypt;
+ /** Number of rounds */
+ unsigned int rounds;
};
/** AES context size */
#define AES_CTX_SIZE sizeof ( struct aes_context )
-/* AXTLS functions */
-extern void axtls_aes_encrypt ( const AES_CTX *ctx, uint32_t *data );
-extern void axtls_aes_decrypt ( const AES_CTX *ctx, uint32_t *data );
-
extern struct cipher_algorithm aes_algorithm;
+extern struct cipher_algorithm aes_ecb_algorithm;
extern struct cipher_algorithm aes_cbc_algorithm;
int aes_wrap ( const void *kek, const void *src, void *dest, int nblk );
diff --git a/qemu/roms/ipxe/src/include/ipxe/ansicol.h b/qemu/roms/ipxe/src/include/ipxe/ansicol.h
index 707d1599d..2b54ecaca 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ansicol.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ansicol.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <curses.h> /* For COLOR_RED etc. */
diff --git a/qemu/roms/ipxe/src/include/ipxe/ansiesc.h b/qemu/roms/ipxe/src/include/ipxe/ansiesc.h
index c1c74481d..80bc83308 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ansiesc.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ansiesc.h
@@ -26,7 +26,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct ansiesc_context;
diff --git a/qemu/roms/ipxe/src/include/ipxe/aoe.h b/qemu/roms/ipxe/src/include/ipxe/aoe.h
index 60f3bd959..0c656e7c2 100644
--- a/qemu/roms/ipxe/src/include/ipxe/aoe.h
+++ b/qemu/roms/ipxe/src/include/ipxe/aoe.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/list.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/api.h b/qemu/roms/ipxe/src/include/ipxe/api.h
index 838b8936e..d05d3b07a 100644
--- a/qemu/roms/ipxe/src/include/ipxe/api.h
+++ b/qemu/roms/ipxe/src/include/ipxe/api.h
@@ -11,7 +11,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @defgroup Single-implementation APIs
*
diff --git a/qemu/roms/ipxe/src/include/ipxe/arp.h b/qemu/roms/ipxe/src/include/ipxe/arp.h
index e30ae6b76..5822fa095 100644
--- a/qemu/roms/ipxe/src/include/ipxe/arp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/arp.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/tables.h>
#include <ipxe/netdevice.h>
@@ -57,4 +57,8 @@ static inline int arp_tx ( struct io_buffer *iobuf, struct net_device *netdev,
&arp_discovery, net_source, ll_source );
}
+extern int arp_tx_request ( struct net_device *netdev,
+ struct net_protocol *net_protocol,
+ const void *net_dest, const void *net_source );
+
#endif /* _IPXE_ARP_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/asn1.h b/qemu/roms/ipxe/src/include/ipxe/asn1.h
index d12524ddb..5fbd58281 100644
--- a/qemu/roms/ipxe/src/include/ipxe/asn1.h
+++ b/qemu/roms/ipxe/src/include/ipxe/asn1.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <time.h>
@@ -141,6 +141,24 @@ struct asn1_builder_header {
ASN1_OID_TRIPLE ( 113549 ), ASN1_OID_SINGLE ( 1 ), \
ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 11 )
+/** ASN.1 OID for sha384WithRSAEncryption (1.2.840.113549.1.1.12) */
+#define ASN1_OID_SHA384WITHRSAENCRYPTION \
+ ASN1_OID_INITIAL ( 1, 2 ), ASN1_OID_DOUBLE ( 840 ), \
+ ASN1_OID_TRIPLE ( 113549 ), ASN1_OID_SINGLE ( 1 ), \
+ ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 12 )
+
+/** ASN.1 OID for sha512WithRSAEncryption (1.2.840.113549.1.1.13) */
+#define ASN1_OID_SHA512WITHRSAENCRYPTION \
+ ASN1_OID_INITIAL ( 1, 2 ), ASN1_OID_DOUBLE ( 840 ), \
+ ASN1_OID_TRIPLE ( 113549 ), ASN1_OID_SINGLE ( 1 ), \
+ ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 13 )
+
+/** ASN.1 OID for sha224WithRSAEncryption (1.2.840.113549.1.1.14) */
+#define ASN1_OID_SHA224WITHRSAENCRYPTION \
+ ASN1_OID_INITIAL ( 1, 2 ), ASN1_OID_DOUBLE ( 840 ), \
+ ASN1_OID_TRIPLE ( 113549 ), ASN1_OID_SINGLE ( 1 ), \
+ ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 14 )
+
/** ASN.1 OID for id-md5 (1.2.840.113549.2.5) */
#define ASN1_OID_MD5 \
ASN1_OID_INITIAL ( 1, 2 ), ASN1_OID_DOUBLE ( 840 ), \
@@ -160,6 +178,41 @@ struct asn1_builder_header {
ASN1_OID_SINGLE ( 3 ), ASN1_OID_SINGLE ( 4 ), \
ASN1_OID_SINGLE ( 2 ), ASN1_OID_SINGLE ( 1 )
+/** ASN.1 OID for id-sha384 (2.16.840.1.101.3.4.2.2) */
+#define ASN1_OID_SHA384 \
+ ASN1_OID_INITIAL ( 2, 16 ), ASN1_OID_DOUBLE ( 840 ), \
+ ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 101 ), \
+ ASN1_OID_SINGLE ( 3 ), ASN1_OID_SINGLE ( 4 ), \
+ ASN1_OID_SINGLE ( 2 ), ASN1_OID_SINGLE ( 2 )
+
+/** ASN.1 OID for id-sha512 (2.16.840.1.101.3.4.2.3) */
+#define ASN1_OID_SHA512 \
+ ASN1_OID_INITIAL ( 2, 16 ), ASN1_OID_DOUBLE ( 840 ), \
+ ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 101 ), \
+ ASN1_OID_SINGLE ( 3 ), ASN1_OID_SINGLE ( 4 ), \
+ ASN1_OID_SINGLE ( 2 ), ASN1_OID_SINGLE ( 3 )
+
+/** ASN.1 OID for id-sha224 (2.16.840.1.101.3.4.2.4) */
+#define ASN1_OID_SHA224 \
+ ASN1_OID_INITIAL ( 2, 16 ), ASN1_OID_DOUBLE ( 840 ), \
+ ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 101 ), \
+ ASN1_OID_SINGLE ( 3 ), ASN1_OID_SINGLE ( 4 ), \
+ ASN1_OID_SINGLE ( 2 ), ASN1_OID_SINGLE ( 4 )
+
+/** ASN.1 OID for id-sha512-224 (2.16.840.1.101.3.4.2.5) */
+#define ASN1_OID_SHA512_224 \
+ ASN1_OID_INITIAL ( 2, 16 ), ASN1_OID_DOUBLE ( 840 ), \
+ ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 101 ), \
+ ASN1_OID_SINGLE ( 3 ), ASN1_OID_SINGLE ( 4 ), \
+ ASN1_OID_SINGLE ( 2 ), ASN1_OID_SINGLE ( 5 )
+
+/** ASN.1 OID for id-sha512-256 (2.16.840.1.101.3.4.2.6) */
+#define ASN1_OID_SHA512_256 \
+ ASN1_OID_INITIAL ( 2, 16 ), ASN1_OID_DOUBLE ( 840 ), \
+ ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 101 ), \
+ ASN1_OID_SINGLE ( 3 ), ASN1_OID_SINGLE ( 4 ), \
+ ASN1_OID_SINGLE ( 2 ), ASN1_OID_SINGLE ( 6 )
+
/** ASN.1 OID for commonName (2.5.4.3) */
#define ASN1_OID_COMMON_NAME \
ASN1_OID_INITIAL ( 2, 5 ), ASN1_OID_SINGLE ( 4 ), \
diff --git a/qemu/roms/ipxe/src/include/ipxe/ata.h b/qemu/roms/ipxe/src/include/ipxe/ata.h
index b7f02d655..a10cfafcc 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ata.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ata.h
@@ -11,7 +11,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* An ATA Logical Block Address
diff --git a/qemu/roms/ipxe/src/include/ipxe/base16.h b/qemu/roms/ipxe/src/include/ipxe/base16.h
index 60e3f2315..8c44da17e 100644
--- a/qemu/roms/ipxe/src/include/ipxe/base16.h
+++ b/qemu/roms/ipxe/src/include/ipxe/base16.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
@@ -32,9 +32,36 @@ static inline size_t base16_decoded_max_len ( const char *encoded ) {
return ( ( strlen ( encoded ) + 1 ) / 2 );
}
-extern void base16_encode ( const uint8_t *raw, size_t len, char *encoded );
-extern int hex_decode ( const char *string, char separator, void *data,
+extern size_t hex_encode ( char separator, const void *raw, size_t raw_len,
+ char *data, size_t len );
+extern int hex_decode ( char separator, const char *encoded, void *data,
size_t len );
-extern int base16_decode ( const char *encoded, uint8_t *raw );
+
+/**
+ * Base16-encode data
+ *
+ * @v raw Raw data
+ * @v raw_len Length of raw data
+ * @v data Buffer
+ * @v len Length of buffer
+ * @ret len Encoded length
+ */
+static inline __attribute__ (( always_inline )) size_t
+base16_encode ( const void *raw, size_t raw_len, char *data, size_t len ) {
+ return hex_encode ( 0, raw, raw_len, data, len );
+}
+
+/**
+ * Base16-decode data
+ *
+ * @v encoded Encoded string
+ * @v data Buffer
+ * @v len Length of buffer
+ * @ret len Length of data, or negative error
+ */
+static inline __attribute__ (( always_inline )) int
+base16_decode ( const char *encoded, void *data, size_t len ) {
+ return hex_decode ( 0, encoded, data, len );
+}
#endif /* _IPXE_BASE16_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/base64.h b/qemu/roms/ipxe/src/include/ipxe/base64.h
index 5fe134dc8..0c70d8382 100644
--- a/qemu/roms/ipxe/src/include/ipxe/base64.h
+++ b/qemu/roms/ipxe/src/include/ipxe/base64.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
@@ -35,7 +35,8 @@ static inline size_t base64_decoded_max_len ( const char *encoded ) {
return ( ( ( strlen ( encoded ) + 4 - 1 ) / 4 ) * 3 );
}
-extern void base64_encode ( const uint8_t *raw, size_t len, char *encoded );
-extern int base64_decode ( const char *encoded, uint8_t *raw );
+extern size_t base64_encode ( const void *raw, size_t raw_len, char *data,
+ size_t len );
+extern int base64_decode ( const char *encoded, void *data, size_t len );
#endif /* _IPXE_BASE64_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/bigint.h b/qemu/roms/ipxe/src/include/ipxe/bigint.h
index 97fbce245..2f99f8445 100644
--- a/qemu/roms/ipxe/src/include/ipxe/bigint.h
+++ b/qemu/roms/ipxe/src/include/ipxe/bigint.h
@@ -6,7 +6,7 @@
* Big integer support
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* Define a big-integer type
diff --git a/qemu/roms/ipxe/src/include/ipxe/bitbash.h b/qemu/roms/ipxe/src/include/ipxe/bitbash.h
index 69d5d9e3e..2a2e475d0 100644
--- a/qemu/roms/ipxe/src/include/ipxe/bitbash.h
+++ b/qemu/roms/ipxe/src/include/ipxe/bitbash.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct bit_basher;
diff --git a/qemu/roms/ipxe/src/include/ipxe/bitmap.h b/qemu/roms/ipxe/src/include/ipxe/bitmap.h
index b18584c1f..38aca694b 100644
--- a/qemu/roms/ipxe/src/include/ipxe/bitmap.h
+++ b/qemu/roms/ipxe/src/include/ipxe/bitmap.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stddef.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/bitops.h b/qemu/roms/ipxe/src/include/ipxe/bitops.h
index 73e859f41..220ab0fe7 100644
--- a/qemu/roms/ipxe/src/include/ipxe/bitops.h
+++ b/qemu/roms/ipxe/src/include/ipxe/bitops.h
@@ -18,9 +18,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* @file
diff --git a/qemu/roms/ipxe/src/include/ipxe/blockdev.h b/qemu/roms/ipxe/src/include/ipxe/blockdev.h
index 9f0a9f787..418c43004 100644
--- a/qemu/roms/ipxe/src/include/ipxe/blockdev.h
+++ b/qemu/roms/ipxe/src/include/ipxe/blockdev.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/uaccess.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/blocktrans.h b/qemu/roms/ipxe/src/include/ipxe/blocktrans.h
new file mode 100644
index 000000000..fee71b96c
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/blocktrans.h
@@ -0,0 +1,38 @@
+#ifndef _IPXE_BLOCKTRANS_H
+#define _IPXE_BLOCKTRANS_H
+
+/** @file
+ *
+ * Block device translator
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/refcnt.h>
+#include <ipxe/interface.h>
+#include <ipxe/xferbuf.h>
+#include <ipxe/uaccess.h>
+
+/** A block device translator */
+struct block_translator {
+ /** Reference count */
+ struct refcnt refcnt;
+ /** Block device interface */
+ struct interface block;
+ /** Data transfer interface */
+ struct interface xfer;
+
+ /** Data transfer buffer */
+ struct xfer_buffer xferbuf;
+ /** Data buffer */
+ userptr_t buffer;
+ /** Block size */
+ size_t blksize;
+};
+
+extern int block_translate ( struct interface *block,
+ userptr_t buffer, size_t size );
+
+#endif /* _IPXE_BLOCKTRANS_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/bofm.h b/qemu/roms/ipxe/src/include/ipxe/bofm.h
index 1da47f651..bc994ea8b 100644
--- a/qemu/roms/ipxe/src/include/ipxe/bofm.h
+++ b/qemu/roms/ipxe/src/include/ipxe/bofm.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/list.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/cbc.h b/qemu/roms/ipxe/src/include/ipxe/cbc.h
index fae376577..18a94e144 100644
--- a/qemu/roms/ipxe/src/include/ipxe/cbc.h
+++ b/qemu/roms/ipxe/src/include/ipxe/cbc.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/crypto.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/cdc.h b/qemu/roms/ipxe/src/include/ipxe/cdc.h
new file mode 100644
index 000000000..f1799cd9a
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/cdc.h
@@ -0,0 +1,55 @@
+#ifndef _IPXE_CDC_H
+#define _IPXE_CDC_H
+
+/** @file
+ *
+ * USB Communications Device Class (CDC)
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/usb.h>
+
+/** Class code for communications devices */
+#define USB_CLASS_CDC 2
+
+/** Union functional descriptor */
+struct cdc_union_descriptor {
+ /** Descriptor header */
+ struct usb_descriptor_header header;
+ /** Descriptor subtype */
+ uint8_t subtype;
+ /** Interfaces (variable-length) */
+ uint8_t interface[1];
+} __attribute__ (( packed ));
+
+/** Union functional descriptor subtype */
+#define CDC_SUBTYPE_UNION 6
+
+/** Ethernet descriptor subtype */
+#define CDC_SUBTYPE_ETHERNET 15
+
+/** Network connection notification */
+#define CDC_NETWORK_CONNECTION \
+ ( USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE | \
+ USB_REQUEST_TYPE ( 0x00 ) )
+
+/** Connection speed change notification */
+#define CDC_CONNECTION_SPEED_CHANGE \
+ ( USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE | \
+ USB_REQUEST_TYPE ( 0x2a ) )
+
+/** Connection speed change notification */
+struct cdc_connection_speed_change {
+ /** Downlink bit rate, in bits per second */
+ uint32_t down;
+ /** Uplink bit rate, in bits per second */
+ uint32_t up;
+} __attribute__ (( packed ));
+
+extern struct cdc_union_descriptor *
+cdc_union_descriptor ( struct usb_configuration_descriptor *config,
+ struct usb_interface_descriptor *interface );
+
+#endif /* _IPXE_CDC_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/certstore.h b/qemu/roms/ipxe/src/include/ipxe/certstore.h
index 7456db621..49b3b512c 100644
--- a/qemu/roms/ipxe/src/include/ipxe/certstore.h
+++ b/qemu/roms/ipxe/src/include/ipxe/certstore.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/asn1.h>
#include <ipxe/x509.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/chap.h b/qemu/roms/ipxe/src/include/ipxe/chap.h
index fce48f3ea..7c693e29d 100644
--- a/qemu/roms/ipxe/src/include/ipxe/chap.h
+++ b/qemu/roms/ipxe/src/include/ipxe/chap.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/md5.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/cms.h b/qemu/roms/ipxe/src/include/ipxe/cms.h
index e026ebd2f..7adf724b2 100644
--- a/qemu/roms/ipxe/src/include/ipxe/cms.h
+++ b/qemu/roms/ipxe/src/include/ipxe/cms.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <time.h>
#include <ipxe/asn1.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/command.h b/qemu/roms/ipxe/src/include/ipxe/command.h
index 432da1abb..a208e7d8f 100644
--- a/qemu/roms/ipxe/src/include/ipxe/command.h
+++ b/qemu/roms/ipxe/src/include/ipxe/command.h
@@ -1,7 +1,7 @@
#ifndef _IPXE_COMMAND_H
#define _IPXE_COMMAND_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/tables.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/console.h b/qemu/roms/ipxe/src/include/ipxe/console.h
index 4b90c9cec..1b764aaca 100644
--- a/qemu/roms/ipxe/src/include/ipxe/console.h
+++ b/qemu/roms/ipxe/src/include/ipxe/console.h
@@ -16,7 +16,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct pixel_buffer;
diff --git a/qemu/roms/ipxe/src/include/ipxe/cpio.h b/qemu/roms/ipxe/src/include/ipxe/cpio.h
index 277232808..0637c531d 100644
--- a/qemu/roms/ipxe/src/include/ipxe/cpio.h
+++ b/qemu/roms/ipxe/src/include/ipxe/cpio.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** A CPIO archive header
*
diff --git a/qemu/roms/ipxe/src/include/ipxe/crc32.h b/qemu/roms/ipxe/src/include/ipxe/crc32.h
index 38ac1b31f..30d2fe66c 100644
--- a/qemu/roms/ipxe/src/include/ipxe/crc32.h
+++ b/qemu/roms/ipxe/src/include/ipxe/crc32.h
@@ -1,7 +1,7 @@
#ifndef _IPXE_CRC32_H
#define _IPXE_CRC32_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/crypto.h b/qemu/roms/ipxe/src/include/ipxe/crypto.h
index 3eda5ec6e..fc0d8b22b 100644
--- a/qemu/roms/ipxe/src/include/ipxe/crypto.h
+++ b/qemu/roms/ipxe/src/include/ipxe/crypto.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stddef.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/deflate.h b/qemu/roms/ipxe/src/include/ipxe/deflate.h
index 19c5125eb..b751aa9a3 100644
--- a/qemu/roms/ipxe/src/include/ipxe/deflate.h
+++ b/qemu/roms/ipxe/src/include/ipxe/deflate.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/device.h b/qemu/roms/ipxe/src/include/ipxe/device.h
index 7202a6966..d81417e8e 100644
--- a/qemu/roms/ipxe/src/include/ipxe/device.h
+++ b/qemu/roms/ipxe/src/include/ipxe/device.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/list.h>
#include <ipxe/tables.h>
@@ -63,10 +63,16 @@ struct device_description {
/** Xen bus type */
#define BUS_TYPE_XEN 8
+/** Hyper-V bus type */
+#define BUS_TYPE_HV 9
+
+/** USB bus type */
+#define BUS_TYPE_USB 10
+
/** A hardware device */
struct device {
/** Name */
- char name[16];
+ char name[32];
/** Driver name */
const char *driver_name;
/** Device description */
@@ -93,6 +99,8 @@ struct root_device {
struct device dev;
/** Root device driver */
struct root_driver *driver;
+ /** Driver-private data */
+ void *priv;
};
/** A root device driver */
@@ -123,6 +131,27 @@ struct root_driver {
/** Declare a root device */
#define __root_device __table_entry ( ROOT_DEVICES, 01 )
+/**
+ * Set root device driver-private data
+ *
+ * @v rootdev Root device
+ * @v priv Private data
+ */
+static inline void rootdev_set_drvdata ( struct root_device *rootdev,
+ void *priv ){
+ rootdev->priv = priv;
+}
+
+/**
+ * Get root device driver-private data
+ *
+ * @v rootdev Root device
+ * @ret priv Private data
+ */
+static inline void * rootdev_get_drvdata ( struct root_device *rootdev ) {
+ return rootdev->priv;
+}
+
extern int device_keep_count;
/**
diff --git a/qemu/roms/ipxe/src/include/ipxe/dhcp.h b/qemu/roms/ipxe/src/include/ipxe/dhcp.h
index bcfb85cc1..a11db3497 100644
--- a/qemu/roms/ipxe/src/include/ipxe/dhcp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/dhcp.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stdarg.h>
@@ -639,16 +639,6 @@ struct dhcphdr {
*/
#define DHCP_MIN_LEN 552
-/** Timeouts for sending DHCP packets */
-#define DHCP_MIN_TIMEOUT ( 1 * TICKS_PER_SEC )
-#define DHCP_MAX_TIMEOUT ( 10 * TICKS_PER_SEC )
-
-/** Maximum time that we will wait for ProxyDHCP responses */
-#define PROXYDHCP_MAX_TIMEOUT ( 2 * TICKS_PER_SEC )
-
-/** Maximum time that we will wait for Boot Server responses */
-#define PXEBS_MAX_TIMEOUT ( 3 * TICKS_PER_SEC )
-
/** Settings block name used for DHCP responses */
#define DHCP_SETTINGS_NAME "dhcp"
diff --git a/qemu/roms/ipxe/src/include/ipxe/dhcpopts.h b/qemu/roms/ipxe/src/include/ipxe/dhcpopts.h
index c5af5d749..707fda4a8 100644
--- a/qemu/roms/ipxe/src/include/ipxe/dhcpopts.h
+++ b/qemu/roms/ipxe/src/include/ipxe/dhcpopts.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/dhcppkt.h b/qemu/roms/ipxe/src/include/ipxe/dhcppkt.h
index 3179a6bb0..f13dfc93d 100644
--- a/qemu/roms/ipxe/src/include/ipxe/dhcppkt.h
+++ b/qemu/roms/ipxe/src/include/ipxe/dhcppkt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#include <ipxe/dhcpopts.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/dhcpv6.h b/qemu/roms/ipxe/src/include/ipxe/dhcpv6.h
index 2636b8ab2..9307b6cae 100644
--- a/qemu/roms/ipxe/src/include/ipxe/dhcpv6.h
+++ b/qemu/roms/ipxe/src/include/ipxe/dhcpv6.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/in.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/dns.h b/qemu/roms/ipxe/src/include/ipxe/dns.h
index 4f6cab3a4..738dea6e4 100644
--- a/qemu/roms/ipxe/src/include/ipxe/dns.h
+++ b/qemu/roms/ipxe/src/include/ipxe/dns.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/in.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/downloader.h b/qemu/roms/ipxe/src/include/ipxe/downloader.h
index de1a2e75e..ccb1abfef 100644
--- a/qemu/roms/ipxe/src/include/ipxe/downloader.h
+++ b/qemu/roms/ipxe/src/include/ipxe/downloader.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct interface;
struct image;
diff --git a/qemu/roms/ipxe/src/include/ipxe/drbg.h b/qemu/roms/ipxe/src/include/ipxe/drbg.h
index 6374e7787..ed2b3757a 100644
--- a/qemu/roms/ipxe/src/include/ipxe/drbg.h
+++ b/qemu/roms/ipxe/src/include/ipxe/drbg.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/sha256.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ecb.h b/qemu/roms/ipxe/src/include/ipxe/ecb.h
new file mode 100644
index 000000000..4e6aa3c81
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/ecb.h
@@ -0,0 +1,55 @@
+#ifndef _IPXE_ECB_H
+#define _IPXE_ECB_H
+
+/** @file
+ *
+ * Electronic codebook (ECB)
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/crypto.h>
+
+extern void ecb_encrypt ( void *ctx, const void *src, void *dst,
+ size_t len, struct cipher_algorithm *raw_cipher );
+extern void ecb_decrypt ( void *ctx, const void *src, void *dst,
+ size_t len, struct cipher_algorithm *raw_cipher );
+
+/**
+ * Create a cipher-block chaining mode of behaviour of an existing cipher
+ *
+ * @v _ecb_name Name for the new ECB cipher
+ * @v _ecb_cipher New cipher algorithm
+ * @v _raw_cipher Underlying cipher algorithm
+ * @v _raw_context Context structure for the underlying cipher
+ * @v _blocksize Cipher block size
+ */
+#define ECB_CIPHER( _ecb_name, _ecb_cipher, _raw_cipher, _raw_context, \
+ _blocksize ) \
+static int _ecb_name ## _setkey ( void *ctx, const void *key, \
+ size_t keylen ) { \
+ return cipher_setkey ( &_raw_cipher, ctx, key, keylen ); \
+} \
+static void _ecb_name ## _setiv ( void *ctx, const void *iv ) { \
+ cipher_setiv ( &_raw_cipher, ctx, iv ); \
+} \
+static void _ecb_name ## _encrypt ( void *ctx, const void *src, \
+ void *dst, size_t len ) { \
+ ecb_encrypt ( ctx, src, dst, len, &_raw_cipher ); \
+} \
+static void _ecb_name ## _decrypt ( void *ctx, const void *src, \
+ void *dst, size_t len ) { \
+ ecb_decrypt ( ctx, src, dst, len, &_raw_cipher ); \
+} \
+struct cipher_algorithm _ecb_cipher = { \
+ .name = #_ecb_name, \
+ .ctxsize = sizeof ( _raw_context ), \
+ .blocksize = _blocksize, \
+ .setkey = _ecb_name ## _setkey, \
+ .setiv = _ecb_name ## _setiv, \
+ .encrypt = _ecb_name ## _encrypt, \
+ .decrypt = _ecb_name ## _decrypt, \
+};
+
+#endif /* _IPXE_ECB_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/edd.h b/qemu/roms/ipxe/src/include/ipxe/edd.h
index 0c25593d5..1914fd0b0 100644
--- a/qemu/roms/ipxe/src/include/ipxe/edd.h
+++ b/qemu/roms/ipxe/src/include/ipxe/edd.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/interface.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/editbox.h b/qemu/roms/ipxe/src/include/ipxe/editbox.h
index 9122dbbf3..2c70e0b6b 100644
--- a/qemu/roms/ipxe/src/include/ipxe/editbox.h
+++ b/qemu/roms/ipxe/src/include/ipxe/editbox.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <curses.h>
#include <ipxe/editstring.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/editstring.h b/qemu/roms/ipxe/src/include/ipxe/editstring.h
index 2ef546a63..a00a8adaa 100644
--- a/qemu/roms/ipxe/src/include/ipxe/editstring.h
+++ b/qemu/roms/ipxe/src/include/ipxe/editstring.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** An editable string */
struct edit_string {
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/ProcessorBind.h b/qemu/roms/ipxe/src/include/ipxe/efi/ProcessorBind.h
index 1294459f9..7466814fa 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/ProcessorBind.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/ProcessorBind.h
@@ -1,7 +1,7 @@
#ifndef _IPXE_EFI_PROCESSOR_BIND_H
#define _IPXE_EFI_PROCESSOR_BIND_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/*
* EFI header files rely on having the CPU architecture directory
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/Protocol/Rng.h b/qemu/roms/ipxe/src/include/ipxe/efi/Protocol/Rng.h
new file mode 100644
index 000000000..f04efbb03
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/Protocol/Rng.h
@@ -0,0 +1,158 @@
+/** @file
+ EFI_RNG_PROTOCOL as defined in UEFI 2.4.
+ The UEFI Random Number Generator Protocol is used to provide random bits for use
+ in applications, or entropy for seeding other random number generators.
+
+Copyright (c) 2013, 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 that 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 __EFI_RNG_PROTOCOL_H__
+#define __EFI_RNG_PROTOCOL_H__
+
+FILE_LICENCE ( BSD3 );
+
+///
+/// Global ID for the Random Number Generator Protocol
+///
+#define EFI_RNG_PROTOCOL_GUID \
+ { \
+ 0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \
+ }
+
+typedef struct _EFI_RNG_PROTOCOL EFI_RNG_PROTOCOL;
+
+///
+/// A selection of EFI_RNG_PROTOCOL algorithms.
+/// The algorithms listed are optional, not meant to be exhaustive and be argmented by
+/// vendors or other industry standards.
+///
+
+typedef EFI_GUID EFI_RNG_ALGORITHM;
+
+///
+/// The algorithms corresponds to SP800-90 as defined in
+/// NIST SP 800-90, "Recommendation for Random Number Generation Using Deterministic Random
+/// Bit Generators", March 2007.
+///
+#define EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID \
+ { \
+ 0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 } \
+ }
+#define EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID \
+ { \
+ 0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7 } \
+ }
+#define EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID \
+ { \
+ 0x44f0de6e, 0x4d8c, 0x4045, {0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e } \
+ }
+///
+/// The algorithms correspond to X9.31 as defined in
+/// NIST, "Recommended Random Number Generator Based on ANSI X9.31 Appendix A.2.4 Using
+/// the 3-Key Triple DES and AES Algorithm", January 2005.
+///
+#define EFI_RNG_ALGORITHM_X9_31_3DES_GUID \
+ { \
+ 0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46 } \
+ }
+#define EFI_RNG_ALGORITHM_X9_31_AES_GUID \
+ { \
+ 0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9 } \
+ }
+///
+/// The "raw" algorithm, when supported, is intended to provide entropy directly from
+/// the source, without it going through some deterministic random bit generator.
+///
+#define EFI_RNG_ALGORITHM_RAW \
+ { \
+ 0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61 } \
+ }
+
+/**
+ Returns information about the random number generation implementation.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
+ On output with a return code of EFI_SUCCESS, the size
+ in bytes of the data returned in RNGAlgorithmList. On output
+ with a return code of EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
+ with one EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must not change across multiple
+ calls to the same driver. The first algorithm in the list
+ is the default algorithm for the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was returned successfully.
+ @retval EFI_UNSUPPORTED The services is not supported by this driver.
+ @retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a
+ hardware or firmware error.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_RNG_GET_INFO) (
+ IN EFI_RNG_PROTOCOL *This,
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ );
+
+/**
+ Produces and returns an RNG value using either the default or specified RNG algorithm.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
+ algorithm to use. May be NULL in which case the function will
+ use its default RNG algorithm.
+ @param[in] RNGValueLength The length in bytes of the memory buffer pointed to by
+ RNGValue. The driver shall return exactly this numbers of bytes.
+ @param[out] RNGValue A caller-allocated memory buffer filled by the driver with the
+ resulting RNG value.
+
+ @retval EFI_SUCCESS The RNG value was returned successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by
+ this driver.
+ @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or
+ firmware error.
+ @retval EFI_NOT_READY There is not enough random data available to satisfy the length
+ requested by RNGValueLength.
+ @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_RNG_GET_RNG) (
+ IN EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
+ IN UINTN RNGValueLength,
+ OUT UINT8 *RNGValue
+ );
+
+///
+/// The Random Number Generator (RNG) protocol provides random bits for use in
+/// applications, or entropy for seeding other random number generators.
+///
+struct _EFI_RNG_PROTOCOL {
+ EFI_RNG_GET_INFO GetInfo;
+ EFI_RNG_GET_RNG GetRNG;
+};
+
+extern EFI_GUID gEfiRngProtocolGuid;
+extern EFI_GUID gEfiRngAlgorithmSp80090Hash256Guid;
+extern EFI_GUID gEfiRngAlgorithmSp80090Hmac256Guid;
+extern EFI_GUID gEfiRngAlgorithmSp80090Ctr256Guid;
+extern EFI_GUID gEfiRngAlgorithmX9313DesGuid;
+extern EFI_GUID gEfiRngAlgorithmX931AesGuid;
+extern EFI_GUID gEfiRngAlgorithmRaw;
+
+#endif
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_autoboot.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_autoboot.h
index d4a26850c..1d5ddc8c3 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_autoboot.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_autoboot.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern void efi_set_autoboot ( void );
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_driver.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_driver.h
index e16a24daa..f497df3e3 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_driver.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_driver.h
@@ -6,7 +6,7 @@
* EFI driver interface
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/device.h>
#include <ipxe/tables.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_entropy.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_entropy.h
new file mode 100644
index 000000000..39a667355
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_entropy.h
@@ -0,0 +1,35 @@
+#ifndef _IPXE_EFI_ENTROPY_H
+#define _IPXE_EFI_ENTROPY_H
+
+/** @file
+ *
+ * EFI entropy source
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+
+#ifdef ENTROPY_EFI
+#define ENTROPY_PREFIX_efi
+#else
+#define ENTROPY_PREFIX_efi __efi_
+#endif
+
+/**
+ * min-entropy per sample
+ *
+ * @ret min_entropy min-entropy of each sample
+ */
+static inline __always_inline double
+ENTROPY_INLINE ( efi, min_entropy_per_sample ) ( void ) {
+
+ /* We use essentially the same mechanism as for the BIOS
+ * RTC-based entropy source, and so assume the same
+ * min-entropy per sample.
+ */
+ return 1.3;
+}
+
+#endif /* _IPXE_EFI_ENTROPY_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_hii.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_hii.h
index 8e94bbe7e..bbec31194 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_hii.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_hii.h
@@ -6,7 +6,7 @@
* EFI human interface infrastructure
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <ipxe/efi/Uefi/UefiInternalFormRepresentation.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_pci.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_pci.h
index af36613d9..6dd945f05 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_pci.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_pci.h
@@ -6,7 +6,7 @@
* EFI driver interface
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/pci.h>
#include <ipxe/efi/efi.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_pci_api.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_pci_api.h
index 498a0388b..887d5ee14 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_pci_api.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_pci_api.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef PCIAPI_EFI
#define PCIAPI_PREFIX_efi
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_reboot.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_reboot.h
index 33921b913..249cae8c5 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_reboot.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_reboot.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef REBOOT_EFI
#define REBOOT_PREFIX_efi
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_smbios.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_smbios.h
index 7642e5bc5..d890d5460 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_smbios.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_smbios.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef SMBIOS_EFI
#define SMBIOS_PREFIX_efi
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_snp.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_snp.h
index a18bced5f..1e5c66626 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_snp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_snp.h
@@ -18,6 +18,9 @@
#include <ipxe/efi/Protocol/HiiDatabase.h>
#include <ipxe/efi/Protocol/LoadFile.h>
+/** SNP transmit completion ring size */
+#define EFI_SNP_NUM_TX 32
+
/** An SNP device */
struct efi_snp_device {
/** List of SNP devices */
@@ -34,20 +37,16 @@ struct efi_snp_device {
EFI_SIMPLE_NETWORK_MODE mode;
/** Started flag */
int started;
- /** Outstanding TX packet count (via "interrupt status")
- *
- * Used in order to generate TX completions.
- */
- unsigned int tx_count_interrupts;
- /** Outstanding TX packet count (via "recycled tx buffers")
- *
- * Used in order to generate TX completions.
- */
- unsigned int tx_count_txbufs;
- /** Outstanding RX packet count (via "interrupt status") */
- unsigned int rx_count_interrupts;
- /** Outstanding RX packet count (via WaitForPacket event) */
- unsigned int rx_count_events;
+ /** Pending interrupt status */
+ unsigned int interrupts;
+ /** Transmit completion ring */
+ VOID *tx[EFI_SNP_NUM_TX];
+ /** Transmit completion ring producer counter */
+ unsigned int tx_prod;
+ /** Transmit completion ring consumer counter */
+ unsigned int tx_cons;
+ /** Receive queue */
+ struct list_head rx;
/** The network interface identifier */
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL nii;
/** Component name protocol */
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_strings.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_strings.h
index 023ccda07..2f241537e 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_strings.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_strings.h
@@ -6,7 +6,7 @@
* EFI strings
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_time.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_time.h
new file mode 100644
index 000000000..099994b57
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_time.h
@@ -0,0 +1,20 @@
+#ifndef _IPXE_EFI_TIME_H
+#define _IPXE_EFI_TIME_H
+
+/** @file
+ *
+ * EFI time source
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+
+#ifdef TIME_EFI
+#define TIME_PREFIX_efi
+#else
+#define TIME_PREFIX_efi __efi_
+#endif
+
+#endif /* _IPXE_EFI_TIME_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_timer.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_timer.h
index b10543d6c..c03765393 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_timer.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_timer.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef TIMER_EFI
#define TIMER_PREFIX_efi
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_uaccess.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_uaccess.h
index 870a089b2..3cc750405 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_uaccess.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_uaccess.h
@@ -10,7 +10,7 @@
* no-ops.
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef UACCESS_EFI
#define UACCESS_PREFIX_efi
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_umalloc.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_umalloc.h
index 911e69a96..4eb2a5f9b 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_umalloc.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_umalloc.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef UMALLOC_EFI
#define UMALLOC_PREFIX_efi
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_utils.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_utils.h
index 9164be190..57268daf7 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_utils.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_utils.h
@@ -6,7 +6,7 @@
* EFI utilities
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/DevicePath.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_watchdog.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_watchdog.h
new file mode 100644
index 000000000..4a56b9a29
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_watchdog.h
@@ -0,0 +1,31 @@
+#ifndef _IPXE_EFI_WATCHDOG_H
+#define _IPXE_EFI_WATCHDOG_H
+
+/** @file
+ *
+ * EFI watchdog holdoff timer
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+extern struct retry_timer efi_watchdog;
+
+/**
+ * Start EFI watchdog holdoff timer
+ *
+ */
+static inline void efi_watchdog_start ( void ) {
+
+ start_timer_nodelay ( &efi_watchdog );
+}
+
+/**
+ * Stop EFI watchdog holdoff timer
+ *
+ */
+static inline void efi_watchdog_stop ( void ) {
+
+ stop_timer ( &efi_watchdog );
+}
+
+#endif /* _IPXE_EFI_WATCHDOG_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/efi/efi_wrap.h b/qemu/roms/ipxe/src/include/ipxe/efi/efi_wrap.h
index 7579e0fe9..d8ed1a5cc 100644
--- a/qemu/roms/ipxe/src/include/ipxe/efi/efi_wrap.h
+++ b/qemu/roms/ipxe/src/include/ipxe/efi/efi_wrap.h
@@ -6,7 +6,7 @@
* EFI driver interface
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/eisa.h b/qemu/roms/ipxe/src/include/ipxe/eisa.h
index 22a1ed94e..e7dac1f39 100644
--- a/qemu/roms/ipxe/src/include/ipxe/eisa.h
+++ b/qemu/roms/ipxe/src/include/ipxe/eisa.h
@@ -1,7 +1,7 @@
#ifndef EISA_H
#define EISA_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/isa_ids.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/elf.h b/qemu/roms/ipxe/src/include/ipxe/elf.h
index ec675c047..033c3f7a8 100644
--- a/qemu/roms/ipxe/src/include/ipxe/elf.h
+++ b/qemu/roms/ipxe/src/include/ipxe/elf.h
@@ -8,10 +8,21 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+#include <stdint.h>
+#include <ipxe/image.h>
#include <elf.h>
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Phdr Elf_Phdr;
+typedef Elf32_Off Elf_Off;
+#define ELFCLASS ELFCLASS32
+
+extern int elf_segments ( struct image *image, Elf_Ehdr *ehdr,
+ int ( * process ) ( struct image *image,
+ Elf_Phdr *phdr, physaddr_t dest ),
+ physaddr_t *entry, physaddr_t *max );
extern int elf_load ( struct image *image, physaddr_t *entry, physaddr_t *max );
#endif /* _IPXE_ELF_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/eltorito.h b/qemu/roms/ipxe/src/include/ipxe/eltorito.h
index 3302b38b6..27e361b16 100644
--- a/qemu/roms/ipxe/src/include/ipxe/eltorito.h
+++ b/qemu/roms/ipxe/src/include/ipxe/eltorito.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/iso9660.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/entropy.h b/qemu/roms/ipxe/src/include/ipxe/entropy.h
index adf325e79..beeb3abfa 100644
--- a/qemu/roms/ipxe/src/include/ipxe/entropy.h
+++ b/qemu/roms/ipxe/src/include/ipxe/entropy.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
@@ -54,6 +54,7 @@ typedef uint8_t entropy_sample_t;
/* Include all architecture-independent entropy API headers */
#include <ipxe/null_entropy.h>
+#include <ipxe/efi/efi_entropy.h>
#include <ipxe/linux/linux_entropy.h>
/* Include all architecture-dependent entropy API headers */
diff --git a/qemu/roms/ipxe/src/include/ipxe/errfile.h b/qemu/roms/ipxe/src/include/ipxe/errfile.h
index f809337ff..e21c95938 100644
--- a/qemu/roms/ipxe/src/include/ipxe/errfile.h
+++ b/qemu/roms/ipxe/src/include/ipxe/errfile.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <bits/errfile.h>
@@ -68,6 +68,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_fbcon ( ERRFILE_CORE | 0x001c0000 )
#define ERRFILE_ansicol ( ERRFILE_CORE | 0x001d0000 )
#define ERRFILE_ansicoldef ( ERRFILE_CORE | 0x001e0000 )
+#define ERRFILE_fault ( ERRFILE_CORE | 0x001f0000 )
+#define ERRFILE_blocktrans ( ERRFILE_CORE | 0x00200000 )
#define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 )
#define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 )
@@ -76,12 +78,20 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_pci ( ERRFILE_DRIVER | 0x00040000 )
#define ERRFILE_linux ( ERRFILE_DRIVER | 0x00050000 )
#define ERRFILE_pcivpd ( ERRFILE_DRIVER | 0x00060000 )
+#define ERRFILE_usb ( ERRFILE_DRIVER | 0x00070000 )
+#define ERRFILE_usbhub ( ERRFILE_DRIVER | 0x00080000 )
+#define ERRFILE_xhci ( ERRFILE_DRIVER | 0x00090000 )
+#define ERRFILE_ehci ( ERRFILE_DRIVER | 0x000a0000 )
+#define ERRFILE_uhci ( ERRFILE_DRIVER | 0x000b0000 )
+#define ERRFILE_usbhid ( ERRFILE_DRIVER | 0x000c0000 )
+#define ERRFILE_usbkbd ( ERRFILE_DRIVER | 0x000d0000 )
#define ERRFILE_nvs ( ERRFILE_DRIVER | 0x00100000 )
#define ERRFILE_spi ( ERRFILE_DRIVER | 0x00110000 )
#define ERRFILE_i2c_bit ( ERRFILE_DRIVER | 0x00120000 )
#define ERRFILE_spi_bit ( ERRFILE_DRIVER | 0x00130000 )
#define ERRFILE_nvsvpd ( ERRFILE_DRIVER | 0x00140000 )
+#define ERRFILE_uart ( ERRFILE_DRIVER | 0x00150000 )
#define ERRFILE_3c509 ( ERRFILE_DRIVER | 0x00200000 )
#define ERRFILE_bnx2 ( ERRFILE_DRIVER | 0x00210000 )
@@ -157,7 +167,11 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_snp ( ERRFILE_DRIVER | 0x00680000 )
#define ERRFILE_netfront ( ERRFILE_DRIVER | 0x00690000 )
#define ERRFILE_nii ( ERRFILE_DRIVER | 0x006a0000 )
-
+#define ERRFILE_netvsc ( ERRFILE_DRIVER | 0x006b0000 )
+#define ERRFILE_ecm ( ERRFILE_DRIVER | 0x006c0000 )
+#define ERRFILE_ncm ( ERRFILE_DRIVER | 0x006d0000 )
+#define ERRFILE_usbnet ( ERRFILE_DRIVER | 0x006e0000 )
+#define ERRFILE_dm96xx ( ERRFILE_DRIVER | 0x006f0000 )
#define ERRFILE_scsi ( ERRFILE_DRIVER | 0x00700000 )
#define ERRFILE_arbel ( ERRFILE_DRIVER | 0x00710000 )
#define ERRFILE_hermon ( ERRFILE_DRIVER | 0x00720000 )
@@ -165,6 +179,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_ata ( ERRFILE_DRIVER | 0x00740000 )
#define ERRFILE_srp ( ERRFILE_DRIVER | 0x00750000 )
#define ERRFILE_qib7322 ( ERRFILE_DRIVER | 0x00760000 )
+#define ERRFILE_smsc75xx ( ERRFILE_DRIVER | 0x00770000 )
+#define ERRFILE_intelvf ( ERRFILE_DRIVER | 0x00780000 )
+#define ERRFILE_intelxvf ( ERRFILE_DRIVER | 0x00790000 )
#define ERRFILE_aoe ( ERRFILE_NET | 0x00000000 )
#define ERRFILE_arp ( ERRFILE_NET | 0x00010000 )
@@ -227,6 +244,17 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_ping ( ERRFILE_NET | 0x003a0000 )
#define ERRFILE_dhcpv6 ( ERRFILE_NET | 0x003b0000 )
#define ERRFILE_nfs_uri ( ERRFILE_NET | 0x003c0000 )
+#define ERRFILE_rndis ( ERRFILE_NET | 0x003d0000 )
+#define ERRFILE_pccrc ( ERRFILE_NET | 0x003e0000 )
+#define ERRFILE_stp ( ERRFILE_NET | 0x003f0000 )
+#define ERRFILE_pccrd ( ERRFILE_NET | 0x00400000 )
+#define ERRFILE_httpconn ( ERRFILE_NET | 0x00410000 )
+#define ERRFILE_httpauth ( ERRFILE_NET | 0x00420000 )
+#define ERRFILE_httpbasic ( ERRFILE_NET | 0x00430000 )
+#define ERRFILE_httpdigest ( ERRFILE_NET | 0x00440000 )
+#define ERRFILE_peerdisc ( ERRFILE_NET | 0x00450000 )
+#define ERRFILE_peerblk ( ERRFILE_NET | 0x00460000 )
+#define ERRFILE_peermux ( ERRFILE_NET | 0x00470000 )
#define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 )
#define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 )
@@ -245,7 +273,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_imgmgmt ( ERRFILE_OTHER | 0x00050000 )
#define ERRFILE_pxe_tftp ( ERRFILE_OTHER | 0x00060000 )
#define ERRFILE_pxe_udp ( ERRFILE_OTHER | 0x00070000 )
-#define ERRFILE_axtls_aes ( ERRFILE_OTHER | 0x00080000 )
+#define ERRFILE_aes ( ERRFILE_OTHER | 0x00080000 )
#define ERRFILE_cipher ( ERRFILE_OTHER | 0x00090000 )
#define ERRFILE_image_cmd ( ERRFILE_OTHER | 0x000a0000 )
#define ERRFILE_uri_test ( ERRFILE_OTHER | 0x000b0000 )
@@ -308,6 +336,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_xengrant ( ERRFILE_OTHER | 0x00440000 )
#define ERRFILE_efi_utils ( ERRFILE_OTHER | 0x00450000 )
#define ERRFILE_efi_wrap ( ERRFILE_OTHER | 0x00460000 )
+#define ERRFILE_vmbus ( ERRFILE_OTHER | 0x00470000 )
+#define ERRFILE_efi_time ( ERRFILE_OTHER | 0x00480000 )
+#define ERRFILE_efi_watchdog ( ERRFILE_OTHER | 0x00490000 )
/** @} */
diff --git a/qemu/roms/ipxe/src/include/ipxe/errno/efi.h b/qemu/roms/ipxe/src/include/ipxe/errno/efi.h
index 2d2c50176..9f010f5fb 100644
--- a/qemu/roms/ipxe/src/include/ipxe/errno/efi.h
+++ b/qemu/roms/ipxe/src/include/ipxe/errno/efi.h
@@ -21,7 +21,7 @@
* as-is.
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Uefi/UefiBaseType.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/errno/linux.h b/qemu/roms/ipxe/src/include/ipxe/errno/linux.h
index 11309b4ad..99133c816 100644
--- a/qemu/roms/ipxe/src/include/ipxe/errno/linux.h
+++ b/qemu/roms/ipxe/src/include/ipxe/errno/linux.h
@@ -10,7 +10,7 @@
* directly as our platform error codes.
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* Convert platform error code to platform component of iPXE error code
diff --git a/qemu/roms/ipxe/src/include/ipxe/errortab.h b/qemu/roms/ipxe/src/include/ipxe/errortab.h
index a2f6a70f5..4fe81a6be 100644
--- a/qemu/roms/ipxe/src/include/ipxe/errortab.h
+++ b/qemu/roms/ipxe/src/include/ipxe/errortab.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/tables.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/eth_slow.h b/qemu/roms/ipxe/src/include/ipxe/eth_slow.h
index 00509197d..f6d731b3b 100644
--- a/qemu/roms/ipxe/src/include/ipxe/eth_slow.h
+++ b/qemu/roms/ipxe/src/include/ipxe/eth_slow.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Slow protocols header */
struct eth_slow_header {
diff --git a/qemu/roms/ipxe/src/include/ipxe/ethernet.h b/qemu/roms/ipxe/src/include/ipxe/ethernet.h
index d1263d7c3..dd04e00ce 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ethernet.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ethernet.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/netdevice.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/fakedhcp.h b/qemu/roms/ipxe/src/include/ipxe/fakedhcp.h
index ea06b06dc..d016b5237 100644
--- a/qemu/roms/ipxe/src/include/ipxe/fakedhcp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/fakedhcp.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/fault.h b/qemu/roms/ipxe/src/include/ipxe/fault.h
new file mode 100644
index 000000000..356296c35
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/fault.h
@@ -0,0 +1,53 @@
+#ifndef _IPXE_FAULT_H
+#define _IPXE_FAULT_H
+
+/** @file
+ *
+ * Fault injection
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <config/fault.h>
+
+extern int inject_fault_nonzero ( unsigned int rate );
+extern void inject_corruption_nonzero ( unsigned int rate, const void *data,
+ size_t len );
+
+/**
+ * Inject fault with a specified probability
+ *
+ * @v rate Reciprocal of fault probability (zero for no faults)
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+inject_fault ( unsigned int rate ) {
+
+ /* Force dead code elimination in non-fault-injecting builds */
+ if ( rate == 0 )
+ return 0;
+
+ return inject_fault_nonzero ( rate );
+}
+
+/**
+ * Corrupt data with a specified probability
+ *
+ * @v rate Reciprocal of fault probability (zero for no faults)
+ * @v data Data
+ * @v len Length of data
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) void
+inject_corruption ( unsigned int rate, const void *data, size_t len ) {
+
+ /* Force dead code elimination in non-fault-injecting builds */
+ if ( rate == 0 )
+ return;
+
+ return inject_corruption_nonzero ( rate, data, len );
+}
+
+#endif /* _IPXE_FAULT_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/fbcon.h b/qemu/roms/ipxe/src/include/ipxe/fbcon.h
index 0538449ac..d442bb918 100644
--- a/qemu/roms/ipxe/src/include/ipxe/fbcon.h
+++ b/qemu/roms/ipxe/src/include/ipxe/fbcon.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/ansiesc.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/fc.h b/qemu/roms/ipxe/src/include/ipxe/fc.h
index 6fdef092d..840d11f62 100644
--- a/qemu/roms/ipxe/src/include/ipxe/fc.h
+++ b/qemu/roms/ipxe/src/include/ipxe/fc.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/refcnt.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/fcels.h b/qemu/roms/ipxe/src/include/ipxe/fcels.h
index 45fa69a4a..02f755115 100644
--- a/qemu/roms/ipxe/src/include/ipxe/fcels.h
+++ b/qemu/roms/ipxe/src/include/ipxe/fcels.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/fc.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/fcns.h b/qemu/roms/ipxe/src/include/ipxe/fcns.h
index e25d9b9d5..9011a7be7 100644
--- a/qemu/roms/ipxe/src/include/ipxe/fcns.h
+++ b/qemu/roms/ipxe/src/include/ipxe/fcns.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/fc.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/fcoe.h b/qemu/roms/ipxe/src/include/ipxe/fcoe.h
index 6ba5b406a..b61e82fea 100644
--- a/qemu/roms/ipxe/src/include/ipxe/fcoe.h
+++ b/qemu/roms/ipxe/src/include/ipxe/fcoe.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/fc.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/fcp.h b/qemu/roms/ipxe/src/include/ipxe/fcp.h
index f6922bc7c..853ca13f6 100644
--- a/qemu/roms/ipxe/src/include/ipxe/fcp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/fcp.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/fc.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/features.h b/qemu/roms/ipxe/src/include/ipxe/features.h
index d8b8b2184..e86a2d226 100644
--- a/qemu/roms/ipxe/src/include/ipxe/features.h
+++ b/qemu/roms/ipxe/src/include/ipxe/features.h
@@ -11,7 +11,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* @defgroup featurecat Feature categories
diff --git a/qemu/roms/ipxe/src/include/ipxe/fragment.h b/qemu/roms/ipxe/src/include/ipxe/fragment.h
index e311ad1e4..0069e5e08 100644
--- a/qemu/roms/ipxe/src/include/ipxe/fragment.h
+++ b/qemu/roms/ipxe/src/include/ipxe/fragment.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/list.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ftp.h b/qemu/roms/ipxe/src/include/ipxe/ftp.h
index cbab12d2c..3180f1631 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ftp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ftp.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** FTP default port */
#define FTP_PORT 21
diff --git a/qemu/roms/ipxe/src/include/ipxe/gdbserial.h b/qemu/roms/ipxe/src/include/ipxe/gdbserial.h
index a3b56173c..e1040c94e 100644
--- a/qemu/roms/ipxe/src/include/ipxe/gdbserial.h
+++ b/qemu/roms/ipxe/src/include/ipxe/gdbserial.h
@@ -7,15 +7,14 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
struct gdb_transport;
-/**
- * Set up the serial transport
- *
- * @ret transport suitable for starting the GDB stub or NULL on error
- */
-struct gdb_transport *gdbserial_configure ( void );
+extern struct gdb_transport * gdbserial_configure ( unsigned int port,
+ unsigned int baud,
+ uint8_t lcr );
#endif /* _IPXE_GDBSERIAL_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/gdbstub.h b/qemu/roms/ipxe/src/include/ipxe/gdbstub.h
index 319606747..13ca33ddb 100644
--- a/qemu/roms/ipxe/src/include/ipxe/gdbstub.h
+++ b/qemu/roms/ipxe/src/include/ipxe/gdbstub.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/tables.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/gdbudp.h b/qemu/roms/ipxe/src/include/ipxe/gdbudp.h
index db7a451c9..a1c091522 100644
--- a/qemu/roms/ipxe/src/include/ipxe/gdbudp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/gdbudp.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct sockaddr_in;
struct gdb_transport;
diff --git a/qemu/roms/ipxe/src/include/ipxe/hash_df.h b/qemu/roms/ipxe/src/include/ipxe/hash_df.h
index 607a4a610..e57682446 100644
--- a/qemu/roms/ipxe/src/include/ipxe/hash_df.h
+++ b/qemu/roms/ipxe/src/include/ipxe/hash_df.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/crypto.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/hidemem.h b/qemu/roms/ipxe/src/include/ipxe/hidemem.h
index ddc9cd8b3..cc8d5ee37 100644
--- a/qemu/roms/ipxe/src/include/ipxe/hidemem.h
+++ b/qemu/roms/ipxe/src/include/ipxe/hidemem.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/hmac.h b/qemu/roms/ipxe/src/include/ipxe/hmac.h
index d5ec0868d..09d3e273d 100644
--- a/qemu/roms/ipxe/src/include/ipxe/hmac.h
+++ b/qemu/roms/ipxe/src/include/ipxe/hmac.h
@@ -6,7 +6,7 @@
* Keyed-Hashing for Message Authentication
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/crypto.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/hmac_drbg.h b/qemu/roms/ipxe/src/include/ipxe/hmac_drbg.h
index 8dfd2924f..a0f22da75 100644
--- a/qemu/roms/ipxe/src/include/ipxe/hmac_drbg.h
+++ b/qemu/roms/ipxe/src/include/ipxe/hmac_drbg.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/crypto.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/http.h b/qemu/roms/ipxe/src/include/ipxe/http.h
index cf8c0c7fa..a0dff7d00 100644
--- a/qemu/roms/ipxe/src/include/ipxe/http.h
+++ b/qemu/roms/ipxe/src/include/ipxe/http.h
@@ -7,7 +7,26 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/refcnt.h>
+#include <ipxe/interface.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/process.h>
+#include <ipxe/retry.h>
+#include <ipxe/linebuf.h>
+#include <ipxe/pool.h>
+#include <ipxe/tables.h>
+
+struct http_transaction;
+
+/******************************************************************************
+ *
+ * HTTP URI schemes
+ *
+ ******************************************************************************
+ */
/** HTTP default port */
#define HTTP_PORT 80
@@ -15,10 +34,469 @@ FILE_LICENCE ( GPL2_OR_LATER );
/** HTTPS default port */
#define HTTPS_PORT 443
-extern int http_open_filter ( struct interface *xfer, struct uri *uri,
- unsigned int default_port,
- int ( * filter ) ( struct interface *,
- const char *,
- struct interface ** ) );
+/** An HTTP URI scheme */
+struct http_scheme {
+ /** Scheme name (e.g. "http" or "https") */
+ const char *name;
+ /** Default port */
+ unsigned int port;
+ /** Transport-layer filter (if any)
+ *
+ * @v xfer Data transfer interface
+ * @v name Host name
+ * @v next Next interface
+ * @ret rc Return status code
+ */
+ int ( * filter ) ( struct interface *xfer, const char *name,
+ struct interface **next );
+};
+
+/** HTTP scheme table */
+#define HTTP_SCHEMES __table ( struct http_scheme, "http_schemes" )
+
+/** Declare an HTTP scheme */
+#define __http_scheme __table_entry ( HTTP_SCHEMES, 01 )
+
+/******************************************************************************
+ *
+ * Connections
+ *
+ ******************************************************************************
+ */
+
+/** An HTTP connection
+ *
+ * This represents a potentially reusable connection to an HTTP
+ * server.
+ */
+struct http_connection {
+ /** Reference count */
+ struct refcnt refcnt;
+ /** Connection URI
+ *
+ * This encapsulates the server (and protocol) used for the
+ * connection. This may be the origin server or a proxy
+ * server.
+ */
+ struct uri *uri;
+ /** HTTP scheme */
+ struct http_scheme *scheme;
+ /** Transport layer interface */
+ struct interface socket;
+ /** Data transfer interface */
+ struct interface xfer;
+ /** Pooled connection */
+ struct pooled_connection pool;
+};
+
+/******************************************************************************
+ *
+ * HTTP methods
+ *
+ ******************************************************************************
+ */
+
+/** An HTTP method */
+struct http_method {
+ /** Method name (e.g. "GET" or "POST") */
+ const char *name;
+};
+
+extern struct http_method http_head;
+extern struct http_method http_get;
+extern struct http_method http_post;
+
+/******************************************************************************
+ *
+ * Requests
+ *
+ ******************************************************************************
+ */
+
+/** HTTP Digest authentication client nonce count
+ *
+ * We choose to generate a new client nonce each time.
+ */
+#define HTTP_DIGEST_NC "00000001"
+
+/** HTTP Digest authentication client nonce length
+ *
+ * We choose to use a 32-bit hex client nonce.
+ */
+#define HTTP_DIGEST_CNONCE_LEN 8
+
+/** HTTP Digest authentication response length
+ *
+ * The Digest authentication response is a Base16-encoded 16-byte MD5
+ * checksum.
+ */
+#define HTTP_DIGEST_RESPONSE_LEN 32
+
+/** HTTP request range descriptor */
+struct http_request_range {
+ /** Range start */
+ size_t start;
+ /** Range length, or zero for no range request */
+ size_t len;
+};
+
+/** HTTP request content descriptor */
+struct http_request_content {
+ /** Content type (if any) */
+ const char *type;
+ /** Content data (if any) */
+ const void *data;
+ /** Content length */
+ size_t len;
+};
+
+/** HTTP request authentication descriptor */
+struct http_request_auth {
+ /** Authentication scheme (if any) */
+ struct http_authentication *auth;
+ /** Username */
+ const char *username;
+ /** Password */
+ const char *password;
+ /** Quality of protection */
+ const char *qop;
+ /** Algorithm */
+ const char *algorithm;
+ /** Client nonce */
+ char cnonce[ HTTP_DIGEST_CNONCE_LEN + 1 /* NUL */ ];
+ /** Response */
+ char response[ HTTP_DIGEST_RESPONSE_LEN + 1 /* NUL */ ];
+};
+
+/** An HTTP request
+ *
+ * This represents a single request to be sent to a server, including
+ * the values required to construct all headers.
+ *
+ * Pointers within this structure must point to storage which is
+ * guaranteed to remain valid for the lifetime of the containing HTTP
+ * transaction.
+ */
+struct http_request {
+ /** Method */
+ struct http_method *method;
+ /** Request URI string */
+ const char *uri;
+ /** Server host name */
+ const char *host;
+ /** Range descriptor */
+ struct http_request_range range;
+ /** Content descriptor */
+ struct http_request_content content;
+ /** Authentication descriptor */
+ struct http_request_auth auth;
+};
+
+/** An HTTP request header */
+struct http_request_header {
+ /** Header name (e.g. "User-Agent") */
+ const char *name;
+ /** Construct remaining header line
+ *
+ * @v http HTTP transaction
+ * @v buf Buffer
+ * @v len Length of buffer
+ * @ret len Header length if present, or negative error
+ */
+ int ( * format ) ( struct http_transaction *http, char *buf,
+ size_t len );
+};
+
+/** HTTP request header table */
+#define HTTP_REQUEST_HEADERS \
+ __table ( struct http_request_header, "http_request_headers" )
+
+/** Declare an HTTP request header */
+#define __http_request_header __table_entry ( HTTP_REQUEST_HEADERS, 01 )
+
+/******************************************************************************
+ *
+ * Responses
+ *
+ ******************************************************************************
+ */
+
+/** HTTP response transfer descriptor */
+struct http_response_transfer {
+ /** Transfer encoding */
+ struct http_transfer_encoding *encoding;
+};
+
+/** HTTP response content descriptor */
+struct http_response_content {
+ /** Content length (may be zero) */
+ size_t len;
+ /** Content encoding */
+ struct http_content_encoding *encoding;
+};
+
+/** HTTP response authorization descriptor */
+struct http_response_auth {
+ /** Authentication scheme (if any) */
+ struct http_authentication *auth;
+ /** Realm */
+ const char *realm;
+ /** Quality of protection */
+ const char *qop;
+ /** Algorithm */
+ const char *algorithm;
+ /** Nonce */
+ const char *nonce;
+ /** Opaque */
+ const char *opaque;
+};
+
+/** An HTTP response
+ *
+ * This represents a single response received from the server,
+ * including all values parsed from headers.
+ *
+ * Pointers within this structure may point into the raw response
+ * buffer, and so should be invalidated when the response buffer is
+ * modified or discarded.
+ */
+struct http_response {
+ /** Raw response header lines
+ *
+ * This is the raw response data received from the server, up
+ * to and including the terminating empty line. String
+ * pointers within the response may point into this data
+ * buffer; NUL terminators will be added (overwriting the
+ * original terminating characters) as needed.
+ */
+ struct line_buffer headers;
+ /** Status code
+ *
+ * This is the raw HTTP numeric status code (e.g. 404).
+ */
+ unsigned int status;
+ /** Return status code
+ *
+ * This is the iPXE return status code corresponding to the
+ * HTTP status code (e.g. -ENOENT).
+ */
+ int rc;
+ /** Redirection location */
+ const char *location;
+ /** Transfer descriptor */
+ struct http_response_transfer transfer;
+ /** Content descriptor */
+ struct http_response_content content;
+ /** Authorization descriptor */
+ struct http_response_auth auth;
+ /** Retry delay (in seconds) */
+ unsigned int retry_after;
+ /** Flags */
+ unsigned int flags;
+};
+
+/** HTTP response flags */
+enum http_response_flags {
+ /** Keep connection alive after close */
+ HTTP_RESPONSE_KEEPALIVE = 0x0001,
+ /** Content length specified */
+ HTTP_RESPONSE_CONTENT_LEN = 0x0002,
+ /** Transaction may be retried on failure */
+ HTTP_RESPONSE_RETRY = 0x0004,
+};
+
+/** An HTTP response header */
+struct http_response_header {
+ /** Header name (e.g. "Transfer-Encoding") */
+ const char *name;
+ /** Parse header line
+ *
+ * @v http HTTP transaction
+ * @v line Remaining header line
+ * @ret rc Return status code
+ */
+ int ( * parse ) ( struct http_transaction *http, char *line );
+};
+
+/** HTTP response header table */
+#define HTTP_RESPONSE_HEADERS \
+ __table ( struct http_response_header, "http_response_headers" )
+
+/** Declare an HTTP response header */
+#define __http_response_header __table_entry ( HTTP_RESPONSE_HEADERS, 01 )
+
+/******************************************************************************
+ *
+ * Transactions
+ *
+ ******************************************************************************
+ */
+
+/** HTTP transaction state */
+struct http_state {
+ /** Transmit data
+ *
+ * @v http HTTP transaction
+ * @ret rc Return status code
+ */
+ int ( * tx ) ( struct http_transaction *http );
+ /** Receive data
+ *
+ * @v http HTTP transaction
+ * @v iobuf I/O buffer (may be claimed)
+ * @ret rc Return status code
+ */
+ int ( * rx ) ( struct http_transaction *http,
+ struct io_buffer **iobuf );
+ /** Server connection closed
+ *
+ * @v http HTTP transaction
+ * @v rc Reason for close
+ */
+ void ( * close ) ( struct http_transaction *http, int rc );
+};
+
+/** An HTTP transaction */
+struct http_transaction {
+ /** Reference count */
+ struct refcnt refcnt;
+ /** Data transfer interface */
+ struct interface xfer;
+ /** Content-decoded interface */
+ struct interface content;
+ /** Transfer-decoded interface */
+ struct interface transfer;
+ /** Server connection */
+ struct interface conn;
+ /** Transmit process */
+ struct process process;
+ /** Reconnection timer */
+ struct retry_timer timer;
+
+ /** Request URI */
+ struct uri *uri;
+ /** Request */
+ struct http_request request;
+ /** Response */
+ struct http_response response;
+ /** Temporary line buffer */
+ struct line_buffer linebuf;
+
+ /** Transaction state */
+ struct http_state *state;
+ /** Accumulated transfer-decoded length */
+ size_t len;
+ /** Chunk length remaining */
+ size_t remaining;
+};
+
+/******************************************************************************
+ *
+ * Transfer encoding
+ *
+ ******************************************************************************
+ */
+
+/** An HTTP transfer encoding */
+struct http_transfer_encoding {
+ /** Name */
+ const char *name;
+ /** Initialise transfer encoding
+ *
+ * @v http HTTP transaction
+ * @ret rc Return status code
+ */
+ int ( * init ) ( struct http_transaction *http );
+ /** Receive data state */
+ struct http_state state;
+};
+
+/** HTTP transfer encoding table */
+#define HTTP_TRANSFER_ENCODINGS \
+ __table ( struct http_transfer_encoding, "http_transfer_encodings" )
+
+/** Declare an HTTP transfer encoding */
+#define __http_transfer_encoding __table_entry ( HTTP_TRANSFER_ENCODINGS, 01 )
+
+/******************************************************************************
+ *
+ * Content encoding
+ *
+ ******************************************************************************
+ */
+
+/** An HTTP content encoding */
+struct http_content_encoding {
+ /** Name */
+ const char *name;
+ /** Check if content encoding is supported for this request
+ *
+ * @v http HTTP transaction
+ * @ret supported Content encoding is supported for this request
+ */
+ int ( * supported ) ( struct http_transaction *http );
+ /** Initialise content encoding
+ *
+ * @v http HTTP transaction
+ * @ret rc Return status code
+ */
+ int ( * init ) ( struct http_transaction *http );
+};
+
+/** HTTP content encoding table */
+#define HTTP_CONTENT_ENCODINGS \
+ __table ( struct http_content_encoding, "http_content_encodings" )
+
+/** Declare an HTTP content encoding */
+#define __http_content_encoding __table_entry ( HTTP_CONTENT_ENCODINGS, 01 )
+
+/******************************************************************************
+ *
+ * Authentication
+ *
+ ******************************************************************************
+ */
+
+/** An HTTP authentication scheme */
+struct http_authentication {
+ /** Name (e.g. "Digest") */
+ const char *name;
+ /** Perform authentication
+ *
+ * @v http HTTP transaction
+ * @ret rc Return status code
+ */
+ int ( * authenticate ) ( struct http_transaction *http );
+ /** Construct remaining "Authorization" header line
+ *
+ * @v http HTTP transaction
+ * @v buf Buffer
+ * @v len Length of buffer
+ * @ret len Header length if present, or negative error
+ */
+ int ( * format ) ( struct http_transaction *http, char *buf,
+ size_t len );
+};
+
+/** HTTP authentication scheme table */
+#define HTTP_AUTHENTICATIONS \
+ __table ( struct http_authentication, "http_authentications" )
+
+/** Declare an HTTP authentication scheme */
+#define __http_authentication __table_entry ( HTTP_AUTHENTICATIONS, 01 )
+
+/******************************************************************************
+ *
+ * General
+ *
+ ******************************************************************************
+ */
+
+extern char * http_token ( char **line, char **value );
+extern int http_connect ( struct interface *xfer, struct uri *uri );
+extern int http_open ( struct interface *xfer, struct http_method *method,
+ struct uri *uri, struct http_request_range *range,
+ struct http_request_content *content );
+extern int http_open_uri ( struct interface *xfer, struct uri *uri );
#endif /* _IPXE_HTTP_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/hyperv.h b/qemu/roms/ipxe/src/include/ipxe/hyperv.h
new file mode 100644
index 000000000..c61e2a083
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/hyperv.h
@@ -0,0 +1,232 @@
+#ifndef _IPXE_HYPERV_H
+#define _IPXE_HYPERV_H
+
+/** @file
+ *
+ * Hyper-V interface
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/io.h>
+
+/** Hyper-V interface identification */
+#define HV_INTERFACE_ID 0x31237648 /* "Hv#1" */
+
+/** Guest OS identity for iPXE
+ *
+ * This field comprises:
+ *
+ * Bit 63 : set to 1 to indicate an open source OS
+ * Bits 62:56 : OS Type
+ * Bits 55:48 : OS ID
+ * Bits 47:16 : Version
+ * Bits 15:0 : Build number
+ *
+ * There appears to be no central registry for the "OS Type". The
+ * specification states that "Linux is 0x100", and the FreeBSD source
+ * states that "FreeBSD is 0x200". Both of these statements are
+ * actually referring to the combined "OS Type" and "OS ID" field.
+ *
+ * We choose to use 0x98ae: this is generated by setting bit 63 (to
+ * indicate an open source OS) and setting the OS Type+ID equal to the
+ * PnP vendor ID used in romprefix.S. No version information or build
+ * number is included.
+ */
+#define HV_GUEST_OS_ID_IPXE ( ( 1ULL << 63 ) | ( 0x18aeULL << 48 ) )
+
+/** Enable hypercall page */
+#define HV_HYPERCALL_ENABLE 0x00000001UL
+
+/** Enable SynIC */
+#define HV_SCONTROL_ENABLE 0x00000001UL
+
+/** Enable SynIC event flags */
+#define HV_SIEFP_ENABLE 0x00000001UL
+
+/** Enable SynIC messages */
+#define HV_SIMP_ENABLE 0x00000001UL
+
+/** Perform implicit EOI upon synthetic interrupt delivery */
+#define HV_SINT_AUTO_EOI 0x00020000UL
+
+/** Mask synthetic interrupt */
+#define HV_SINT_MASKED 0x00010000UL
+
+/** Synthetic interrupt vector */
+#define HV_SINT_VECTOR(x) ( (x) << 0 )
+
+/** Synthetic interrupt vector mask */
+#define HV_SINT_VECTOR_MASK HV_SINT_VECTOR ( 0xff )
+
+/** Post message */
+#define HV_POST_MESSAGE 0x005c
+
+/** A posted message
+ *
+ * This is the input parameter list for the HvPostMessage hypercall.
+ */
+struct hv_post_message {
+ /** Connection ID */
+ uint32_t id;
+ /** Padding */
+ uint32_t reserved;
+ /** Type */
+ uint32_t type;
+ /** Length of message */
+ uint32_t len;
+ /** Message */
+ uint8_t data[240];
+} __attribute__ (( packed ));
+
+/** A received message
+ *
+ * This is the HV_MESSAGE structure from the Hypervisor Top-Level
+ * Functional Specification. The field order given in the
+ * documentation is incorrect.
+ */
+struct hv_message {
+ /** Type */
+ uint32_t type;
+ /** Length of message */
+ uint8_t len;
+ /** Flags */
+ uint8_t flags;
+ /** Padding */
+ uint16_t reserved;
+ /** Origin */
+ uint64_t origin;
+ /** Message */
+ uint8_t data[240];
+} __attribute__ (( packed ));
+
+/** Signal event */
+#define HV_SIGNAL_EVENT 0x005d
+
+/** A signalled event */
+struct hv_signal_event {
+ /** Connection ID */
+ uint32_t id;
+ /** Flag number */
+ uint16_t flag;
+ /** Reserved */
+ uint16_t reserved;
+} __attribute__ (( packed ));
+
+/** A received event */
+struct hv_event {
+ /** Event flags */
+ uint8_t flags[256];
+} __attribute__ (( packed ));
+
+/** A monitor trigger group
+ *
+ * This is the HV_MONITOR_TRIGGER_GROUP structure from the Hypervisor
+ * Top-Level Functional Specification.
+ */
+struct hv_monitor_trigger {
+ /** Pending events */
+ uint32_t pending;
+ /** Armed events */
+ uint32_t armed;
+} __attribute__ (( packed ));
+
+/** A monitor parameter set
+ *
+ * This is the HV_MONITOR_PARAMETER structure from the Hypervisor
+ * Top-Level Functional Specification.
+ */
+struct hv_monitor_parameter {
+ /** Connection ID */
+ uint32_t id;
+ /** Flag number */
+ uint16_t flag;
+ /** Reserved */
+ uint16_t reserved;
+} __attribute__ (( packed ));
+
+/** A monitor page
+ *
+ * This is the HV_MONITOR_PAGE structure from the Hypervisor Top-Level
+ * Functional Specification.
+ */
+struct hv_monitor {
+ /** Flags */
+ uint32_t flags;
+ /** Reserved */
+ uint8_t reserved_a[4];
+ /** Trigger groups */
+ struct hv_monitor_trigger trigger[4];
+ /** Reserved */
+ uint8_t reserved_b[536];
+ /** Latencies */
+ uint16 latency[4][32];
+ /** Reserved */
+ uint8_t reserved_c[256];
+ /** Parameters */
+ struct hv_monitor_parameter param[4][32];
+ /** Reserved */
+ uint8_t reserved_d[1984];
+} __attribute__ (( packed ));
+
+/** A synthetic interrupt controller */
+struct hv_synic {
+ /** Message page */
+ struct hv_message *message;
+ /** Event flag page */
+ struct hv_event *event;
+};
+
+/** A message buffer */
+union hv_message_buffer {
+ /** Posted message */
+ struct hv_post_message posted;
+ /** Received message */
+ struct hv_message received;
+ /** Signalled event */
+ struct hv_signal_event signalled;
+};
+
+/** A Hyper-V hypervisor */
+struct hv_hypervisor {
+ /** Hypercall page */
+ void *hypercall;
+ /** Synthetic interrupt controller (SynIC) */
+ struct hv_synic synic;
+ /** Message buffer */
+ union hv_message_buffer *message;
+ /** Virtual machine bus */
+ struct vmbus *vmbus;
+};
+
+#include <bits/hyperv.h>
+
+/**
+ * Calculate the number of pages covering an address range
+ *
+ * @v data Start of data
+ * @v len Length of data (must be non-zero)
+ * @ret pfn_count Number of pages covered
+ */
+static inline unsigned int hv_pfn_count ( physaddr_t data, size_t len ) {
+ unsigned int first_pfn = ( data / PAGE_SIZE );
+ unsigned int last_pfn = ( ( data + len - 1 ) / PAGE_SIZE );
+
+ return ( last_pfn - first_pfn + 1 );
+}
+
+extern __attribute__ (( sentinel )) int
+hv_alloc_pages ( struct hv_hypervisor *hv, ... );
+extern __attribute__ (( sentinel )) void
+hv_free_pages ( struct hv_hypervisor *hv, ... );
+extern void hv_enable_sint ( struct hv_hypervisor *hv, unsigned int sintx );
+extern void hv_disable_sint ( struct hv_hypervisor *hv, unsigned int sintx );
+extern int hv_post_message ( struct hv_hypervisor *hv, unsigned int id,
+ unsigned int type, const void *data, size_t len );
+extern int hv_wait_for_message ( struct hv_hypervisor *hv, unsigned int sintx );
+extern int hv_signal_event ( struct hv_hypervisor *hv, unsigned int id,
+ unsigned int flag );
+
+#endif /* _IPXE_HYPERV_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/i2c.h b/qemu/roms/ipxe/src/include/ipxe/i2c.h
index c1f5a9bbd..46970515c 100644
--- a/qemu/roms/ipxe/src/include/ipxe/i2c.h
+++ b/qemu/roms/ipxe/src/include/ipxe/i2c.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/bitbash.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ib_cm.h b/qemu/roms/ipxe/src/include/ipxe/ib_cm.h
index 7d08cd9b1..4913eebae 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ib_cm.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ib_cm.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/infiniband.h>
#include <ipxe/retry.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ib_mad.h b/qemu/roms/ipxe/src/include/ipxe/ib_mad.h
index b8694833e..ae1eea7e4 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ib_mad.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ib_mad.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/ib_packet.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ib_mcast.h b/qemu/roms/ipxe/src/include/ipxe/ib_mcast.h
index a5c22a03e..564066975 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ib_mcast.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ib_mcast.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/infiniband.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ib_mi.h b/qemu/roms/ipxe/src/include/ipxe/ib_mi.h
index 5c5415b71..c7c8143ba 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ib_mi.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ib_mi.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/list.h>
#include <ipxe/retry.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ib_packet.h b/qemu/roms/ipxe/src/include/ipxe/ib_packet.h
index a959967cb..f275fcb09 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ib_packet.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ib_packet.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct ib_device;
struct ib_queue_pair;
diff --git a/qemu/roms/ipxe/src/include/ipxe/ib_pathrec.h b/qemu/roms/ipxe/src/include/ipxe/ib_pathrec.h
index 1fe67f87d..a4e11ebe3 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ib_pathrec.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ib_pathrec.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/infiniband.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ib_sma.h b/qemu/roms/ipxe/src/include/ipxe/ib_sma.h
index fa355c652..74003d045 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ib_sma.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ib_sma.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct ib_device;
struct ib_mad_interface;
diff --git a/qemu/roms/ipxe/src/include/ipxe/ib_smc.h b/qemu/roms/ipxe/src/include/ipxe/ib_smc.h
index 259d2cde1..f9b96b1bd 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ib_smc.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ib_smc.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/infiniband.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/icmp.h b/qemu/roms/ipxe/src/include/ipxe/icmp.h
index 0480ddfaf..803f8e019 100644
--- a/qemu/roms/ipxe/src/include/ipxe/icmp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/icmp.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/iobuf.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/icmpv6.h b/qemu/roms/ipxe/src/include/ipxe/icmpv6.h
index b5ea54eab..0474ddca8 100644
--- a/qemu/roms/ipxe/src/include/ipxe/icmpv6.h
+++ b/qemu/roms/ipxe/src/include/ipxe/icmpv6.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/tables.h>
@@ -40,6 +40,18 @@ struct icmpv6_handler {
/** Declare an ICMPv6 handler */
#define __icmpv6_handler __table_entry ( ICMPV6_HANDLERS, 01 )
+/** ICMPv6 destination unreachable */
+#define ICMPV6_DESTINATION_UNREACHABLE 1
+
+/** ICMPv6 packet too big */
+#define ICMPV6_PACKET_TOO_BIG 2
+
+/** ICMPv6 time exceeded */
+#define ICMPV6_TIME_EXCEEDED 3
+
+/** ICMPv6 parameter problem */
+#define ICMPV6_PARAMETER_PROBLEM 4
+
/** ICMPv6 echo request */
#define ICMPV6_ECHO_REQUEST 128
diff --git a/qemu/roms/ipxe/src/include/ipxe/if_arp.h b/qemu/roms/ipxe/src/include/ipxe/if_arp.h
index fd36e9c67..4eb1f80b7 100644
--- a/qemu/roms/ipxe/src/include/ipxe/if_arp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/if_arp.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/if_ether.h b/qemu/roms/ipxe/src/include/ipxe/if_ether.h
index a7e237349..58d91b976 100644
--- a/qemu/roms/ipxe/src/include/ipxe/if_ether.h
+++ b/qemu/roms/ipxe/src/include/ipxe/if_ether.h
@@ -1,7 +1,7 @@
#ifndef _IPXE_IF_ETHER_H
#define _IPXE_IF_ETHER_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/image.h b/qemu/roms/ipxe/src/include/ipxe/image.h
index 5d7080a75..6abd7a2d2 100644
--- a/qemu/roms/ipxe/src/include/ipxe/image.h
+++ b/qemu/roms/ipxe/src/include/ipxe/image.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/tables.h>
#include <ipxe/list.h>
@@ -163,7 +163,6 @@ extern int image_set_cmdline ( struct image *image, const char *cmdline );
extern int register_image ( struct image *image );
extern void unregister_image ( struct image *image );
struct image * find_image ( const char *name );
-extern int image_probe ( struct image *image );
extern int image_exec ( struct image *image );
extern int image_replace ( struct image *replacement );
extern int image_select ( struct image *image );
diff --git a/qemu/roms/ipxe/src/include/ipxe/in.h b/qemu/roms/ipxe/src/include/ipxe/in.h
index de96ca22a..0ebf441c2 100644
--- a/qemu/roms/ipxe/src/include/ipxe/in.h
+++ b/qemu/roms/ipxe/src/include/ipxe/in.h
@@ -1,9 +1,10 @@
#ifndef _IPXE_IN_H
#define _IPXE_IN_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
+#include <byteswap.h>
#include <ipxe/socket.h>
/* Protocol numbers */
@@ -15,17 +16,22 @@ FILE_LICENCE ( GPL2_OR_LATER );
/* IP address constants */
-#define INADDR_NONE 0xffffffff
+#define INADDR_NONE htonl ( 0xffffffff )
-#define INADDR_BROADCAST 0xffffffff
+#define INADDR_BROADCAST htonl ( 0xffffffff )
-#define IN_CLASSA(addr) ( ( (addr) & 0x80000000 ) == 0x00000000 )
-#define IN_CLASSA_NET 0xff000000
-#define IN_CLASSB(addr) ( ( (addr) & 0xc0000000 ) == 0x80000000 )
-#define IN_CLASSB_NET 0xffff0000
-#define IN_CLASSC(addr) ( ( (addr) & 0xe0000000 ) == 0xc0000000 )
-#define IN_CLASSC_NET 0xffffff00
-#define IN_MULTICAST(addr) ( ( (addr) & 0xf0000000 ) == 0xe0000000 )
+#define INADDR_NET_CLASSA htonl ( 0xff000000 )
+#define INADDR_NET_CLASSB htonl ( 0xffff0000 )
+#define INADDR_NET_CLASSC htonl ( 0xffffff00 )
+
+#define IN_IS_CLASSA( addr ) \
+ ( ( (addr) & htonl ( 0x80000000 ) ) == htonl ( 0x00000000 ) )
+#define IN_IS_CLASSB( addr ) \
+ ( ( (addr) & htonl ( 0xc0000000 ) ) == htonl ( 0x80000000 ) )
+#define IN_IS_CLASSC( addr ) \
+ ( ( (addr) & htonl ( 0xe0000000 ) ) == htonl ( 0xc0000000 ) )
+#define IN_IS_MULTICAST( addr ) \
+ ( ( (addr) & htonl ( 0xf0000000 ) ) == htonl ( 0xe0000000 ) )
/**
* IP address structure
@@ -63,6 +69,9 @@ struct in6_addr {
( ( *( ( const uint16_t * ) (addr) ) & htons ( 0xffc0 ) ) == \
htons ( 0xfe80 ) )
+#define IN6_IS_ADDR_NONGLOBAL( addr ) \
+ ( IN6_IS_ADDR_LINKLOCAL (addr) || IN6_IS_ADDR_MULTICAST (addr) )
+
/**
* IPv4 socket address
*/
@@ -76,6 +85,11 @@ struct sockaddr_in {
uint16_t sin_flags;
/** TCP/IP port (part of struct @c sockaddr_tcpip) */
uint16_t sin_port;
+ /** Scope ID (part of struct @c sockaddr_tcpip)
+ *
+ * For multicast addresses, this is the network device index.
+ */
+ uint16_t sin_scope_id;
/** IPv4 address */
struct in_addr sin_addr;
/** Padding
@@ -87,6 +101,7 @@ struct sockaddr_in {
( sizeof ( sa_family_t ) /* sin_family */ +
sizeof ( uint16_t ) /* sin_flags */ +
sizeof ( uint16_t ) /* sin_port */ +
+ sizeof ( uint16_t ) /* sin_scope_id */ +
sizeof ( struct in_addr ) /* sin_addr */ ) ];
} __attribute__ (( packed, may_alias ));
@@ -103,9 +118,10 @@ struct sockaddr_in6 {
uint16_t sin6_flags;
/** TCP/IP port (part of struct @c sockaddr_tcpip) */
uint16_t sin6_port;
- /** Scope ID
+ /** Scope ID (part of struct @c sockaddr_tcpip)
*
- * For link-local addresses, this is the network device index.
+ * For link-local or multicast addresses, this is the network
+ * device index.
*/
uint16_t sin6_scope_id;
/** IPv6 address */
diff --git a/qemu/roms/ipxe/src/include/ipxe/infiniband.h b/qemu/roms/ipxe/src/include/ipxe/infiniband.h
index f546ea61b..87cfe5082 100644
--- a/qemu/roms/ipxe/src/include/ipxe/infiniband.h
+++ b/qemu/roms/ipxe/src/include/ipxe/infiniband.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/refcnt.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/init.h b/qemu/roms/ipxe/src/include/ipxe/init.h
index 19c5925bf..025cfaf37 100644
--- a/qemu/roms/ipxe/src/include/ipxe/init.h
+++ b/qemu/roms/ipxe/src/include/ipxe/init.h
@@ -1,7 +1,7 @@
#ifndef _IPXE_INIT_H
#define _IPXE_INIT_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/tables.h>
@@ -26,10 +26,9 @@ struct init_fn {
*/
#define INIT_EARLY 01 /**< Early initialisation */
-#define INIT_SERIAL 02 /**< Serial driver initialisation */
-#define INIT_CONSOLE 03 /**< Console initialisation */
-#define INIT_NORMAL 04 /**< Normal initialisation */
-#define INIT_LATE 05 /**< Late initialisation */
+#define INIT_CONSOLE 02 /**< Console initialisation */
+#define INIT_NORMAL 03 /**< Normal initialisation */
+#define INIT_LATE 04 /**< Late initialisation */
/** @} */
diff --git a/qemu/roms/ipxe/src/include/ipxe/interface.h b/qemu/roms/ipxe/src/include/ipxe/interface.h
index a474aaad0..a8d823775 100644
--- a/qemu/roms/ipxe/src/include/ipxe/interface.h
+++ b/qemu/roms/ipxe/src/include/ipxe/interface.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <ipxe/refcnt.h>
@@ -145,6 +145,11 @@ extern void intf_close ( struct interface *intf, int rc );
extern void intf_shutdown ( struct interface *intf, int rc );
extern void intf_restart ( struct interface *intf, int rc );
+extern void intf_poke ( struct interface *intf,
+ void ( type ) ( struct interface *intf ) );
+#define intf_poke_TYPE( object_type ) \
+ typeof ( void ( object_type ) )
+
extern struct interface_descriptor null_intf_desc;
extern struct interface null_intf;
diff --git a/qemu/roms/ipxe/src/include/ipxe/io.h b/qemu/roms/ipxe/src/include/ipxe/io.h
index 29ccfd1fa..af767915d 100644
--- a/qemu/roms/ipxe/src/include/ipxe/io.h
+++ b/qemu/roms/ipxe/src/include/ipxe/io.h
@@ -16,7 +16,7 @@
* the address parameter.
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/api.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/iobuf.h b/qemu/roms/ipxe/src/include/ipxe/iobuf.h
index b2b0cb440..27d285d44 100644
--- a/qemu/roms/ipxe/src/include/ipxe/iobuf.h
+++ b/qemu/roms/ipxe/src/include/ipxe/iobuf.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <assert.h>
@@ -217,5 +217,6 @@ extern void free_iob ( struct io_buffer *iobuf );
extern void iob_pad ( struct io_buffer *iobuf, size_t min_len );
extern int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len );
extern struct io_buffer * iob_concatenate ( struct list_head *list );
+extern struct io_buffer * iob_split ( struct io_buffer *iobuf, size_t len );
#endif /* _IPXE_IOBUF_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/ip.h b/qemu/roms/ipxe/src/include/ipxe/ip.h
index 1a93a552e..285be6dcd 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ip.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ip.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/in.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ipoib.h b/qemu/roms/ipxe/src/include/ipxe/ipoib.h
index 68ff8df49..b34dd32d0 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ipoib.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ipoib.h
@@ -6,7 +6,7 @@
* IP over Infiniband
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/if_arp.h>
#include <ipxe/infiniband.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ipstat.h b/qemu/roms/ipxe/src/include/ipxe/ipstat.h
index c554c1859..b34ed5fcf 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ipstat.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ipstat.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/tables.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ipv6.h b/qemu/roms/ipxe/src/include/ipxe/ipv6.h
index 48aaf677e..b500382c1 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ipv6.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ipv6.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/isa_ids.h b/qemu/roms/ipxe/src/include/ipxe/isa_ids.h
index 1faf1148d..d815bda34 100644
--- a/qemu/roms/ipxe/src/include/ipxe/isa_ids.h
+++ b/qemu/roms/ipxe/src/include/ipxe/isa_ids.h
@@ -19,7 +19,7 @@
* the underlying "meaning" is big-endian.
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <byteswap.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/isapnp.h b/qemu/roms/ipxe/src/include/ipxe/isapnp.h
index b0b0e98d6..59beac986 100644
--- a/qemu/roms/ipxe/src/include/ipxe/isapnp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/isapnp.h
@@ -17,6 +17,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
*
* Portions of this code:
* Copyright (C) 2001 P.J.H.Fox (fox@roestock.demon.co.uk)
@@ -34,7 +38,7 @@
*
***************************************************************************/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifndef ISAPNP_H
#define ISAPNP_H
diff --git a/qemu/roms/ipxe/src/include/ipxe/iscsi.h b/qemu/roms/ipxe/src/include/ipxe/iscsi.h
index be71360a0..c75ff4188 100644
--- a/qemu/roms/ipxe/src/include/ipxe/iscsi.h
+++ b/qemu/roms/ipxe/src/include/ipxe/iscsi.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/socket.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/iso9660.h b/qemu/roms/ipxe/src/include/ipxe/iso9660.h
index 02c2ae377..34cb8f0a1 100644
--- a/qemu/roms/ipxe/src/include/ipxe/iso9660.h
+++ b/qemu/roms/ipxe/src/include/ipxe/iso9660.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/isqrt.h b/qemu/roms/ipxe/src/include/ipxe/isqrt.h
index 58ed42f0c..68255d1bc 100644
--- a/qemu/roms/ipxe/src/include/ipxe/isqrt.h
+++ b/qemu/roms/ipxe/src/include/ipxe/isqrt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern unsigned long isqrt ( unsigned long value );
diff --git a/qemu/roms/ipxe/src/include/ipxe/job.h b/qemu/roms/ipxe/src/include/ipxe/job.h
index a2369f7c2..7e1bd8109 100644
--- a/qemu/roms/ipxe/src/include/ipxe/job.h
+++ b/qemu/roms/ipxe/src/include/ipxe/job.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/interface.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/jumpscroll.h b/qemu/roms/ipxe/src/include/ipxe/jumpscroll.h
new file mode 100644
index 000000000..7a5b111c1
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/jumpscroll.h
@@ -0,0 +1,50 @@
+#ifndef _IPXE_JUMPSCROLL_H
+#define _IPXE_JUMPSCROLL_H
+
+/** @file
+ *
+ * Jump scrolling
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+/** A jump scroller */
+struct jump_scroller {
+ /** Maximum number of visible rows */
+ unsigned int rows;
+ /** Total number of items */
+ unsigned int count;
+ /** Currently selected item */
+ unsigned int current;
+ /** First visible item */
+ unsigned int first;
+};
+
+/**
+ * Check if jump scroller is currently on first page
+ *
+ * @v scroll Jump scroller
+ * @ret is_first Scroller is currently on first page
+ */
+static inline int jump_scroll_is_first ( struct jump_scroller *scroll ) {
+
+ return ( scroll->first == 0 );
+}
+
+/**
+ * Check if jump scroller is currently on last page
+ *
+ * @v scroll Jump scroller
+ * @ret is_last Scroller is currently on last page
+ */
+static inline int jump_scroll_is_last ( struct jump_scroller *scroll ) {
+
+ return ( ( scroll->first + scroll->rows ) >= scroll->count );
+}
+
+extern int jump_scroll_key ( struct jump_scroller *scroll, int key );
+extern int jump_scroll_move ( struct jump_scroller *scroll, int move );
+extern int jump_scroll ( struct jump_scroller *scroll );
+
+#endif /* _IPXE_JUMPSCROLL_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/keymap.h b/qemu/roms/ipxe/src/include/ipxe/keymap.h
index 9ac42a6b1..0f1b0c656 100644
--- a/qemu/roms/ipxe/src/include/ipxe/keymap.h
+++ b/qemu/roms/ipxe/src/include/ipxe/keymap.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/tables.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/keys.h b/qemu/roms/ipxe/src/include/ipxe/keys.h
index 8b13550b9..d15267a1f 100644
--- a/qemu/roms/ipxe/src/include/ipxe/keys.h
+++ b/qemu/roms/ipxe/src/include/ipxe/keys.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/*
* Symbolic names for some standard ASCII characters
@@ -58,6 +58,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
*/
#define KEY_ANSI( n, terminator ) ( 0x100 * ( (n) + 1 ) + (terminator) )
+#define KEY_ANSI_N( key ) ( ( (key) / 0x100 ) - 1 )
+#define KEY_ANSI_TERMINATOR( key ) ( (key) & 0xff )
#define KEY_MIN 0x101
#define KEY_UP KEY_ANSI ( 0, 'A' ) /**< Up arrow */
diff --git a/qemu/roms/ipxe/src/include/ipxe/linebuf.h b/qemu/roms/ipxe/src/include/ipxe/linebuf.h
index 706ef2554..630278a04 100644
--- a/qemu/roms/ipxe/src/include/ipxe/linebuf.h
+++ b/qemu/roms/ipxe/src/include/ipxe/linebuf.h
@@ -7,24 +7,24 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stddef.h>
/** A line buffer */
struct line_buffer {
- /** Current string in the buffer */
+ /** Data buffer */
char *data;
- /** Length of current string, excluding the terminating NUL */
+ /** Length of buffered data */
size_t len;
- /** String is ready to read */
- int ready;
+ /** Most recently consumed length */
+ size_t consumed;
};
extern char * buffered_line ( struct line_buffer *linebuf );
-extern ssize_t line_buffer ( struct line_buffer *linebuf,
- const char *data, size_t len );
+extern int line_buffer ( struct line_buffer *linebuf,
+ const char *data, size_t len );
extern void empty_line_buffer ( struct line_buffer *linebuf );
#endif /* _IPXE_LINEBUF_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/lineconsole.h b/qemu/roms/ipxe/src/include/ipxe/lineconsole.h
index 925c0accc..31117e73c 100644
--- a/qemu/roms/ipxe/src/include/ipxe/lineconsole.h
+++ b/qemu/roms/ipxe/src/include/ipxe/lineconsole.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/ansiesc.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/linux/linux_entropy.h b/qemu/roms/ipxe/src/include/ipxe/linux/linux_entropy.h
index bd89bd52f..afef6fe19 100644
--- a/qemu/roms/ipxe/src/include/ipxe/linux/linux_entropy.h
+++ b/qemu/roms/ipxe/src/include/ipxe/linux/linux_entropy.h
@@ -3,11 +3,11 @@
/** @file
*
- * iPXE entropy API for linux
+ * /dev/random-based entropy source
*
*/
-FILE_LICENCE(GPL2_OR_LATER);
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef ENTROPY_LINUX
#define ENTROPY_PREFIX_linux
@@ -23,10 +23,12 @@ FILE_LICENCE(GPL2_OR_LATER);
static inline __always_inline double
ENTROPY_INLINE ( linux, min_entropy_per_sample ) ( void ) {
- /* We read single bytes from /dev/random and assume that each
- * contains full entropy.
+ /* linux_get_noise() reads a single byte from /dev/random,
+ * which is supposed to block until a sufficient amount of
+ * entropy is available. We therefore assume that each sample
+ * contains exactly 8 bits of entropy.
*/
- return 8;
+ return 8.0;
}
#endif /* _IPXE_LINUX_ENTROPY_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/linux/linux_nap.h b/qemu/roms/ipxe/src/include/ipxe/linux/linux_nap.h
index 5bac7242f..d072886c7 100644
--- a/qemu/roms/ipxe/src/include/ipxe/linux/linux_nap.h
+++ b/qemu/roms/ipxe/src/include/ipxe/linux/linux_nap.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE(GPL2_OR_LATER);
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef NAP_LINUX
#define NAP_PREFIX_linux
diff --git a/qemu/roms/ipxe/src/include/ipxe/linux/linux_pci.h b/qemu/roms/ipxe/src/include/ipxe/linux/linux_pci.h
index 439166733..22ae7f1bc 100644
--- a/qemu/roms/ipxe/src/include/ipxe/linux/linux_pci.h
+++ b/qemu/roms/ipxe/src/include/ipxe/linux/linux_pci.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef PCIAPI_LINUX
#define PCIAPI_PREFIX_linux
diff --git a/qemu/roms/ipxe/src/include/ipxe/linux/linux_smbios.h b/qemu/roms/ipxe/src/include/ipxe/linux/linux_smbios.h
index 6d51e13ba..16c6d8acd 100644
--- a/qemu/roms/ipxe/src/include/ipxe/linux/linux_smbios.h
+++ b/qemu/roms/ipxe/src/include/ipxe/linux/linux_smbios.h
@@ -3,11 +3,11 @@
/** @file
*
- * iPXE SMBIOS API for linux
+ * iPXE SMBIOS API for Linux
*
*/
-FILE_LICENCE(GPL2_OR_LATER);
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef SMBIOS_LINUX
#define SMBIOS_PREFIX_linux
diff --git a/qemu/roms/ipxe/src/include/ipxe/linux/linux_time.h b/qemu/roms/ipxe/src/include/ipxe/linux/linux_time.h
index 93a257730..872ef5ade 100644
--- a/qemu/roms/ipxe/src/include/ipxe/linux/linux_time.h
+++ b/qemu/roms/ipxe/src/include/ipxe/linux/linux_time.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef TIME_LINUX
#define TIME_PREFIX_linux
diff --git a/qemu/roms/ipxe/src/include/ipxe/linux/linux_timer.h b/qemu/roms/ipxe/src/include/ipxe/linux/linux_timer.h
index 379507417..7f46e36b2 100644
--- a/qemu/roms/ipxe/src/include/ipxe/linux/linux_timer.h
+++ b/qemu/roms/ipxe/src/include/ipxe/linux/linux_timer.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef TIMER_LINUX
#define TIMER_PREFIX_linux
diff --git a/qemu/roms/ipxe/src/include/ipxe/linux/linux_uaccess.h b/qemu/roms/ipxe/src/include/ipxe/linux/linux_uaccess.h
index e4d16d9e0..acd919a85 100644
--- a/qemu/roms/ipxe/src/include/ipxe/linux/linux_uaccess.h
+++ b/qemu/roms/ipxe/src/include/ipxe/linux/linux_uaccess.h
@@ -1,116 +1,108 @@
-/*
- * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
- *
- * 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 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
#ifndef _IPXE_LINUX_UACCESS_H
#define _IPXE_LINUX_UACCESS_H
-FILE_LICENCE(GPL2_OR_LATER);
-
/** @file
*
- * iPXE user access API for linux
+ * iPXE user access API for Linux
+ *
+ * We run with no distinction between internal and external addresses,
+ * so can use trivial_virt_to_user() et al.
*
- * In linux userspace virtual == user == phys addresses.
- * Physical addresses also being the same is wrong, but there is no general way
- * of converting userspace addresses to physical as what appears to be
- * contiguous in userspace is physically fragmented.
- * Currently only the DMA memory is special-cased, but its conversion to bus
- * addresses is done in phys_to_bus.
- * This is known to break virtio as it is passing phys addresses to the virtual
- * device.
+ * We have no concept of the underlying physical addresses, since
+ * these are not exposed to userspace. We provide a stub
+ * implementation of user_to_phys() since this is required by
+ * alloc_memblock(). We provide no implementation of phys_to_user();
+ * any code attempting to access physical addresses will therefore
+ * (correctly) fail to link.
*/
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
#ifdef UACCESS_LINUX
#define UACCESS_PREFIX_linux
#else
#define UACCESS_PREFIX_linux __linux_
#endif
-static inline __always_inline userptr_t
-UACCESS_INLINE(linux, phys_to_user)(unsigned long phys_addr)
-{
- return phys_addr;
-}
-
+/**
+ * Convert user buffer to physical address
+ *
+ * @v userptr User pointer
+ * @v offset Offset from user pointer
+ * @ret phys_addr Physical address
+ */
static inline __always_inline unsigned long
-UACCESS_INLINE(linux, user_to_phys)(userptr_t userptr, off_t offset)
-{
- return userptr + offset;
+UACCESS_INLINE ( linux, user_to_phys ) ( userptr_t userptr, off_t offset ) {
+
+ /* We do not know the real underlying physical address. We
+ * provide this stub implementation only because it is
+ * required by alloc_memblock() (which allocates memory with
+ * specified physical address alignment). We assume that the
+ * low-order bits of virtual addresses match the low-order
+ * bits of physical addresses, and so simply returning the
+ * virtual address will suffice for the purpose of determining
+ * alignment.
+ */
+ return ( userptr + offset );
}
static inline __always_inline userptr_t
-UACCESS_INLINE(linux, virt_to_user)(volatile const void *addr)
-{
- return trivial_virt_to_user(addr);
+UACCESS_INLINE ( linux, virt_to_user ) ( volatile const void *addr ) {
+ return trivial_virt_to_user ( addr );
}
static inline __always_inline void *
-UACCESS_INLINE(linux, user_to_virt)(userptr_t userptr, off_t offset)
-{
- return trivial_user_to_virt(userptr, offset);
+UACCESS_INLINE ( linux, user_to_virt ) ( userptr_t userptr, off_t offset ) {
+ return trivial_user_to_virt ( userptr, offset );
}
static inline __always_inline userptr_t
-UACCESS_INLINE(linux, userptr_add)(userptr_t userptr, off_t offset)
-{
- return trivial_userptr_add(userptr, offset);
+UACCESS_INLINE ( linux, userptr_add ) ( userptr_t userptr, off_t offset ) {
+ return trivial_userptr_add ( userptr, offset );
}
static inline __always_inline off_t
-UACCESS_INLINE(linux, userptr_sub)(userptr_t userptr, userptr_t subtrahend)
-{
+UACCESS_INLINE ( linux, userptr_sub ) ( userptr_t userptr,
+ userptr_t subtrahend ) {
return trivial_userptr_sub ( userptr, subtrahend );
}
static inline __always_inline void
-UACCESS_INLINE(linux, memcpy_user)(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
-{
- trivial_memcpy_user(dest, dest_off, src, src_off, len);
+UACCESS_INLINE ( linux, memcpy_user ) ( userptr_t dest, off_t dest_off,
+ userptr_t src, off_t src_off,
+ size_t len ) {
+ trivial_memcpy_user ( dest, dest_off, src, src_off, len );
}
static inline __always_inline void
-UACCESS_INLINE(linux, memmove_user)(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
-{
- trivial_memmove_user(dest, dest_off, src, src_off, len);
+UACCESS_INLINE ( linux, memmove_user ) ( userptr_t dest, off_t dest_off,
+ userptr_t src, off_t src_off,
+ size_t len ) {
+ trivial_memmove_user ( dest, dest_off, src, src_off, len );
}
static inline __always_inline int
-UACCESS_INLINE(linux, memcmp_user)(userptr_t first, off_t first_off, userptr_t second, off_t second_off, size_t len)
-{
- return trivial_memcmp_user(first, first_off, second, second_off, len);
+UACCESS_INLINE ( linux, memcmp_user ) ( userptr_t first, off_t first_off,
+ userptr_t second, off_t second_off,
+ size_t len ) {
+ return trivial_memcmp_user ( first, first_off, second, second_off, len);
}
static inline __always_inline void
-UACCESS_INLINE(linux, memset_user)(userptr_t buffer, off_t offset, int c, size_t len)
-{
- trivial_memset_user(buffer, offset, c, len);
+UACCESS_INLINE ( linux, memset_user ) ( userptr_t buffer, off_t offset,
+ int c, size_t len ) {
+ trivial_memset_user ( buffer, offset, c, len );
}
static inline __always_inline size_t
-UACCESS_INLINE(linux, strlen_user)(userptr_t buffer, off_t offset)
-{
- return trivial_strlen_user(buffer, offset);
+UACCESS_INLINE ( linux, strlen_user ) ( userptr_t buffer, off_t offset ) {
+ return trivial_strlen_user ( buffer, offset );
}
static inline __always_inline off_t
-UACCESS_INLINE(linux, memchr_user)(userptr_t buffer, off_t offset, int c, size_t len)
-{
- return trivial_memchr_user(buffer, offset, c, len);
+UACCESS_INLINE ( linux, memchr_user ) ( userptr_t buffer, off_t offset,
+ int c, size_t len ) {
+ return trivial_memchr_user ( buffer, offset, c, len );
}
#endif /* _IPXE_LINUX_UACCESS_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/linux/linux_umalloc.h b/qemu/roms/ipxe/src/include/ipxe/linux/linux_umalloc.h
index 4de55ecf3..1811d0bc6 100644
--- a/qemu/roms/ipxe/src/include/ipxe/linux/linux_umalloc.h
+++ b/qemu/roms/ipxe/src/include/ipxe/linux/linux_umalloc.h
@@ -1,14 +1,14 @@
#ifndef _IPXE_LINUX_UMALLOC_H
#define _IPXE_LINUX_UMALLOC_H
-FILE_LICENCE(GPL2_OR_LATER);
-
/** @file
*
- * iPXE user memory allocation API for linux
+ * iPXE user memory allocation API for Linux
*
*/
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
#ifdef UMALLOC_LINUX
#define UMALLOC_PREFIX_linux
#else
diff --git a/qemu/roms/ipxe/src/include/ipxe/linux_compat.h b/qemu/roms/ipxe/src/include/ipxe/linux_compat.h
index 6f6ed97d7..4704c4817 100644
--- a/qemu/roms/ipxe/src/include/ipxe/linux_compat.h
+++ b/qemu/roms/ipxe/src/include/ipxe/linux_compat.h
@@ -10,7 +10,7 @@
* intended to be a substitute for proper porting.
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <errno.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/list.h b/qemu/roms/ipxe/src/include/ipxe/list.h
index 581ec9806..6a9b76f91 100644
--- a/qemu/roms/ipxe/src/include/ipxe/list.h
+++ b/qemu/roms/ipxe/src/include/ipxe/list.h
@@ -9,7 +9,7 @@
* list.h.
*/
-FILE_LICENCE ( GPL2_ONLY );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <assert.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/login_ui.h b/qemu/roms/ipxe/src/include/ipxe/login_ui.h
index 01e5479f7..313e07349 100644
--- a/qemu/roms/ipxe/src/include/ipxe/login_ui.h
+++ b/qemu/roms/ipxe/src/include/ipxe/login_ui.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern int login_ui ( void );
diff --git a/qemu/roms/ipxe/src/include/ipxe/malloc.h b/qemu/roms/ipxe/src/include/ipxe/malloc.h
index bbd6cb898..dd158b8e6 100644
--- a/qemu/roms/ipxe/src/include/ipxe/malloc.h
+++ b/qemu/roms/ipxe/src/include/ipxe/malloc.h
@@ -9,7 +9,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/*
* Prototypes for the standard functions (malloc() et al) are in
@@ -77,8 +77,8 @@ static inline void * __malloc malloc_dma ( size_t size, size_t phys_align ) {
* If @c ptr is NULL, no action is taken.
*/
static inline void free_dma ( void *ptr, size_t size ) {
- free_memblock ( ptr, size );
VALGRIND_FREELIKE_BLOCK ( ptr, 0 );
+ free_memblock ( ptr, size );
}
/** A cache discarder */
diff --git a/qemu/roms/ipxe/src/include/ipxe/mca.h b/qemu/roms/ipxe/src/include/ipxe/mca.h
index d86dab195..11470ec93 100644
--- a/qemu/roms/ipxe/src/include/ipxe/mca.h
+++ b/qemu/roms/ipxe/src/include/ipxe/mca.h
@@ -5,7 +5,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifndef MCA_H
#define MCA_H
diff --git a/qemu/roms/ipxe/src/include/ipxe/md5.h b/qemu/roms/ipxe/src/include/ipxe/md5.h
index 860bc4769..05c3974c8 100644
--- a/qemu/roms/ipxe/src/include/ipxe/md5.h
+++ b/qemu/roms/ipxe/src/include/ipxe/md5.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/crypto.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/memblock.h b/qemu/roms/ipxe/src/include/ipxe/memblock.h
index 13af3e433..2bb38c460 100644
--- a/qemu/roms/ipxe/src/include/ipxe/memblock.h
+++ b/qemu/roms/ipxe/src/include/ipxe/memblock.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/uaccess.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/menu.h b/qemu/roms/ipxe/src/include/ipxe/menu.h
index f2b3caccc..3cc99be48 100644
--- a/qemu/roms/ipxe/src/include/ipxe/menu.h
+++ b/qemu/roms/ipxe/src/include/ipxe/menu.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/list.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/mii.h b/qemu/roms/ipxe/src/include/ipxe/mii.h
index f53ad4a62..c2245b49e 100644
--- a/qemu/roms/ipxe/src/include/ipxe/mii.h
+++ b/qemu/roms/ipxe/src/include/ipxe/mii.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <mii.h>
#include <ipxe/netdevice.h>
@@ -114,5 +114,7 @@ mii_dump ( struct mii_interface *mii ) {
extern int mii_restart ( struct mii_interface *mii );
extern int mii_reset ( struct mii_interface *mii );
+extern int mii_check_link ( struct mii_interface *mii,
+ struct net_device *netdev );
#endif /* _IPXE_MII_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/monojob.h b/qemu/roms/ipxe/src/include/ipxe/monojob.h
index aedc37eca..1661d91c2 100644
--- a/qemu/roms/ipxe/src/include/ipxe/monojob.h
+++ b/qemu/roms/ipxe/src/include/ipxe/monojob.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct interface;
diff --git a/qemu/roms/ipxe/src/include/ipxe/mount.h b/qemu/roms/ipxe/src/include/ipxe/mount.h
index ca958117a..2d42ba080 100644
--- a/qemu/roms/ipxe/src/include/ipxe/mount.h
+++ b/qemu/roms/ipxe/src/include/ipxe/mount.h
@@ -9,7 +9,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** NFS MOUNT protocol number */
#define ONCRPC_MOUNT 100005
diff --git a/qemu/roms/ipxe/src/include/ipxe/nap.h b/qemu/roms/ipxe/src/include/ipxe/nap.h
index afc887910..f4de778c4 100644
--- a/qemu/roms/ipxe/src/include/ipxe/nap.h
+++ b/qemu/roms/ipxe/src/include/ipxe/nap.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/api.h>
#include <config/nap.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ndp.h b/qemu/roms/ipxe/src/include/ipxe/ndp.h
index 7388f938e..1815236f5 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ndp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ndp.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/in.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/neighbour.h b/qemu/roms/ipxe/src/include/ipxe/neighbour.h
index f2a3946f1..1c1d1b6ca 100644
--- a/qemu/roms/ipxe/src/include/ipxe/neighbour.h
+++ b/qemu/roms/ipxe/src/include/ipxe/neighbour.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/refcnt.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/net80211_err.h b/qemu/roms/ipxe/src/include/ipxe/net80211_err.h
index 7df3d0d85..32ccc257f 100644
--- a/qemu/roms/ipxe/src/include/ipxe/net80211_err.h
+++ b/qemu/roms/ipxe/src/include/ipxe/net80211_err.h
@@ -10,7 +10,7 @@
* Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/include/ipxe/netdevice.h b/qemu/roms/ipxe/src/include/ipxe/netdevice.h
index 95ad1cf1b..a1d207ffc 100644
--- a/qemu/roms/ipxe/src/include/ipxe/netdevice.h
+++ b/qemu/roms/ipxe/src/include/ipxe/netdevice.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/list.h>
@@ -15,6 +15,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/refcnt.h>
#include <ipxe/settings.h>
#include <ipxe/interface.h>
+#include <ipxe/retry.h>
struct io_buffer;
struct net_device;
@@ -36,13 +37,12 @@ struct device;
/** Maximum length of a link-layer header
*
- * The longest currently-supported link-layer header is for 802.11: a
- * 24-byte frame header plus an 8-byte 802.3 LLC/SNAP header, plus a
- * possible 4-byte VLAN header. (The IPoIB link-layer pseudo-header
- * doesn't actually include link-layer addresses; see ipoib.c for
- * details.)
+ * The longest currently-supported link-layer header is for RNDIS: an
+ * 8-byte RNDIS header, a 32-byte RNDIS packet message header, a
+ * 14-byte Ethernet header and a possible 4-byte VLAN header. Round
+ * up to 64 bytes.
*/
-#define MAX_LL_HEADER_LEN 36
+#define MAX_LL_HEADER_LEN 64
/** Maximum length of a network-layer address */
#define MAX_NET_ADDR_LEN 16
@@ -393,6 +393,8 @@ struct net_device {
* indicates the error preventing link-up.
*/
int link_rc;
+ /** Link block timer */
+ struct retry_timer link_block;
/** Maximum packet length
*
* This length includes any link-layer headers.
@@ -428,6 +430,14 @@ struct net_device {
/** Network device receive queue processing is frozen */
#define NETDEV_RX_FROZEN 0x0004
+/** Network device interrupts are unsupported
+ *
+ * This flag can be used by a network device to indicate that
+ * interrupts are not supported despite the presence of an irq()
+ * method.
+ */
+#define NETDEV_IRQ_UNSUPPORTED 0x0008
+
/** Link-layer protocol table */
#define LL_PROTOCOLS __table ( struct ll_protocol, "ll_protocols" )
@@ -615,6 +625,17 @@ netdev_link_ok ( struct net_device *netdev ) {
}
/**
+ * Check link block state of network device
+ *
+ * @v netdev Network device
+ * @ret link_blocked Link is blocked
+ */
+static inline __attribute__ (( always_inline )) int
+netdev_link_blocked ( struct net_device *netdev ) {
+ return ( timer_running ( &netdev->link_block ) );
+}
+
+/**
* Check whether or not network device is open
*
* @v netdev Network device
@@ -633,7 +654,8 @@ netdev_is_open ( struct net_device *netdev ) {
*/
static inline __attribute__ (( always_inline )) int
netdev_irq_supported ( struct net_device *netdev ) {
- return ( netdev->op->irq != NULL );
+ return ( ( netdev->op->irq != NULL ) &&
+ ! ( netdev->state & NETDEV_IRQ_UNSUPPORTED ) );
}
/**
@@ -662,6 +684,9 @@ extern void netdev_rx_freeze ( struct net_device *netdev );
extern void netdev_rx_unfreeze ( struct net_device *netdev );
extern void netdev_link_err ( struct net_device *netdev, int rc );
extern void netdev_link_down ( struct net_device *netdev );
+extern void netdev_link_block ( struct net_device *netdev,
+ unsigned long timeout );
+extern void netdev_link_unblock ( struct net_device *netdev );
extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
extern void netdev_tx_defer ( struct net_device *netdev,
struct io_buffer *iobuf );
diff --git a/qemu/roms/ipxe/src/include/ipxe/nfs.h b/qemu/roms/ipxe/src/include/ipxe/nfs.h
index 498ed5a27..69b8b5381 100644
--- a/qemu/roms/ipxe/src/include/ipxe/nfs.h
+++ b/qemu/roms/ipxe/src/include/ipxe/nfs.h
@@ -10,7 +10,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** NFS protocol number */
#define ONCRPC_NFS 100003
diff --git a/qemu/roms/ipxe/src/include/ipxe/nfs_open.h b/qemu/roms/ipxe/src/include/ipxe/nfs_open.h
index caba977f7..8572c41b3 100644
--- a/qemu/roms/ipxe/src/include/ipxe/nfs_open.h
+++ b/qemu/roms/ipxe/src/include/ipxe/nfs_open.h
@@ -7,6 +7,6 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _IPXE_NFS_OPEN_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/nfs_uri.h b/qemu/roms/ipxe/src/include/ipxe/nfs_uri.h
index d88bd6f65..aaa6d3749 100644
--- a/qemu/roms/ipxe/src/include/ipxe/nfs_uri.h
+++ b/qemu/roms/ipxe/src/include/ipxe/nfs_uri.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/uri.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/null_entropy.h b/qemu/roms/ipxe/src/include/ipxe/null_entropy.h
index 646d1a17e..91adefa69 100644
--- a/qemu/roms/ipxe/src/include/ipxe/null_entropy.h
+++ b/qemu/roms/ipxe/src/include/ipxe/null_entropy.h
@@ -9,7 +9,7 @@
* security-sensitive environment.
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/null_nap.h b/qemu/roms/ipxe/src/include/ipxe/null_nap.h
index 0c0704bc7..17145b48b 100644
--- a/qemu/roms/ipxe/src/include/ipxe/null_nap.h
+++ b/qemu/roms/ipxe/src/include/ipxe/null_nap.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef NAP_NULL
#define NAP_PREFIX_null
diff --git a/qemu/roms/ipxe/src/include/ipxe/null_reboot.h b/qemu/roms/ipxe/src/include/ipxe/null_reboot.h
index 3de36c5b3..5de38afc0 100644
--- a/qemu/roms/ipxe/src/include/ipxe/null_reboot.h
+++ b/qemu/roms/ipxe/src/include/ipxe/null_reboot.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef REBOOT_NULL
#define REBOOT_PREFIX_null
diff --git a/qemu/roms/ipxe/src/include/ipxe/null_sanboot.h b/qemu/roms/ipxe/src/include/ipxe/null_sanboot.h
index 2b3a2c74d..58f03339f 100644
--- a/qemu/roms/ipxe/src/include/ipxe/null_sanboot.h
+++ b/qemu/roms/ipxe/src/include/ipxe/null_sanboot.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef SANBOOT_NULL
#define SANBOOT_PREFIX_null
diff --git a/qemu/roms/ipxe/src/include/ipxe/null_time.h b/qemu/roms/ipxe/src/include/ipxe/null_time.h
index 2b72cdf50..d2b15194b 100644
--- a/qemu/roms/ipxe/src/include/ipxe/null_time.h
+++ b/qemu/roms/ipxe/src/include/ipxe/null_time.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef TIME_NULL
#define TIME_PREFIX_null
diff --git a/qemu/roms/ipxe/src/include/ipxe/nvo.h b/qemu/roms/ipxe/src/include/ipxe/nvo.h
index 1a629da78..7a3c7a3db 100644
--- a/qemu/roms/ipxe/src/include/ipxe/nvo.h
+++ b/qemu/roms/ipxe/src/include/ipxe/nvo.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/dhcpopts.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/nvs.h b/qemu/roms/ipxe/src/include/ipxe/nvs.h
index 4733123cf..5789f4c0d 100644
--- a/qemu/roms/ipxe/src/include/ipxe/nvs.h
+++ b/qemu/roms/ipxe/src/include/ipxe/nvs.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/nvsvpd.h b/qemu/roms/ipxe/src/include/ipxe/nvsvpd.h
index 3450e5c71..4c50daf85 100644
--- a/qemu/roms/ipxe/src/include/ipxe/nvsvpd.h
+++ b/qemu/roms/ipxe/src/include/ipxe/nvsvpd.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/nvs.h>
#include <ipxe/pcivpd.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/ocsp.h b/qemu/roms/ipxe/src/include/ipxe/ocsp.h
index 387e28f81..71fa41dc9 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ocsp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ocsp.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdarg.h>
#include <time.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/oncrpc.h b/qemu/roms/ipxe/src/include/ipxe/oncrpc.h
index 76c1260f2..071468711 100644
--- a/qemu/roms/ipxe/src/include/ipxe/oncrpc.h
+++ b/qemu/roms/ipxe/src/include/ipxe/oncrpc.h
@@ -11,7 +11,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** ONC RCP Version */
#define ONCRPC_VERS 2
diff --git a/qemu/roms/ipxe/src/include/ipxe/oncrpc_iob.h b/qemu/roms/ipxe/src/include/ipxe/oncrpc_iob.h
index 4858d96b5..b55043770 100644
--- a/qemu/roms/ipxe/src/include/ipxe/oncrpc_iob.h
+++ b/qemu/roms/ipxe/src/include/ipxe/oncrpc_iob.h
@@ -13,7 +13,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* Add a string to the end of an I/O buffer
diff --git a/qemu/roms/ipxe/src/include/ipxe/open.h b/qemu/roms/ipxe/src/include/ipxe/open.h
index a522f0cd1..43d4cdc66 100644
--- a/qemu/roms/ipxe/src/include/ipxe/open.h
+++ b/qemu/roms/ipxe/src/include/ipxe/open.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdarg.h>
#include <ipxe/tables.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/params.h b/qemu/roms/ipxe/src/include/ipxe/params.h
index c2d82d9cf..dd3292efc 100644
--- a/qemu/roms/ipxe/src/include/ipxe/params.h
+++ b/qemu/roms/ipxe/src/include/ipxe/params.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/list.h>
#include <ipxe/refcnt.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/parseopt.h b/qemu/roms/ipxe/src/include/ipxe/parseopt.h
index 840de7497..829b3431c 100644
--- a/qemu/roms/ipxe/src/include/ipxe/parseopt.h
+++ b/qemu/roms/ipxe/src/include/ipxe/parseopt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stddef.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/pccrc.h b/qemu/roms/ipxe/src/include/ipxe/pccrc.h
new file mode 100644
index 000000000..7f0963428
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/pccrc.h
@@ -0,0 +1,447 @@
+#ifndef _IPXE_PCCRC_H
+#define _IPXE_PCCRC_H
+
+/** @file
+ *
+ * Peer Content Caching and Retrieval: Content Identification [MS-PCCRC]
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <byteswap.h>
+#include <ipxe/uaccess.h>
+#include <ipxe/crypto.h>
+
+/******************************************************************************
+ *
+ * Content Information versioning
+ *
+ ******************************************************************************
+ *
+ * Note that version 1 data structures are little-endian, but version
+ * 2 data structures are big-endian.
+ */
+
+/** Content Information version number */
+union peerdist_info_version {
+ /** Raw version number
+ *
+ * Always little-endian, regardless of whether the
+ * encompassing structure is version 1 (little-endian) or
+ * version 2 (big-endian).
+ */
+ uint16_t raw;
+ /** Major:minor version number */
+ struct {
+ /** Minor version number */
+ uint8_t minor;
+ /** Major version number */
+ uint8_t major;
+ } __attribute__ (( packed ));
+} __attribute__ (( packed ));
+
+/** Content Information version 1 */
+#define PEERDIST_INFO_V1 0x0100
+
+/** Content Information version 2 */
+#define PEERDIST_INFO_V2 0x0200
+
+/******************************************************************************
+ *
+ * Content Information version 1
+ *
+ ******************************************************************************
+ */
+
+/** Content Information version 1 data structure header
+ *
+ * All fields are little-endian.
+ */
+struct peerdist_info_v1 {
+ /** Version number */
+ union peerdist_info_version version;
+ /** Hash algorithm
+ *
+ * This is a @c PEERDIST_INFO_V1_HASH_XXX constant.
+ */
+ uint32_t hash;
+ /** Length to skip in first segment
+ *
+ * Length at the start of the first segment which is not
+ * included within the content range.
+ */
+ uint32_t first;
+ /** Length to read in last segment, or zero
+ *
+ * Length within the last segment which is included within the
+ * content range. A zero value indicates that the whole of
+ * the last segment is included within the content range.
+ */
+ uint32_t last;
+ /** Number of segments within the content information */
+ uint32_t segments;
+ /* Followed by a variable-length array of segment descriptions
+ * and a list of variable-length block descriptions:
+ *
+ * peerdist_info_v1_segment_t(digestsize) segment[segments];
+ * peerdist_info_v1_block_t(digestsize, block0.blocks) block0;
+ * peerdist_info_v1_block_t(digestsize, block1.blocks) block1;
+ * ...
+ * peerdist_info_v1_block_t(digestsize, blockN.blocks) blockN;
+ */
+} __attribute__ (( packed ));
+
+/** SHA-256 hash algorithm */
+#define PEERDIST_INFO_V1_HASH_SHA256 0x0000800cUL
+
+/** SHA-384 hash algorithm */
+#define PEERDIST_INFO_V1_HASH_SHA384 0x0000800dUL
+
+/** SHA-512 hash algorithm */
+#define PEERDIST_INFO_V1_HASH_SHA512 0x0000800eUL
+
+/** Content Information version 1 segment description header
+ *
+ * All fields are little-endian.
+ */
+struct peerdist_info_v1_segment {
+ /** Offset of this segment within the content */
+ uint64_t offset;
+ /** Length of this segment
+ *
+ * Should always be 32MB, except for the last segment within
+ * the content.
+ */
+ uint32_t len;
+ /** Block size for this segment
+ *
+ * Should always be 64kB. Note that the last block within the
+ * last segment may actually be less than 64kB.
+ */
+ uint32_t blksize;
+ /* Followed by two variable-length hashes:
+ *
+ * uint8_t hash[digestsize];
+ * uint8_t secret[digestsize];
+ *
+ * where digestsize is the digest size for the selected hash
+ * algorithm.
+ *
+ * Note that the hash is taken over (the hashes of all blocks
+ * within) the entire segment, even if the blocks do not
+ * intersect the content range (and so do not appear within
+ * the block list). It therefore functions only as a segment
+ * identifier; it cannot be used to verify the content of the
+ * segment (since we may not download all blocks within the
+ * segment).
+ */
+} __attribute__ (( packed ));
+
+/** Content Information version 1 segment description
+ *
+ * @v digestsize Digest size
+ */
+#define peerdist_info_v1_segment_t( digestsize ) \
+ struct { \
+ struct peerdist_info_v1_segment segment; \
+ uint8_t hash[digestsize]; \
+ uint8_t secret[digestsize]; \
+ } __attribute__ (( packed ))
+
+/** Content Information version 1 block description header
+ *
+ * All fields are little-endian.
+ */
+struct peerdist_info_v1_block {
+ /** Number of blocks within the block description
+ *
+ * This is the number of blocks within the segment which
+ * overlap the content range. It may therefore be less than
+ * the number of blocks within the segment.
+ */
+ uint32_t blocks;
+ /* Followed by an array of variable-length hashes:
+ *
+ * uint8_t hash[blocks][digestsize];
+ *
+ * where digestsize is the digest size for the selected hash
+ * algorithm.
+ */
+ } __attribute__ (( packed ));
+
+/** Content Information version 1 block description
+ *
+ * @v digestsize Digest size
+ * @v blocks Number of blocks
+ */
+#define peerdist_info_v1_block_t( digestsize, blocks ) \
+ struct { \
+ struct peerdist_info_v1_block block; \
+ uint8_t hash[blocks][digestsize]; \
+ } __attribute__ (( packed ))
+
+/******************************************************************************
+ *
+ * Content Information version 2
+ *
+ ******************************************************************************
+ */
+
+/** Content Information version 2 data structure header
+ *
+ * All fields are big-endian.
+ */
+struct peerdist_info_v2 {
+ /** Version number */
+ union peerdist_info_version version;
+ /** Hash algorithm
+ *
+ * This is a @c PEERDIST_INFO_V2_HASH_XXX constant.
+ */
+ uint8_t hash;
+ /** Offset of the first segment within the content */
+ uint64_t offset;
+ /** Index of the first segment within the content */
+ uint64_t index;
+ /** Length to skip in first segment
+ *
+ * Length at the start of the first segment which is not
+ * included within the content range.
+ */
+ uint32_t first;
+ /** Length of content range, or zero
+ *
+ * Length of the content range. A zero indicates that
+ * everything up to the end of the last segment is included in
+ * the content range.
+ */
+ uint64_t len;
+ /* Followed by a list of chunk descriptions */
+} __attribute__ (( packed ));
+
+/** SHA-512 hash algorithm with output truncated to first 256 bits */
+#define PEERDIST_INFO_V2_HASH_SHA512_TRUNC 0x04
+
+/** Content Information version 2 chunk description header
+ *
+ * All fields are big-endian.
+ */
+struct peerdist_info_v2_chunk {
+ /** Chunk type */
+ uint8_t type;
+ /** Chunk data length */
+ uint32_t len;
+ /* Followed by an array of segment descriptions:
+ *
+ * peerdist_info_v2_segment_t(digestsize) segment[segments]
+ *
+ * where digestsize is the digest size for the selected hash
+ * algorithm, and segments is equal to @c len divided by the
+ * size of each segment array entry.
+ */
+} __attribute__ (( packed ));
+
+/** Content Information version 2 chunk description
+ *
+ * @v digestsize Digest size
+ */
+#define peerdist_info_v2_chunk_t( digestsize ) \
+ struct { \
+ struct peerdist_info_v2_chunk chunk; \
+ peerdist_info_v2_segment_t ( digestsize ) segment[0]; \
+ } __attribute__ (( packed ))
+
+/** Chunk type */
+#define PEERDIST_INFO_V2_CHUNK_TYPE 0x00
+
+/** Content Information version 2 segment description header
+ *
+ * All fields are big-endian.
+ */
+struct peerdist_info_v2_segment {
+ /** Segment length */
+ uint32_t len;
+ /* Followed by two variable-length hashes:
+ *
+ * uint8_t hash[digestsize];
+ * uint8_t secret[digestsize];
+ *
+ * where digestsize is the digest size for the selected hash
+ * algorithm.
+ */
+} __attribute__ (( packed ));
+
+/** Content Information version 2 segment description
+ *
+ * @v digestsize Digest size
+ */
+#define peerdist_info_v2_segment_t( digestsize ) \
+ struct { \
+ struct peerdist_info_v2_segment segment; \
+ uint8_t hash[digestsize]; \
+ uint8_t secret[digestsize]; \
+ } __attribute__ (( packed ))
+
+/******************************************************************************
+ *
+ * Content Information
+ *
+ ******************************************************************************
+ */
+
+/** Maximum digest size for any supported algorithm
+ *
+ * The largest digest size that we support is for SHA-512 at 64 bytes
+ */
+#define PEERDIST_DIGEST_MAX_SIZE 64
+
+/** Raw content information */
+struct peerdist_raw {
+ /** Data buffer */
+ userptr_t data;
+ /** Length of data buffer */
+ size_t len;
+};
+
+/** A content range */
+struct peerdist_range {
+ /** Start offset */
+ size_t start;
+ /** End offset */
+ size_t end;
+};
+
+/** Content information */
+struct peerdist_info {
+ /** Raw content information */
+ struct peerdist_raw raw;
+
+ /** Content information operations */
+ struct peerdist_info_operations *op;
+ /** Digest algorithm */
+ struct digest_algorithm *digest;
+ /** Digest size
+ *
+ * Note that this may be shorter than the digest size of the
+ * digest algorithm. The truncation does not always take
+ * place as soon as a digest is calculated. For example,
+ * version 2 content information uses SHA-512 with a truncated
+ * digest size of 32 (256 bits), but the segment identifier
+ * ("HoHoDk") is calculated by using HMAC with the full
+ * SHA-512 digest and then truncating the HMAC output, rather
+ * than by simply using HMAC with the truncated SHA-512
+ * digest. This is, of course, totally undocumented.
+ */
+ size_t digestsize;
+ /** Content range */
+ struct peerdist_range range;
+ /** Trimmed content range */
+ struct peerdist_range trim;
+ /** Number of segments within the content information */
+ unsigned int segments;
+};
+
+/** A content information segment */
+struct peerdist_info_segment {
+ /** Content information */
+ const struct peerdist_info *info;
+ /** Segment index */
+ unsigned int index;
+
+ /** Content range
+ *
+ * Note that this range may exceed the overall content range.
+ */
+ struct peerdist_range range;
+ /** Number of blocks within this segment */
+ unsigned int blocks;
+ /** Block size */
+ size_t blksize;
+ /** Segment hash of data
+ *
+ * This is MS-PCCRC's "HoD".
+ */
+ uint8_t hash[PEERDIST_DIGEST_MAX_SIZE];
+ /** Segment secret
+ *
+ * This is MS-PCCRC's "Ke = Kp".
+ */
+ uint8_t secret[PEERDIST_DIGEST_MAX_SIZE];
+ /** Segment identifier
+ *
+ * This is MS-PCCRC's "HoHoDk".
+ */
+ uint8_t id[PEERDIST_DIGEST_MAX_SIZE];
+};
+
+/** Magic string constant used to calculate segment identifier
+ *
+ * Note that the MS-PCCRC specification states that this constant is
+ *
+ * "the null-terminated ASCII string constant "MS_P2P_CACHING";
+ * string literals are all ASCII strings with NULL terminators
+ * unless otherwise noted."
+ *
+ * The specification lies. This constant is a UTF-16LE string, not an
+ * ASCII string. The terminating wNUL *is* included within the
+ * constant.
+ */
+#define PEERDIST_SEGMENT_ID_MAGIC L"MS_P2P_CACHING"
+
+/** A content information block */
+struct peerdist_info_block {
+ /** Content information segment */
+ const struct peerdist_info_segment *segment;
+ /** Block index */
+ unsigned int index;
+
+ /** Content range
+ *
+ * Note that this range may exceed the overall content range.
+ */
+ struct peerdist_range range;
+ /** Trimmed content range */
+ struct peerdist_range trim;
+ /** Block hash */
+ uint8_t hash[PEERDIST_DIGEST_MAX_SIZE];
+};
+
+/** Content information operations */
+struct peerdist_info_operations {
+ /**
+ * Populate content information
+ *
+ * @v info Content information to fill in
+ * @ret rc Return status code
+ */
+ int ( * info ) ( struct peerdist_info *info );
+ /**
+ * Populate content information segment
+ *
+ * @v segment Content information segment to fill in
+ * @ret rc Return status code
+ */
+ int ( * segment ) ( struct peerdist_info_segment *segment );
+ /**
+ * Populate content information block
+ *
+ * @v block Content information block to fill in
+ * @ret rc Return status code
+ */
+ int ( * block ) ( struct peerdist_info_block *block );
+};
+
+extern struct digest_algorithm sha512_trunc_algorithm;
+
+extern int peerdist_info ( userptr_t data, size_t len,
+ struct peerdist_info *info );
+extern int peerdist_info_segment ( const struct peerdist_info *info,
+ struct peerdist_info_segment *segment,
+ unsigned int index );
+extern int peerdist_info_block ( const struct peerdist_info_segment *segment,
+ struct peerdist_info_block *block,
+ unsigned int index );
+
+#endif /* _IPXE_PCCRC_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/pccrd.h b/qemu/roms/ipxe/src/include/ipxe/pccrd.h
new file mode 100644
index 000000000..3daa92f29
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/pccrd.h
@@ -0,0 +1,47 @@
+#ifndef _IPXE_PCCRD_H
+#define _IPXE_PCCRD_H
+
+/** @file
+ *
+ * Peer Content Caching and Retrieval: Discovery Protocol [MS-PCCRD]
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+/** PeerDist discovery port */
+#define PEERDIST_DISCOVERY_PORT 3702
+
+/** PeerDist discovery IPv4 address (239.255.255.250) */
+#define PEERDIST_DISCOVERY_IPV4 \
+ ( ( 239 << 24 ) | ( 255 << 16 ) | ( 255 << 8 ) | ( 250 << 0 ) )
+
+/** PeerDist discovery IPv6 address (ff02::c) */
+#define PEERDIST_DISCOVERY_IPV6 \
+ { 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xc }
+
+/** A PeerDist discovery reply block count */
+struct peerdist_discovery_block_count {
+ /** Count (as an eight-digit hex value) */
+ char hex[8];
+} __attribute__ (( packed ));
+
+/** A PeerDist discovery reply */
+struct peerdist_discovery_reply {
+ /** List of segment ID strings
+ *
+ * The list is terminated with a zero-length string.
+ */
+ char *ids;
+ /** List of peer locations
+ *
+ * The list is terminated with a zero-length string.
+ */
+ char *locations;
+};
+
+extern char * peerdist_discovery_request ( const char *uuid, const char *id );
+extern int peerdist_discovery_reply ( char *data, size_t len,
+ struct peerdist_discovery_reply *reply );
+
+#endif /* _IPXE_PCCRD_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/pccrr.h b/qemu/roms/ipxe/src/include/ipxe/pccrr.h
new file mode 100644
index 000000000..1ea86c40d
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/pccrr.h
@@ -0,0 +1,376 @@
+#ifndef _IPXE_PCCRR_H
+#define _IPXE_PCCRR_H
+
+/** @file
+ *
+ * Peer Content Caching and Retrieval: Retrieval Protocol [MS-PCCRR]
+ *
+ * All fields are in network byte order.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/uaccess.h>
+
+/** Magic retrieval URI path */
+#define PEERDIST_MAGIC_PATH "/116B50EB-ECE2-41ac-8429-9F9E963361B7/"
+
+/** Retrieval protocol version */
+union peerdist_msg_version {
+ /** Raw version number */
+ uint32_t raw;
+ /** Major:minor version number */
+ struct {
+ /** Minor version number */
+ uint16_t minor;
+ /** Major version number */
+ uint16_t major;
+ } __attribute__ (( packed ));
+} __attribute__ (( packed ));
+
+/** Retrieval protocol version 1.0 */
+#define PEERDIST_MSG_VERSION_1_0 0x00000001UL
+
+/** Retrieval protocol version 2.0 */
+#define PEERDIST_MSG_VERSION_2_0 0x00000002UL
+
+/** Retrieval protocol supported versions */
+struct peerdist_msg_versions {
+ /** Minimum supported protocol version */
+ union peerdist_msg_version min;
+ /** Maximum supported protocol version */
+ union peerdist_msg_version max;
+} __attribute__ (( packed ));
+
+/** Retrieval protocol block range */
+struct peerdist_msg_range {
+ /** First block in range */
+ uint32_t first;
+ /** Number of blocks in range */
+ uint32_t count;
+} __attribute__ (( packed ));
+
+/** Retrieval protocol segment ID header */
+struct peerdist_msg_segment {
+ /** Digest size (i.e. length of segment ID) */
+ uint32_t digestsize;
+ /* Followed by a single variable-length ID and padding:
+ *
+ * uint8_t id[digestsize];
+ * uint8_t pad[ (-digestsize) & 0x3 ];
+ */
+} __attribute__ (( packed ));
+
+/** Retrieval protocol segment ID
+ *
+ * @v digestsize Digest size
+ */
+#define peerdist_msg_segment_t( digestsize ) \
+ struct { \
+ struct peerdist_msg_segment segment; \
+ uint8_t id[digestsize]; \
+ uint8_t pad[ ( -(digestsize) ) & 0x3 ]; \
+ } __attribute__ (( packed ))
+
+/** Retrieval protocol block range list header */
+struct peerdist_msg_ranges {
+ /** Number of ranges */
+ uint32_t count;
+ /* Followed by an array of block ranges:
+ *
+ * struct peerdist_msg_range range[count];
+ */
+} __attribute__ (( packed ));
+
+/** Retrieval protocol block range list
+ *
+ * @v count Number of ranges
+ */
+#define peerdist_msg_ranges_t( count ) \
+ struct { \
+ struct peerdist_msg_ranges ranges; \
+ struct peerdist_msg_range range[count]; \
+ } __attribute__ (( packed ))
+
+/** Retrieval protocol data block header */
+struct peerdist_msg_block {
+ /** Length of data block */
+ uint32_t len;
+ /* Followed by the (encrypted) data block:
+ *
+ * uint8_t data[len];
+ */
+} __attribute__ (( packed ));
+
+/** Retrieval protocol data block */
+#define peerdist_msg_block_t( len ) \
+ struct { \
+ struct peerdist_msg_block block; \
+ uint8_t data[len]; \
+ } __attribute__ (( packed ))
+
+/** Retrieval protocol initialisation vector header */
+struct peerdist_msg_iv {
+ /** Cipher block size */
+ uint32_t blksize;
+ /* Followed by the initialisation vector:
+ *
+ * uint8_t data[blksize];
+ */
+} __attribute__ (( packed ));
+
+/** Retrieval protocol initialisation vector */
+#define peerdist_msg_iv_t( blksize ) \
+ struct { \
+ struct peerdist_msg_iv iv; \
+ uint8_t data[blksize]; \
+ } __attribute__ (( packed ))
+
+/** Retrieval protocol useless VRF data header */
+struct peerdist_msg_useless_vrf {
+ /** Length of useless VRF data */
+ uint32_t len;
+ /* Followed by a variable-length useless VRF data block and
+ * padding:
+ *
+ * uint8_t data[len];
+ * uint8_t pad[ (-len) & 0x3 ];
+ */
+} __attribute__ (( packed ));
+
+/** Retrieval protocol useless VRF data */
+#define peerdist_msg_useless_vrf_t( vrf_len ) \
+ struct { \
+ struct peerdist_msg_useless_vrf vrf; \
+ uint8_t data[vrf_len]; \
+ uint8_t pad[ ( -(vrf_len) ) & 0x3 ]; \
+ } __attribute__ (( packed ))
+
+/** Retrieval protocol message header */
+struct peerdist_msg_header {
+ /** Protocol version
+ *
+ * This is the protocol version in which the message type was
+ * first defined.
+ */
+ union peerdist_msg_version version;
+ /** Message type */
+ uint32_t type;
+ /** Message size (including this header) */
+ uint32_t len;
+ /** Cryptographic algorithm ID */
+ uint32_t algorithm;
+} __attribute__ (( packed ));
+
+/** Retrieval protocol cryptographic algorithm IDs */
+enum peerdist_msg_algorithm {
+ /** No encryption */
+ PEERDIST_MSG_PLAINTEXT = 0x00000000UL,
+ /** AES-128 in CBC mode */
+ PEERDIST_MSG_AES_128_CBC = 0x00000001UL,
+ /** AES-192 in CBC mode */
+ PEERDIST_MSG_AES_192_CBC = 0x00000002UL,
+ /** AES-256 in CBC mode */
+ PEERDIST_MSG_AES_256_CBC = 0x00000003UL,
+};
+
+/** Retrieval protocol transport response header */
+struct peerdist_msg_transport_header {
+ /** Length (excluding this header)
+ *
+ * This seems to be identical in both purpose and value to the
+ * length found within the message header, and therefore
+ * serves no useful purpose.
+ */
+ uint32_t len;
+} __attribute__ (( packed ));
+
+/** Retrieval protocol negotiation request */
+struct peerdist_msg_nego_req {
+ /** Message header */
+ struct peerdist_msg_header hdr;
+ /** Supported versions */
+ struct peerdist_msg_versions versions;
+} __attribute__ (( packed ));
+
+/** Retrieval protocol negotiation request version */
+#define PEERDIST_MSG_NEGO_REQ_VERSION PEERDIST_MSG_VERSION_1_0
+
+/** Retrieval protocol negotiation request type */
+#define PEERDIST_MSG_NEGO_REQ_TYPE 0x00000000UL
+
+/** Retrieval protocol negotiation response */
+struct peerdist_msg_nego_resp {
+ /** Message header */
+ struct peerdist_msg_header hdr;
+ /** Supported versions */
+ struct peerdist_msg_versions versions;
+} __attribute__ (( packed ));
+
+/** Retrieval protocol negotiation response version */
+#define PEERDIST_MSG_NEGO_RESP_VERSION PEERDIST_MSG_VERSION_1_0
+
+/** Retrieval protocol negotiation response type */
+#define PEERDIST_MSG_NEGO_RESP_TYPE 0x00000001UL
+
+/** Retrieval protocol block list request header */
+struct peerdist_msg_getblklist {
+ /** Message header */
+ struct peerdist_msg_header hdr;
+ /* Followed by a segment ID and a block range list:
+ *
+ * peerdist_msg_segment_t(digestsize) segment;
+ * peerdist_msg_ranges_t(count) ranges;
+ */
+} __attribute__ (( packed ));
+
+/** Retrieval protocol block list request
+ *
+ * @v digestsize Digest size
+ * @v count Block range count
+ */
+#define peerdist_msg_getblklist_t( digestsize, count ) \
+ struct { \
+ struct peerdist_msg_getblklist getblklist; \
+ peerdist_msg_segment_t ( digestsize ) segment; \
+ peerdist_msg_ranges_t ( count ) ranges; \
+ } __attribute__ (( packed ))
+
+/** Retrieval protocol block list request version */
+#define PEERDIST_MSG_GETBLKLIST_VERSION PEERDIST_MSG_VERSION_1_0
+
+/** Retrieval protocol block list request type */
+#define PEERDIST_MSG_GETBLKLIST_TYPE 0x00000002UL
+
+/** Retrieval protocol block fetch request header */
+struct peerdist_msg_getblks {
+ /** Message header */
+ struct peerdist_msg_header hdr;
+ /* Followed by a segment ID, a block range list, and a useless
+ * VRF block:
+ *
+ * peerdist_msg_segment_t(digestsize) segment;
+ * peerdist_msg_ranges_t(count) ranges;
+ * peerdist_msg_vrf_t(vrf_len) vrf;
+ */
+} __attribute__ (( packed ));
+
+/** Retrieval protocol block fetch request
+ *
+ * @v digestsize Digest size
+ * @v count Block range count
+ * @v vrf_len Length of uselessness
+ */
+#define peerdist_msg_getblks_t( digestsize, count, vrf_len ) \
+ struct { \
+ struct peerdist_msg_getblks getblks; \
+ peerdist_msg_segment_t ( digestsize ) segment; \
+ peerdist_msg_ranges_t ( count ) ranges; \
+ peerdist_msg_useless_vrf_t ( vrf_len ); \
+ } __attribute__ (( packed ))
+
+/** Retrieval protocol block fetch request version */
+#define PEERDIST_MSG_GETBLKS_VERSION PEERDIST_MSG_VERSION_1_0
+
+/** Retrieval protocol block fetch request type */
+#define PEERDIST_MSG_GETBLKS_TYPE 0x00000003UL
+
+/** Retrieval protocol block list response header */
+struct peerdist_msg_blklist {
+ /** Message header */
+ struct peerdist_msg_header hdr;
+ /* Followed by a segment ID, a block range list, and a next
+ * block index:
+ *
+ * peerdist_msg_segment_t(digestsize) segment;
+ * peerdist_msg_ranges_t(count) ranges;
+ * uint32_t next;
+ */
+} __attribute__ (( packed ));
+
+/** Retrieval protocol block list response
+ *
+ * @v digestsize Digest size
+ * @v count Block range count
+ */
+#define peerdist_msg_blklist_t( digestsize, count ) \
+ struct { \
+ struct peerdist_msg_blklist blklist; \
+ peerdist_msg_segment_t ( digestsize ) segment; \
+ peerdist_msg_ranges_t ( count ) ranges; \
+ uint32_t next; \
+ } __attribute__ (( packed ))
+
+/** Retrieval protocol block list response version */
+#define PEERDIST_MSG_BLKLIST_VERSION PEERDIST_MSG_VERSION_1_0
+
+/** Retrieval protocol block list response type */
+#define PEERDIST_MSG_BLKLIST_TYPE 0x00000004UL
+
+/** Retrieval protocol block fetch response header */
+struct peerdist_msg_blk {
+ /** Message header */
+ struct peerdist_msg_header hdr;
+ /* Followed by a segment ID, a block index, a next block
+ * index, a data block, a useless VRF block, and an
+ * initialisation vector:
+ *
+ * peerdist_msg_segment_t(digestsize) segment;
+ * uint32_t index;
+ * uint32_t next;
+ * peerdist_msg_block_t(len) data;
+ * peerdist_msg_useless_vrf_t(vrf_len) vrf;
+ * peerdist_msg_iv_t(blksize) iv;
+ */
+} __attribute__ (( packed ));
+
+/** Retrieval protocol block fetch response
+ *
+ * @v digestsize Digest size
+ * @v len Data block length
+ * @v vrf_len Length of uselessness
+ * @v blksize Cipher block size
+ */
+#define peerdist_msg_blk_t( digestsize, len, vrf_len, blksize ) \
+ struct { \
+ struct peerdist_msg_blk blk; \
+ peerdist_msg_segment_t ( digestsize ) segment; \
+ uint32_t index; \
+ uint32_t next; \
+ peerdist_msg_block_t ( len ) block; \
+ peerdist_msg_useless_vrf_t ( vrf_len ) vrf; \
+ peerdist_msg_iv_t ( blksize ) iv; \
+ } __attribute__ (( packed ))
+
+/** Retrieval protocol block fetch response version */
+#define PEERDIST_MSG_BLK_VERSION PEERDIST_MSG_VERSION_1_0
+
+/** Retrieval protocol block fetch response type */
+#define PEERDIST_MSG_BLK_TYPE 0x00000005UL
+
+/**
+ * Parse retrieval protocol block fetch response
+ *
+ * @v raw Raw data
+ * @v raw_len Length of raw data
+ * @v digestsize Digest size
+ * @v blksize Cipher block size
+ * @v blk Structure to fill in
+ * @ret rc Return status code
+ */
+#define peerdist_msg_blk( raw, raw_len, digestsize, blksize, blk ) ( { \
+ assert ( sizeof ( (blk)->segment.id ) == (digestsize) ); \
+ assert ( sizeof ( (blk)->block.data ) == 0 ); \
+ assert ( sizeof ( (blk)->vrf.data ) == 0 ); \
+ assert ( sizeof ( (blk)->iv.data ) == blksize ); \
+ peerdist_msg_blk_untyped ( (raw), (raw_len), (digestsize), \
+ (blksize), blk ); \
+ } )
+
+extern int peerdist_msg_blk_untyped ( userptr_t raw, size_t raw_len,
+ size_t digestsize, size_t blksize,
+ void *out );
+
+#endif /* _IPXE_PCCRR_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/pci.h b/qemu/roms/ipxe/src/include/ipxe/pci.h
index 692771ebe..a841e00ff 100644
--- a/qemu/roms/ipxe/src/include/ipxe/pci.h
+++ b/qemu/roms/ipxe/src/include/ipxe/pci.h
@@ -1,268 +1,132 @@
#ifndef _IPXE_PCI_H
#define _IPXE_PCI_H
-/*
- * Support for NE2000 PCI clones added David Monro June 1997
- * Generalised for other PCI NICs by Ken Yap July 1997
- * PCI support rewritten by Michael Brown 2006
+/** @file
+ *
+ * PCI bus
*
- * Most of this is taken from /usr/src/linux/include/linux/pci.h.
- */
-
-/*
- * 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, or (at
- * your option) any later version.
*/
-FILE_LICENCE ( GPL2_ONLY );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/device.h>
#include <ipxe/tables.h>
#include <ipxe/pci_io.h>
-#include "pci_ids.h"
-/*
- * PCI constants
- *
- */
-
-#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
-#define PCI_COMMAND_MEM 0x2 /* Enable response in mem space */
-#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
-
-#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
-#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
-
-#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
-#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
-#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
-#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
-#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
-#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
-#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
-#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
-
-
-#define PCI_VENDOR_ID 0x00 /* 16 bits */
-#define PCI_DEVICE_ID 0x02 /* 16 bits */
-#define PCI_COMMAND 0x04 /* 16 bits */
-
-#define PCI_STATUS 0x06 /* 16 bits */
-#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
-#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
-#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
-#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
-#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
-#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
-#define PCI_STATUS_DEVSEL_FAST 0x000
-#define PCI_STATUS_DEVSEL_MEDIUM 0x200
-#define PCI_STATUS_DEVSEL_SLOW 0x400
-#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
-#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
-#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
-#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
-#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
-
-#define PCI_REVISION 0x08 /* 8 bits */
-#define PCI_REVISION_ID 0x08 /* 8 bits */
-#define PCI_CLASS_REVISION 0x08 /* 32 bits */
-#define PCI_CLASS_CODE 0x0b /* 8 bits */
-#define PCI_SUBCLASS_CODE 0x0a /* 8 bits */
-#define PCI_HEADER_TYPE 0x0e /* 8 bits */
-#define PCI_HEADER_TYPE_NORMAL 0
-#define PCI_HEADER_TYPE_BRIDGE 1
-#define PCI_HEADER_TYPE_CARDBUS 2
-
-
-/* Header type 0 (normal devices) */
-#define PCI_CARDBUS_CIS 0x28
+/** PCI vendor ID */
+#define PCI_VENDOR_ID 0x00
+
+/** PCI device ID */
+#define PCI_DEVICE_ID 0x02
+
+/** PCI command */
+#define PCI_COMMAND 0x04
+#define PCI_COMMAND_IO 0x0001 /**< I/O space */
+#define PCI_COMMAND_MEM 0x0002 /**< Memory space */
+#define PCI_COMMAND_MASTER 0x0004 /**< Bus master */
+#define PCI_COMMAND_INVALIDATE 0x0010 /**< Mem. write & invalidate */
+#define PCI_COMMAND_PARITY 0x0040 /**< Parity error response */
+#define PCI_COMMAND_SERR 0x0100 /**< SERR# enable */
+#define PCI_COMMAND_INTX_DISABLE 0x0400 /**< Interrupt disable */
+
+/** PCI status */
+#define PCI_STATUS 0x06
+#define PCI_STATUS_CAP_LIST 0x0010 /**< Capabilities list */
+#define PCI_STATUS_PARITY 0x0100 /**< Master data parity error */
+#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /**< Received target abort */
+#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /**< Received master abort */
+#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /**< Signalled system error */
+#define PCI_STATUS_DETECTED_PARITY 0x8000 /**< Detected parity error */
+
+/** PCI revision */
+#define PCI_REVISION 0x08
+
+/** PCI cache line size */
+#define PCI_CACHE_LINE_SIZE 0x0c
+
+/** PCI latency timer */
+#define PCI_LATENCY_TIMER 0x0d
+
+/** PCI header type */
+#define PCI_HEADER_TYPE 0x0e
+#define PCI_HEADER_TYPE_NORMAL 0x00 /**< Normal header */
+#define PCI_HEADER_TYPE_BRIDGE 0x01 /**< PCI-to-PCI bridge header */
+#define PCI_HEADER_TYPE_CARDBUS 0x02 /**< CardBus header */
+#define PCI_HEADER_TYPE_MASK 0x7f /**< Header type mask */
+#define PCI_HEADER_TYPE_MULTI 0x80 /**< Multi-function device */
+
+/** PCI base address registers */
+#define PCI_BASE_ADDRESS(n) ( 0x10 + ( 4 * (n) ) )
+#define PCI_BASE_ADDRESS_0 PCI_BASE_ADDRESS ( 0 )
+#define PCI_BASE_ADDRESS_1 PCI_BASE_ADDRESS ( 1 )
+#define PCI_BASE_ADDRESS_2 PCI_BASE_ADDRESS ( 2 )
+#define PCI_BASE_ADDRESS_3 PCI_BASE_ADDRESS ( 3 )
+#define PCI_BASE_ADDRESS_4 PCI_BASE_ADDRESS ( 4 )
+#define PCI_BASE_ADDRESS_5 PCI_BASE_ADDRESS ( 5 )
+#define PCI_BASE_ADDRESS_SPACE_IO 0x00000001UL /**< I/O BAR */
+#define PCI_BASE_ADDRESS_IO_MASK 0x00000003UL /**< I/O BAR mask */
+#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x00000004UL /**< 64-bit memory */
+#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x00000006UL /**< Memory type mask */
+#define PCI_BASE_ADDRESS_MEM_MASK 0x0000000fUL /**< Memory BAR mask */
+
+/** PCI subsystem vendor ID */
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
+
+/** PCI subsystem ID */
#define PCI_SUBSYSTEM_ID 0x2e
-#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
-#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits */
-#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits */
-#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
-#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
-#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
-
-#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
-#define PCI_BASE_ADDRESS_SPACE_IO 0x01
-#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
-
-#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
-#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
-#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
-#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
-#define PCI_BASE_ADDRESS_MEM_MASK (~0x0f)
-#define PCI_BASE_ADDRESS_IO_MASK (~0x03)
-#define PCI_ROM_ADDRESS 0x30 /* 32 bits */
-#define PCI_ROM_ADDRESS_ENABLE 0x01 /* Write 1 to enable ROM,
- bits 31..11 are address,
- 10..2 are reserved */
-
-#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
-
-#define PCI_INTERRUPT_LINE 0x3c /* IRQ number (0-15) */
-#define PCI_INTERRUPT_PIN 0x3d /* IRQ pin on PCI bus (A-D) */
-
-/* Header type 1 (PCI-to-PCI bridges) */
-#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
-#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
-#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
-#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
-#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
-#define PCI_IO_LIMIT 0x1d
-#define PCI_IO_RANGE_TYPE_MASK 0x0f /* I/O bridging type */
-#define PCI_IO_RANGE_TYPE_16 0x00
-#define PCI_IO_RANGE_TYPE_32 0x01
-#define PCI_IO_RANGE_MASK ~0x0f
-#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
-#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
-#define PCI_MEMORY_LIMIT 0x22
-#define PCI_MEMORY_RANGE_TYPE_MASK 0x0f
-#define PCI_MEMORY_RANGE_MASK ~0x0f
-#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
-#define PCI_PREF_MEMORY_LIMIT 0x26
-#define PCI_PREF_RANGE_TYPE_MASK 0x0f
-#define PCI_PREF_RANGE_TYPE_32 0x00
-#define PCI_PREF_RANGE_TYPE_64 0x01
-#define PCI_PREF_RANGE_MASK ~0x0f
-#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
-#define PCI_PREF_LIMIT_UPPER32 0x2c
-#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
-#define PCI_IO_LIMIT_UPPER16 0x32
-/* 0x34 same as for htype 0 */
-/* 0x35-0x3b is reserved */
-#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
-/* 0x3c-0x3d are same as for htype 0 */
-#define PCI_BRIDGE_CONTROL 0x3e
-#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
-#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
-#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
-#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
-#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
-#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
-#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
+/** PCI expansion ROM base address */
+#define PCI_ROM_ADDRESS 0x30
+/** PCI capabilities pointer */
+#define PCI_CAPABILITY_LIST 0x34
+
+/** CardBus capabilities pointer */
#define PCI_CB_CAPABILITY_LIST 0x14
-/* Capability lists */
-
-#define PCI_CAP_LIST_ID 0 /* Capability ID */
-#define PCI_CAP_ID_PM 0x01 /* Power Management */
-#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
-#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
-#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
-#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
-#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
-#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific */
-#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
-#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
-#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
-#define PCI_CAP_SIZEOF 4
-
-/* Power Management Registers */
-
-#define PCI_PM_PMC 2 /* PM Capabilities Register */
-#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
-#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
-#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */
-#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
-#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxiliary power support mask */
-#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */
-#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */
-#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
-#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */
-#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */
-#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */
-#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */
-#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */
-#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */
-#define PCI_PM_CTRL 4 /* PM control and status register */
-#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
-#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
-#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
-#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
-#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
-#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */
-#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */
-#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */
-#define PCI_PM_DATA_REGISTER 7 /* (??) */
-#define PCI_PM_SIZEOF 8
-
-/* AGP registers */
-
-#define PCI_AGP_VERSION 2 /* BCD version number */
-#define PCI_AGP_RFU 3 /* Rest of capability flags */
-#define PCI_AGP_STATUS 4 /* Status register */
-#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
-#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
-#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
-#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
-#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
-#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
-#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
-#define PCI_AGP_COMMAND 8 /* Control register */
-#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
-#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
-#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
-#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
-#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
-#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
-#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
-#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
-#define PCI_AGP_SIZEOF 12
-
-/* Slot Identification */
-
-#define PCI_SID_ESR 2 /* Expansion Slot Register */
-#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */
-#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */
-#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */
-
-/* Message Signalled Interrupts registers */
-
-#define PCI_MSI_FLAGS 2 /* Various flags */
-#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
-#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
-#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
-#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
-#define PCI_MSI_RFU 3 /* Rest of capability flags */
-#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
-#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
-#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
-#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
-
-/* Advanced Error Reporting */
-
-#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */
-#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */
-#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */
-#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */
-#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */
-#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */
-#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */
-#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */
-#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */
-#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */
-#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */
-#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */
-#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */
- /* Same bits as above */
-#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */
- /* Same bits as above */
-#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */
-#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */
-#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */
-#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */
-#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */
-#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */
-#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */
- /* Same bits as above */
+/** PCI interrupt line */
+#define PCI_INTERRUPT_LINE 0x3c
+
+/** Capability ID */
+#define PCI_CAP_ID 0x00
+#define PCI_CAP_ID_PM 0x01 /**< Power management */
+#define PCI_CAP_ID_VPD 0x03 /**< Vital product data */
+#define PCI_CAP_ID_VNDR 0x09 /**< Vendor-specific */
+#define PCI_CAP_ID_EXP 0x10 /**< PCI Express */
+
+/** Next capability */
+#define PCI_CAP_NEXT 0x01
+
+/** Power management control and status */
+#define PCI_PM_CTRL 0x04
+#define PCI_PM_CTRL_STATE_MASK 0x0003 /**< Current power state */
+#define PCI_PM_CTRL_PME_ENABLE 0x0100 /**< PME pin enable */
+#define PCI_PM_CTRL_PME_STATUS 0x8000 /**< PME pin status */
+
+/** Uncorrectable error status */
+#define PCI_ERR_UNCOR_STATUS 0x04
+
+/** Network controller */
+#define PCI_CLASS_NETWORK 0x02
+
+/** Serial bus controller */
+#define PCI_CLASS_SERIAL 0x0c
+#define PCI_CLASS_SERIAL_USB 0x03 /**< USB controller */
+#define PCI_CLASS_SERIAL_USB_UHCI 0x00 /**< UHCI USB controller */
+#define PCI_CLASS_SERIAL_USB_OHCI 0x10 /**< OHCI USB controller */
+#define PCI_CLASS_SERIAL_USB_EHCI 0x20 /**< ECHI USB controller */
+#define PCI_CLASS_SERIAL_USB_XHCI 0x30 /**< xHCI USB controller */
+
+/** Construct PCI class
+ *
+ * @v base Base class (or PCI_ANY_ID)
+ * @v sub Subclass (or PCI_ANY_ID)
+ * @v progif Programming interface (or PCI_ANY_ID)
+ */
+#define PCI_CLASS( base, sub, progif ) \
+ ( ( ( (base) & 0xff ) << 16 ) | ( ( (sub) & 0xff ) << 8 ) | \
+ ( ( (progif) & 0xff) << 0 ) )
/** A PCI device ID list entry */
struct pci_device_id {
@@ -279,6 +143,27 @@ struct pci_device_id {
/** Match-anything ID */
#define PCI_ANY_ID 0xffff
+/** A PCI class ID */
+struct pci_class_id {
+ /** Class */
+ uint32_t class;
+ /** Class mask */
+ uint32_t mask;
+};
+
+/** Construct PCI class ID
+ *
+ * @v base Base class (or PCI_ANY_ID)
+ * @v sub Subclass (or PCI_ANY_ID)
+ * @v progif Programming interface (or PCI_ANY_ID)
+ */
+#define PCI_CLASS_ID( base, sub, progif ) { \
+ .class = PCI_CLASS ( base, sub, progif ), \
+ .mask = ( ( ( ( (base) == PCI_ANY_ID ) ? 0x00 : 0xff ) << 16 ) | \
+ ( ( ( (sub) == PCI_ANY_ID ) ? 0x00 : 0xff ) << 8 ) | \
+ ( ( ( (progif) == PCI_ANY_ID ) ? 0x00 : 0xff ) << 0 ) ), \
+ }
+
/** A PCI device */
struct pci_device {
/** Generic device */
@@ -322,6 +207,8 @@ struct pci_driver {
struct pci_device_id *ids;
/** Number of entries in PCI ID table */
unsigned int id_count;
+ /** PCI class ID */
+ struct pci_class_id class;
/**
* Probe device
*
@@ -352,6 +239,7 @@ struct pci_driver {
#define PCI_BUSDEVFN( bus, slot, func ) \
( ( (bus) << 8 ) | ( (slot) << 3 ) | ( (func) << 0 ) )
#define PCI_FIRST_FUNC( busdevfn ) ( (busdevfn) & ~0x07 )
+#define PCI_LAST_FUNC( busdevfn ) ( (busdevfn) | 0x07 )
#define PCI_BASE_CLASS( class ) ( (class) >> 16 )
#define PCI_SUB_CLASS( class ) ( ( (class) >> 8 ) & 0xff )
diff --git a/qemu/roms/ipxe/src/include/ipxe/pci_ids.h b/qemu/roms/ipxe/src/include/ipxe/pci_ids.h
deleted file mode 100644
index 25c7782bc..000000000
--- a/qemu/roms/ipxe/src/include/ipxe/pci_ids.h
+++ /dev/null
@@ -1,351 +0,0 @@
-#ifndef _IPXE_PCI_IDS_H
-#define _IPXE_PCI_IDS_H
-
-/*
- * PCI Class, Vendor and Device IDs
- *
- * Please keep sorted.
- */
-
-FILE_LICENCE ( GPL2_ONLY );
-
-/* Device classes and subclasses */
-
-#define PCI_CLASS_NOT_DEFINED 0x0000
-#define PCI_CLASS_NOT_DEFINED_VGA 0x0001
-
-#define PCI_BASE_CLASS_STORAGE 0x01
-#define PCI_CLASS_STORAGE_SCSI 0x0100
-#define PCI_CLASS_STORAGE_IDE 0x0101
-#define PCI_CLASS_STORAGE_FLOPPY 0x0102
-#define PCI_CLASS_STORAGE_IPI 0x0103
-#define PCI_CLASS_STORAGE_RAID 0x0104
-#define PCI_CLASS_STORAGE_OTHER 0x0180
-
-#define PCI_BASE_CLASS_NETWORK 0x02
-#define PCI_CLASS_NETWORK_ETHERNET 0x0200
-#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201
-#define PCI_CLASS_NETWORK_FDDI 0x0202
-#define PCI_CLASS_NETWORK_ATM 0x0203
-#define PCI_CLASS_NETWORK_OTHER 0x0280
-
-#define PCI_BASE_CLASS_DISPLAY 0x03
-#define PCI_CLASS_DISPLAY_VGA 0x0300
-#define PCI_CLASS_DISPLAY_XGA 0x0301
-#define PCI_CLASS_DISPLAY_3D 0x0302
-#define PCI_CLASS_DISPLAY_OTHER 0x0380
-
-#define PCI_BASE_CLASS_MULTIMEDIA 0x04
-#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400
-#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
-#define PCI_CLASS_MULTIMEDIA_PHONE 0x0402
-#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480
-
-#define PCI_BASE_CLASS_MEMORY 0x05
-#define PCI_CLASS_MEMORY_RAM 0x0500
-#define PCI_CLASS_MEMORY_FLASH 0x0501
-#define PCI_CLASS_MEMORY_OTHER 0x0580
-
-#define PCI_BASE_CLASS_BRIDGE 0x06
-#define PCI_CLASS_BRIDGE_HOST 0x0600
-#define PCI_CLASS_BRIDGE_ISA 0x0601
-#define PCI_CLASS_BRIDGE_EISA 0x0602
-#define PCI_CLASS_BRIDGE_MC 0x0603
-#define PCI_CLASS_BRIDGE_PCI 0x0604
-#define PCI_CLASS_BRIDGE_PCMCIA 0x0605
-#define PCI_CLASS_BRIDGE_NUBUS 0x0606
-#define PCI_CLASS_BRIDGE_CARDBUS 0x0607
-#define PCI_CLASS_BRIDGE_RACEWAY 0x0608
-#define PCI_CLASS_BRIDGE_OTHER 0x0680
-
-#define PCI_BASE_CLASS_COMMUNICATION 0x07
-#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
-#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
-#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702
-#define PCI_CLASS_COMMUNICATION_MODEM 0x0703
-#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
-
-#define PCI_BASE_CLASS_SYSTEM 0x08
-#define PCI_CLASS_SYSTEM_PIC 0x0800
-#define PCI_CLASS_SYSTEM_DMA 0x0801
-#define PCI_CLASS_SYSTEM_TIMER 0x0802
-#define PCI_CLASS_SYSTEM_RTC 0x0803
-#define PCI_CLASS_SYSTEM_PCI_HOTPLUG 0x0804
-#define PCI_CLASS_SYSTEM_OTHER 0x0880
-
-#define PCI_BASE_CLASS_INPUT 0x09
-#define PCI_CLASS_INPUT_KEYBOARD 0x0900
-#define PCI_CLASS_INPUT_PEN 0x0901
-#define PCI_CLASS_INPUT_MOUSE 0x0902
-#define PCI_CLASS_INPUT_SCANNER 0x0903
-#define PCI_CLASS_INPUT_GAMEPORT 0x0904
-#define PCI_CLASS_INPUT_OTHER 0x0980
-
-#define PCI_BASE_CLASS_DOCKING 0x0a
-#define PCI_CLASS_DOCKING_GENERIC 0x0a00
-#define PCI_CLASS_DOCKING_OTHER 0x0a80
-
-#define PCI_BASE_CLASS_PROCESSOR 0x0b
-#define PCI_CLASS_PROCESSOR_386 0x0b00
-#define PCI_CLASS_PROCESSOR_486 0x0b01
-#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02
-#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10
-#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20
-#define PCI_CLASS_PROCESSOR_MIPS 0x0b30
-#define PCI_CLASS_PROCESSOR_CO 0x0b40
-
-#define PCI_BASE_CLASS_SERIAL 0x0c
-#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00
-#define PCI_CLASS_SERIAL_ACCESS 0x0c01
-#define PCI_CLASS_SERIAL_SSA 0x0c02
-#define PCI_CLASS_SERIAL_USB 0x0c03
-#define PCI_CLASS_SERIAL_FIBER 0x0c04
-#define PCI_CLASS_SERIAL_SMBUS 0x0c05
-
-#define PCI_BASE_CLASS_INTELLIGENT 0x0e
-#define PCI_CLASS_INTELLIGENT_I2O 0x0e00
-
-#define PCI_BASE_CLASS_SATELLITE 0x0f
-#define PCI_CLASS_SATELLITE_TV 0x0f00
-#define PCI_CLASS_SATELLITE_AUDIO 0x0f01
-#define PCI_CLASS_SATELLITE_VOICE 0x0f03
-#define PCI_CLASS_SATELLITE_DATA 0x0f04
-
-#define PCI_BASE_CLASS_CRYPT 0x10
-#define PCI_CLASS_CRYPT_NETWORK 0x1000
-#define PCI_CLASS_CRYPT_ENTERTAINMENT 0x1001
-#define PCI_CLASS_CRYPT_OTHER 0x1080
-
-#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11
-#define PCI_CLASS_SP_DPIO 0x1100
-#define PCI_CLASS_SP_OTHER 0x1180
-
-#define PCI_CLASS_OTHERS 0xff
-
-/* Vendors */
-
-#define PCI_VENDOR_ID_DYNALINK 0x0675
-#define PCI_VENDOR_ID_BERKOM 0x0871
-#define PCI_VENDOR_ID_COMPAQ 0x0e11
-#define PCI_VENDOR_ID_NCR 0x1000
-#define PCI_VENDOR_ID_LSI_LOGIC 0x1000
-#define PCI_VENDOR_ID_ATI 0x1002
-#define PCI_VENDOR_ID_VLSI 0x1004
-#define PCI_VENDOR_ID_ADL 0x1005
-#define PCI_VENDOR_ID_NS 0x100b
-#define PCI_VENDOR_ID_TSENG 0x100c
-#define PCI_VENDOR_ID_WEITEK 0x100e
-#define PCI_VENDOR_ID_DEC 0x1011
-#define PCI_VENDOR_ID_CIRRUS 0x1013
-#define PCI_VENDOR_ID_IBM 0x1014
-#define PCI_VENDOR_ID_COMPEX2 0x101a
-/* pci.ids says "AT&T GIS (NCR)" */
-#define PCI_VENDOR_ID_WD 0x101c
-#define PCI_VENDOR_ID_AMI 0x101e
-#define PCI_VENDOR_ID_AMD 0x1022
-#define PCI_VENDOR_ID_TRIDENT 0x1023
-#define PCI_VENDOR_ID_AI 0x1025
-#define PCI_VENDOR_ID_DELL 0x1028
-#define PCI_VENDOR_ID_MATROX 0x102B
-#define PCI_VENDOR_ID_CT 0x102c
-#define PCI_VENDOR_ID_MIRO 0x1031
-#define PCI_VENDOR_ID_NEC 0x1033
-#define PCI_VENDOR_ID_FD 0x1036
-#define PCI_VENDOR_ID_SIS 0x1039
-#define PCI_VENDOR_ID_SI 0x1039
-#define PCI_VENDOR_ID_HP 0x103c
-#define PCI_VENDOR_ID_PCTECH 0x1042
-#define PCI_VENDOR_ID_ASUSTEK 0x1043
-#define PCI_VENDOR_ID_DPT 0x1044
-#define PCI_VENDOR_ID_OPTI 0x1045
-#define PCI_VENDOR_ID_ELSA 0x1048
-#define PCI_VENDOR_ID_ELSA 0x1048
-#define PCI_VENDOR_ID_SGS 0x104a
-#define PCI_VENDOR_ID_BUSLOGIC 0x104B
-#define PCI_VENDOR_ID_TI 0x104c
-#define PCI_VENDOR_ID_SONY 0x104d
-#define PCI_VENDOR_ID_OAK 0x104e
-/* Winbond have two vendor IDs! See 0x10ad as well */
-#define PCI_VENDOR_ID_WINBOND2 0x1050
-#define PCI_VENDOR_ID_ANIGMA 0x1051
-#define PCI_VENDOR_ID_EFAR 0x1055
-#define PCI_VENDOR_ID_MOTOROLA 0x1057
-#define PCI_VENDOR_ID_MOTOROLA_OOPS 0x1507
-#define PCI_VENDOR_ID_PROMISE 0x105a
-#define PCI_VENDOR_ID_N9 0x105d
-#define PCI_VENDOR_ID_UMC 0x1060
-#define PCI_VENDOR_ID_X 0x1061
-#define PCI_VENDOR_ID_MYLEX 0x1069
-#define PCI_VENDOR_ID_PICOP 0x1066
-#define PCI_VENDOR_ID_APPLE 0x106b
-#define PCI_VENDOR_ID_YAMAHA 0x1073
-#define PCI_VENDOR_ID_NEXGEN 0x1074
-#define PCI_VENDOR_ID_QLOGIC 0x1077
-#define PCI_VENDOR_ID_CYRIX 0x1078
-#define PCI_VENDOR_ID_LEADTEK 0x107d
-#define PCI_VENDOR_ID_INTERPHASE 0x107e
-#define PCI_VENDOR_ID_CONTAQ 0x1080
-#define PCI_VENDOR_ID_FOREX 0x1083
-#define PCI_VENDOR_ID_OLICOM 0x108d
-#define PCI_VENDOR_ID_SUN 0x108e
-#define PCI_VENDOR_ID_CMD 0x1095
-#define PCI_VENDOR_ID_VISION 0x1098
-#define PCI_VENDOR_ID_BROOKTREE 0x109e
-#define PCI_VENDOR_ID_SIERRA 0x10a8
-#define PCI_VENDOR_ID_SGI 0x10a9
-#define PCI_VENDOR_ID_ACC 0x10aa
-#define PCI_VENDOR_ID_WINBOND 0x10ad
-#define PCI_VENDOR_ID_DATABOOK 0x10b3
-#define PCI_VENDOR_ID_PLX 0x10b5
-#define PCI_VENDOR_ID_MADGE 0x10b6
-#define PCI_VENDOR_ID_3COM 0x10b7
-#define PCI_VENDOR_ID_SMC 0x10b8
-#define PCI_VENDOR_ID_SUNDANCE 0x13F0
-#define PCI_VENDOR_ID_AL 0x10b9
-#define PCI_VENDOR_ID_MITSUBISHI 0x10ba
-#define PCI_VENDOR_ID_SURECOM 0x10bd
-#define PCI_VENDOR_ID_NEOMAGIC 0x10c8
-#define PCI_VENDOR_ID_ASP 0x10cd
-#define PCI_VENDOR_ID_MACRONIX 0x10d9
-#define PCI_VENDOR_ID_TCONRAD 0x10da
-#define PCI_VENDOR_ID_CERN 0x10dc
-#define PCI_VENDOR_ID_NVIDIA 0x10de
-#define PCI_VENDOR_ID_IMS 0x10e0
-#define PCI_VENDOR_ID_TEKRAM2 0x10e1
-#define PCI_VENDOR_ID_TUNDRA 0x10e3
-#define PCI_VENDOR_ID_AMCC 0x10e8
-#define PCI_VENDOR_ID_INTERG 0x10ea
-#define PCI_VENDOR_ID_REALTEK 0x10ec
-#define PCI_VENDOR_ID_XILINX 0x10ee
-#define PCI_VENDOR_ID_TRUEVISION 0x10fa
-#define PCI_VENDOR_ID_INIT 0x1101
-#define PCI_VENDOR_ID_CREATIVE 0x1102
-/* duplicate: ECTIVA */
-#define PCI_VENDOR_ID_ECTIVA 0x1102
-/* duplicate: CREATIVE */
-#define PCI_VENDOR_ID_TTI 0x1103
-#define PCI_VENDOR_ID_VIA 0x1106
-#define PCI_VENDOR_ID_VIATEC 0x1106
-#define PCI_VENDOR_ID_SIEMENS 0x110A
-#define PCI_VENDOR_ID_SMC2 0x1113
-#define PCI_VENDOR_ID_VORTEX 0x1119
-#define PCI_VENDOR_ID_EF 0x111a
-#define PCI_VENDOR_ID_IDT 0x111d
-#define PCI_VENDOR_ID_FORE 0x1127
-#define PCI_VENDOR_ID_IMAGINGTECH 0x112f
-#define PCI_VENDOR_ID_PHILIPS 0x1131
-#define PCI_VENDOR_ID_EICON 0x1133
-#define PCI_VENDOR_ID_CYCLONE 0x113c
-#define PCI_VENDOR_ID_ALLIANCE 0x1142
-#define PCI_VENDOR_ID_SYSKONNECT 0x1148
-#define PCI_VENDOR_ID_VMIC 0x114a
-#define PCI_VENDOR_ID_DIGI 0x114f
-#define PCI_VENDOR_ID_MUTECH 0x1159
-#define PCI_VENDOR_ID_XIRCOM 0x115d
-#define PCI_VENDOR_ID_RENDITION 0x1163
-#define PCI_VENDOR_ID_SERVERWORKS 0x1166
-#define PCI_VENDOR_ID_SBE 0x1176
-#define PCI_VENDOR_ID_TOSHIBA 0x1179
-#define PCI_VENDOR_ID_RICOH 0x1180
-#define PCI_VENDOR_ID_DLINK 0x1186
-#define PCI_VENDOR_ID_ARTOP 0x1191
-#define PCI_VENDOR_ID_ZEITNET 0x1193
-#define PCI_VENDOR_ID_OMEGA 0x119b
-#define PCI_VENDOR_ID_FUJITSU_ME 0x119e
-#define PCI_SUBVENDOR_ID_KEYSPAN 0x11a9
-#define PCI_VENDOR_ID_GALILEO 0x11ab
-#define PCI_VENDOR_ID_LINKSYS 0x11ad
-#define PCI_VENDOR_ID_LITEON 0x11ad
-#define PCI_VENDOR_ID_V3 0x11b0
-#define PCI_VENDOR_ID_NP 0x11bc
-#define PCI_VENDOR_ID_ATT 0x11c1
-#define PCI_VENDOR_ID_SPECIALIX 0x11cb
-#define PCI_VENDOR_ID_AURAVISION 0x11d1
-#define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4
-#define PCI_VENDOR_ID_IKON 0x11d5
-#define PCI_VENDOR_ID_ZORAN 0x11de
-#define PCI_VENDOR_ID_KINETIC 0x11f4
-#define PCI_VENDOR_ID_COMPEX 0x11f6
-#define PCI_VENDOR_ID_RP 0x11fe
-#define PCI_VENDOR_ID_CYCLADES 0x120e
-#define PCI_VENDOR_ID_ESSENTIAL 0x120f
-#define PCI_VENDOR_ID_O2 0x1217
-#define PCI_VENDOR_ID_3DFX 0x121a
-#define PCI_VENDOR_ID_SIGMADES 0x1236
-#define PCI_VENDOR_ID_CCUBE 0x123f
-#define PCI_VENDOR_ID_AVM 0x1244
-#define PCI_VENDOR_ID_DIPIX 0x1246
-#define PCI_VENDOR_ID_STALLION 0x124d
-#define PCI_VENDOR_ID_OPTIBASE 0x1255
-#define PCI_VENDOR_ID_ESS 0x125d
-#define PCI_VENDOR_ID_HARRIS 0x1260
-#define PCI_VENDOR_ID_SATSAGEM 0x1267
-#define PCI_VENDOR_ID_HUGHES 0x1273
-#define PCI_VENDOR_ID_ENSONIQ 0x1274
-#define PCI_VENDOR_ID_ROCKWELL 0x127A
-#define PCI_VENDOR_ID_DAVICOM 0x1282
-#define PCI_VENDOR_ID_ITE 0x1283
-/* formerly Platform Tech */
-#define PCI_VENDOR_ID_ESS_OLD 0x1285
-#define PCI_VENDOR_ID_ALTEON 0x12ae
-#define PCI_VENDOR_ID_USR 0x12B9
-#define PCI_VENDOR_ID_HOLTEK 0x12c3
-#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4
-#define PCI_VENDOR_ID_PICTUREL 0x12c5
-#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2
-#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0
-#define PCI_SUBVENDOR_ID_CHASE_PCIRAS 0x124D
-#define PCI_VENDOR_ID_AUREAL 0x12eb
-#define PCI_VENDOR_ID_CBOARDS 0x1307
-#define PCI_VENDOR_ID_SIIG 0x131f
-#define PCI_VENDOR_ID_ADMTEK 0x1317
-#define PCI_VENDOR_ID_DOMEX 0x134a
-#define PCI_VENDOR_ID_QUATECH 0x135C
-#define PCI_VENDOR_ID_SEALEVEL 0x135e
-#define PCI_VENDOR_ID_HYPERCOPE 0x1365
-#define PCI_VENDOR_ID_KAWASAKI 0x136b
-#define PCI_VENDOR_ID_LMC 0x1376
-#define PCI_VENDOR_ID_NETGEAR 0x1385
-#define PCI_VENDOR_ID_APPLICOM 0x1389
-#define PCI_VENDOR_ID_MOXA 0x1393
-#define PCI_VENDOR_ID_CCD 0x1397
-#define PCI_VENDOR_ID_MICROGATE 0x13c0
-#define PCI_VENDOR_ID_3WARE 0x13C1
-#define PCI_VENDOR_ID_ABOCOM 0x13D1
-#define PCI_VENDOR_ID_CMEDIA 0x13f6
-#define PCI_VENDOR_ID_LAVA 0x1407
-#define PCI_VENDOR_ID_TIMEDIA 0x1409
-#define PCI_VENDOR_ID_OXSEMI 0x1415
-#define PCI_VENDOR_ID_AIRONET 0x14b9
-#define PCI_VENDOR_ID_MYRICOM 0x14c1
-#define PCI_VENDOR_ID_TITAN 0x14D2
-#define PCI_VENDOR_ID_PANACOM 0x14d4
-#define PCI_VENDOR_ID_BROADCOM 0x14e4
-#define PCI_VENDOR_ID_SYBA 0x1592
-#define PCI_VENDOR_ID_MORETON 0x15aa
-#define PCI_VENDOR_ID_ZOLTRIX 0x15b0
-#define PCI_VENDOR_ID_PDC 0x15e9
-#define PCI_VENDOR_ID_FSC 0x1734
-#define PCI_VENDOR_ID_SYMPHONY 0x1c1c
-#define PCI_VENDOR_ID_TEKRAM 0x1de1
-#define PCI_VENDOR_ID_3DLABS 0x3d3d
-#define PCI_VENDOR_ID_AVANCE 0x4005
-#define PCI_VENDOR_ID_AKS 0x416c
-#define PCI_VENDOR_ID_NETVIN 0x4a14
-#define PCI_VENDOR_ID_S3 0x5333
-#define PCI_VENDOR_ID_DCI 0x6666
-#define PCI_VENDOR_ID_GENROCO 0x5555
-#define PCI_VENDOR_ID_INTEL 0x8086
-#define PCI_VENDOR_ID_COMPUTONE 0x8e0e
-#define PCI_SUBVENDOR_ID_COMPUTONE 0x8e0e
-#define PCI_VENDOR_ID_KTI 0x8e2e
-#define PCI_VENDOR_ID_ADAPTEC 0x9004
-#define PCI_VENDOR_ID_ADAPTEC2 0x9005
-#define PCI_VENDOR_ID_ATRONICS 0x907f
-#define PCI_VENDOR_ID_HOLTEK2 0x9412
-#define PCI_VENDOR_ID_NETMOS 0x9710
-#define PCI_SUBVENDOR_ID_EXSYS 0xd84d
-#define PCI_VENDOR_ID_TIGERJET 0xe159
-#define PCI_VENDOR_ID_ARK 0xedd8
-
-#endif /* _IPXE_PCI_IDS_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/pci_io.h b/qemu/roms/ipxe/src/include/ipxe/pci_io.h
index 781b77fe1..10e69763e 100644
--- a/qemu/roms/ipxe/src/include/ipxe/pci_io.h
+++ b/qemu/roms/ipxe/src/include/ipxe/pci_io.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/api.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/pcibackup.h b/qemu/roms/ipxe/src/include/ipxe/pcibackup.h
index b9f55cf71..159d25392 100644
--- a/qemu/roms/ipxe/src/include/ipxe/pcibackup.h
+++ b/qemu/roms/ipxe/src/include/ipxe/pcibackup.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/pcivpd.h b/qemu/roms/ipxe/src/include/ipxe/pcivpd.h
index 0abf8a956..fefb69740 100644
--- a/qemu/roms/ipxe/src/include/ipxe/pcivpd.h
+++ b/qemu/roms/ipxe/src/include/ipxe/pcivpd.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <byteswap.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/peerblk.h b/qemu/roms/ipxe/src/include/ipxe/peerblk.h
new file mode 100644
index 000000000..6fc9172f6
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/peerblk.h
@@ -0,0 +1,144 @@
+#ifndef _IPXE_PEERBLK_H
+#define _IPXE_PEERBLK_H
+
+/** @file
+ *
+ * Peer Content Caching and Retrieval (PeerDist) protocol block downloads
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/refcnt.h>
+#include <ipxe/interface.h>
+#include <ipxe/crypto.h>
+#include <ipxe/aes.h>
+#include <ipxe/xferbuf.h>
+#include <ipxe/retry.h>
+#include <ipxe/process.h>
+#include <ipxe/pccrc.h>
+#include <ipxe/peerdisc.h>
+
+/** A PeerDist retrieval protocol decryption buffer descriptor */
+struct peerdist_block_decrypt {
+ /** Data transfer buffer */
+ struct xfer_buffer *xferbuf;
+ /** Offset within data transfer buffer */
+ size_t offset;
+ /** Length to use from data transfer buffer */
+ size_t len;
+};
+
+/** PeerDist retrieval protocol decryption data transfer buffer indices */
+enum peerdist_block_decrypt_index {
+ /** Data before the trimmed content */
+ PEERBLK_BEFORE = 0,
+ /** Data within the trimmed content */
+ PEERBLK_DURING,
+ /** Data after the trimmed content */
+ PEERBLK_AFTER,
+ /** Number of decryption buffers */
+ PEERBLK_NUM_BUFFERS
+};
+
+/** A PeerDist block download */
+struct peerdist_block {
+ /** Reference count */
+ struct refcnt refcnt;
+ /** Data transfer interface */
+ struct interface xfer;
+ /** Raw data interface */
+ struct interface raw;
+ /** Retrieval protocol interface */
+ struct interface retrieval;
+
+ /** Original URI */
+ struct uri *uri;
+ /** Content range of this block */
+ struct peerdist_range range;
+ /** Trimmed range of this block */
+ struct peerdist_range trim;
+ /** Offset of first byte in trimmed range within overall download */
+ size_t offset;
+
+ /** Digest algorithm */
+ struct digest_algorithm *digest;
+ /** Digest size
+ *
+ * Note that this may be shorter than the digest size of the
+ * digest algorithm.
+ */
+ size_t digestsize;
+ /** Digest context (statically allocated at instantiation time) */
+ void *digestctx;
+
+ /** Cipher algorithm */
+ struct cipher_algorithm *cipher;
+ /** Cipher context (dynamically allocated as needed) */
+ void *cipherctx;
+
+ /** Segment index */
+ unsigned int segment;
+ /** Segment identifier */
+ uint8_t id[PEERDIST_DIGEST_MAX_SIZE];
+ /** Segment secret */
+ uint8_t secret[PEERDIST_DIGEST_MAX_SIZE];
+ /** Block index */
+ unsigned int block;
+ /** Block hash */
+ uint8_t hash[PEERDIST_DIGEST_MAX_SIZE];
+
+ /** Current position (relative to incoming data stream) */
+ size_t pos;
+ /** Start of trimmed content (relative to incoming data stream) */
+ size_t start;
+ /** End of trimmed content (relative to incoming data stream) */
+ size_t end;
+ /** Data buffer */
+ struct xfer_buffer buffer;
+
+ /** Decryption process */
+ struct process process;
+ /** Decryption data buffer descriptors */
+ struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS];
+ /** Remaining decryption length */
+ size_t cipher_remaining;
+ /** Remaining digest length (excluding AES padding bytes) */
+ size_t digest_remaining;
+
+ /** Discovery client */
+ struct peerdisc_client discovery;
+ /** Current position in discovered peer list */
+ struct peerdisc_peer *peer;
+ /** Retry timer */
+ struct retry_timer timer;
+ /** Number of full attempt cycles completed */
+ unsigned int cycles;
+ /** Most recent attempt failure */
+ int rc;
+
+ /** Time at which block download was started */
+ unsigned long started;
+ /** Time at which most recent attempt was started */
+ unsigned long attempted;
+};
+
+/** Retrieval protocol block fetch response (including transport header)
+ *
+ * @v digestsize Digest size
+ * @v len Data block length
+ * @v vrf_len Length of uselessness
+ * @v blksize Cipher block size
+ */
+#define peerblk_msg_blk_t( digestsize, len, vrf_len, blksize ) \
+ struct { \
+ struct peerdist_msg_transport_header hdr; \
+ peerdist_msg_blk_t ( digestsize, len, vrf_len, \
+ blksize ) msg; \
+ } __attribute__ (( packed ))
+
+extern int peerblk_open ( struct interface *xfer, struct uri *uri,
+ struct peerdist_info_block *block );
+
+#endif /* _IPXE_PEERBLK_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/peerdisc.h b/qemu/roms/ipxe/src/include/ipxe/peerdisc.h
new file mode 100644
index 000000000..f08ccaae2
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/peerdisc.h
@@ -0,0 +1,116 @@
+#ifndef _IPXE_PEERDISC_H
+#define _IPXE_PEERDISC_H
+
+/** @file
+ *
+ * Peer Content Caching and Retrieval (PeerDist) protocol peer discovery
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/refcnt.h>
+#include <ipxe/list.h>
+#include <ipxe/tables.h>
+#include <ipxe/retry.h>
+#include <ipxe/socket.h>
+#include <ipxe/interface.h>
+#include <ipxe/pccrc.h>
+
+/** A PeerDist discovery socket */
+struct peerdisc_socket {
+ /** Name */
+ const char *name;
+ /** Data transfer interface */
+ struct interface xfer;
+ /** Socket address */
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ } address;
+};
+
+/** PeerDist discovery socket table */
+#define PEERDISC_SOCKETS __table ( struct peerdisc_socket, "peerdisc_sockets" )
+
+/** Declare a PeerDist discovery socket */
+#define __peerdisc_socket __table_entry ( PEERDISC_SOCKETS, 01 )
+
+/** A PeerDist discovery segment */
+struct peerdisc_segment {
+ /** Reference count */
+ struct refcnt refcnt;
+ /** List of segments */
+ struct list_head list;
+ /** Segment identifier string
+ *
+ * This is MS-PCCRC's "HoHoDk", transcribed as an upper-case
+ * Base16-encoded string.
+ */
+ const char *id;
+ /** Message UUID string */
+ const char *uuid;
+ /** List of discovered peers
+ *
+ * The list of peers may be appended to during the lifetime of
+ * the discovery segment. Discovered peers will not be
+ * removed from the list until the last discovery has been
+ * closed; this allows users to safely maintain a pointer to a
+ * current position within the list.
+ */
+ struct list_head peers;
+ /** List of active clients */
+ struct list_head clients;
+ /** Transmission timer */
+ struct retry_timer timer;
+};
+
+/** A PeerDist discovery peer */
+struct peerdisc_peer {
+ /** List of peers */
+ struct list_head list;
+ /** Peer location */
+ char location[0];
+};
+
+/** A PeerDist discovery client */
+struct peerdisc_client {
+ /** Discovery segment */
+ struct peerdisc_segment *segment;
+ /** List of clients */
+ struct list_head list;
+ /** Operations */
+ struct peerdisc_client_operations *op;
+};
+
+/** PeerDist discovery client operations */
+struct peerdisc_client_operations {
+ /** New peers have been discovered
+ *
+ * @v peerdisc PeerDist discovery client
+ */
+ void ( * discovered ) ( struct peerdisc_client *peerdisc );
+};
+
+/**
+ * Initialise PeerDist discovery
+ *
+ * @v peerdisc PeerDist discovery client
+ * @v op Discovery operations
+ */
+static inline __attribute__ (( always_inline )) void
+peerdisc_init ( struct peerdisc_client *peerdisc,
+ struct peerdisc_client_operations *op ) {
+
+ peerdisc->op = op;
+}
+
+extern unsigned int peerdisc_timeout_secs;
+
+extern int peerdisc_open ( struct peerdisc_client *peerdisc, const void *id,
+ size_t len );
+extern void peerdisc_close ( struct peerdisc_client *peerdisc );
+
+#endif /* _IPXE_PEERDISC_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/peermux.h b/qemu/roms/ipxe/src/include/ipxe/peermux.h
new file mode 100644
index 000000000..44cbdb9d6
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/peermux.h
@@ -0,0 +1,73 @@
+#ifndef _IPXE_PEERMUX_H
+#define _IPXE_PEERMUX_H
+
+/** @file
+ *
+ * Peer Content Caching and Retrieval (PeerDist) protocol multiplexer
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/list.h>
+#include <ipxe/refcnt.h>
+#include <ipxe/interface.h>
+#include <ipxe/process.h>
+#include <ipxe/uri.h>
+#include <ipxe/xferbuf.h>
+#include <ipxe/pccrc.h>
+
+/** Maximum number of concurrent block downloads */
+#define PEERMUX_MAX_BLOCKS 32
+
+/** PeerDist download content information cache */
+struct peerdist_info_cache {
+ /** Content information */
+ struct peerdist_info info;
+ /** Content information segment */
+ struct peerdist_info_segment segment;
+ /** Content information block */
+ struct peerdist_info_block block;
+};
+
+/** A PeerDist multiplexed block download */
+struct peerdist_multiplexed_block {
+ /** PeerDist download multiplexer */
+ struct peerdist_multiplexer *peermux;
+ /** List of multiplexed blocks */
+ struct list_head list;
+ /** Data transfer interface */
+ struct interface xfer;
+};
+
+/** A PeerDist download multiplexer */
+struct peerdist_multiplexer {
+ /** Reference count */
+ struct refcnt refcnt;
+ /** Data transfer interface */
+ struct interface xfer;
+ /** Content information interface */
+ struct interface info;
+ /** Original URI */
+ struct uri *uri;
+
+ /** Content information data transfer buffer */
+ struct xfer_buffer buffer;
+ /** Content information cache */
+ struct peerdist_info_cache cache;
+
+ /** Block download initiation process */
+ struct process process;
+ /** List of busy block downloads */
+ struct list_head busy;
+ /** List of idle block downloads */
+ struct list_head idle;
+ /** Block downloads */
+ struct peerdist_multiplexed_block block[PEERMUX_MAX_BLOCKS];
+};
+
+extern int peermux_filter ( struct interface *xfer, struct interface *info,
+ struct uri *uri );
+
+#endif /* _IPXE_PEERMUX_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/pending.h b/qemu/roms/ipxe/src/include/ipxe/pending.h
index e6a369813..be6ed05a1 100644
--- a/qemu/roms/ipxe/src/include/ipxe/pending.h
+++ b/qemu/roms/ipxe/src/include/ipxe/pending.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** A pending operation */
struct pending_operation {
diff --git a/qemu/roms/ipxe/src/include/ipxe/ping.h b/qemu/roms/ipxe/src/include/ipxe/ping.h
index 6cd376b6f..c55bd1ab2 100644
--- a/qemu/roms/ipxe/src/include/ipxe/ping.h
+++ b/qemu/roms/ipxe/src/include/ipxe/ping.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/iobuf.h>
#include <ipxe/tcpip.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/pinger.h b/qemu/roms/ipxe/src/include/ipxe/pinger.h
index 9932df6b0..227f002dc 100644
--- a/qemu/roms/ipxe/src/include/ipxe/pinger.h
+++ b/qemu/roms/ipxe/src/include/ipxe/pinger.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/interface.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/pixbuf.h b/qemu/roms/ipxe/src/include/ipxe/pixbuf.h
index 106b666e6..615744812 100644
--- a/qemu/roms/ipxe/src/include/ipxe/pixbuf.h
+++ b/qemu/roms/ipxe/src/include/ipxe/pixbuf.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <ipxe/refcnt.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/png.h b/qemu/roms/ipxe/src/include/ipxe/png.h
index f51d1e6fe..3505eefc8 100644
--- a/qemu/roms/ipxe/src/include/ipxe/png.h
+++ b/qemu/roms/ipxe/src/include/ipxe/png.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <byteswap.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/pnm.h b/qemu/roms/ipxe/src/include/ipxe/pnm.h
index 536c14d5f..860968cbc 100644
--- a/qemu/roms/ipxe/src/include/ipxe/pnm.h
+++ b/qemu/roms/ipxe/src/include/ipxe/pnm.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/uaccess.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/pool.h b/qemu/roms/ipxe/src/include/ipxe/pool.h
new file mode 100644
index 000000000..27066e9b3
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/pool.h
@@ -0,0 +1,127 @@
+#ifndef _IPXE_POOL_H
+#define _IPXE_POOL_H
+
+/** @file
+ *
+ * Pooled connections
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/interface.h>
+#include <ipxe/list.h>
+#include <ipxe/retry.h>
+
+/** A pooled connection */
+struct pooled_connection {
+ /** List of pooled connections
+ *
+ * Note that each connecton in the pool has a running expiry
+ * timer which holds a reference to the connection. We
+ * therefore do not require the connection pool list to hold a
+ * reference for each pooled connection.
+ */
+ struct list_head list;
+ /** Expiry timer */
+ struct retry_timer timer;
+ /** Close expired pooled connection
+ *
+ * @v pool Pooled connection
+ */
+ void ( * expired ) ( struct pooled_connection *pool );
+ /** Flags */
+ unsigned int flags;
+};
+
+/** Pooled connection flags */
+enum pooled_connection_flags {
+ /** Connection should be recycled after closing */
+ POOL_RECYCLABLE = 0x0001,
+ /** Connection has been recycled */
+ POOL_RECYCLED = 0x0002,
+ /** Connection is known to be alive */
+ POOL_ALIVE = 0x0004,
+};
+
+extern void pool_add ( struct pooled_connection *pool, struct list_head *list,
+ unsigned long expiry );
+extern void pool_del ( struct pooled_connection *pool );
+extern void pool_expired ( struct retry_timer *timer, int over );
+
+/**
+ * Initialise a pooled connection
+ *
+ * @v pool Pooled connection
+ * @v expired Close expired pooled connection method
+ * @v refcnt Containing object reference counter
+ */
+static inline __attribute__ (( always_inline )) void
+pool_init ( struct pooled_connection *pool,
+ void ( * expired ) ( struct pooled_connection *pool ),
+ struct refcnt *refcnt ) {
+
+ INIT_LIST_HEAD ( &pool->list );
+ timer_init ( &pool->timer, pool_expired, refcnt );
+ pool->expired = expired;
+}
+
+/**
+ * Mark pooled connection as recyclable
+ *
+ * @v pool Pooled connection
+ */
+static inline __attribute__ (( always_inline )) void
+pool_recyclable ( struct pooled_connection *pool ) {
+
+ pool->flags |= POOL_RECYCLABLE;
+}
+
+/**
+ * Mark pooled connection as alive
+ *
+ * @v pool Pooled connection
+ */
+static inline __attribute__ (( always_inline )) void
+pool_alive ( struct pooled_connection *pool ) {
+
+ pool->flags |= POOL_ALIVE;
+}
+
+/**
+ * Check if pooled connection is recyclable
+ *
+ * @v pool Pooled connection
+ * @ret recyclable Pooled connection is recyclable
+ */
+static inline __attribute__ (( always_inline )) int
+pool_is_recyclable ( struct pooled_connection *pool ) {
+
+ return ( pool->flags & POOL_RECYCLABLE );
+}
+
+/**
+ * Check if pooled connection is reopenable
+ *
+ * @v pool Pooled connection
+ * @ret reopenable Pooled connection is reopenable
+ */
+static inline __attribute__ (( always_inline )) int
+pool_is_reopenable ( struct pooled_connection *pool ) {
+
+ /* A connection is reopenable if it has been recycled but is
+ * not yet known to be alive.
+ */
+ return ( ( pool->flags & POOL_RECYCLED ) &
+ ( ! ( pool->flags & POOL_ALIVE ) ) );
+}
+
+extern void pool_recycle ( struct interface *intf );
+#define pool_recycle_TYPE( object_type ) \
+ typeof ( void ( object_type ) )
+
+extern void pool_reopen ( struct interface *intf );
+#define pool_reopen_TYPE( object_type ) \
+ typeof ( void ( object_type ) )
+
+#endif /* _IPXE_POOL_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/portmap.h b/qemu/roms/ipxe/src/include/ipxe/portmap.h
index 9b735bbca..681ca2ec2 100644
--- a/qemu/roms/ipxe/src/include/ipxe/portmap.h
+++ b/qemu/roms/ipxe/src/include/ipxe/portmap.h
@@ -10,7 +10,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** PORTMAP default port */
#define PORTMAP_PORT 111
diff --git a/qemu/roms/ipxe/src/include/ipxe/posix_io.h b/qemu/roms/ipxe/src/include/ipxe/posix_io.h
index 11f3bb5c9..1a73b5e86 100644
--- a/qemu/roms/ipxe/src/include/ipxe/posix_io.h
+++ b/qemu/roms/ipxe/src/include/ipxe/posix_io.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/uaccess.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/privkey.h b/qemu/roms/ipxe/src/include/ipxe/privkey.h
index 39049ac9f..81108b6bf 100644
--- a/qemu/roms/ipxe/src/include/ipxe/privkey.h
+++ b/qemu/roms/ipxe/src/include/ipxe/privkey.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/asn1.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/process.h b/qemu/roms/ipxe/src/include/ipxe/process.h
index 2c76ff260..d600508e7 100644
--- a/qemu/roms/ipxe/src/include/ipxe/process.h
+++ b/qemu/roms/ipxe/src/include/ipxe/process.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/list.h>
#include <ipxe/refcnt.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/profile.h b/qemu/roms/ipxe/src/include/ipxe/profile.h
index 3a745fcfa..b6d2b19e0 100644
--- a/qemu/roms/ipxe/src/include/ipxe/profile.h
+++ b/qemu/roms/ipxe/src/include/ipxe/profile.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <bits/profile.h>
#include <ipxe/tables.h>
@@ -186,4 +186,18 @@ profile_exclude ( struct profiler *profiler ) {
profile_excluded += profile_elapsed ( profiler );
}
+/**
+ * Record profiling sample in custom units
+ *
+ * @v profiler Profiler
+ * @v sample Profiling sample
+ */
+static inline __attribute__ (( always_inline )) void
+profile_custom ( struct profiler *profiler, unsigned long sample ) {
+
+ /* If profiling is active then update stats */
+ if ( PROFILING )
+ profile_update ( profiler, sample );
+}
+
#endif /* _IPXE_PROFILE_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/random_nz.h b/qemu/roms/ipxe/src/include/ipxe/random_nz.h
index 6bb80d2ab..4c433fa38 100644
--- a/qemu/roms/ipxe/src/include/ipxe/random_nz.h
+++ b/qemu/roms/ipxe/src/include/ipxe/random_nz.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/rarp.h b/qemu/roms/ipxe/src/include/ipxe/rarp.h
index f84301a43..9054db21a 100644
--- a/qemu/roms/ipxe/src/include/ipxe/rarp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/rarp.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/netdevice.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/rbg.h b/qemu/roms/ipxe/src/include/ipxe/rbg.h
index 9689142f8..758238a65 100644
--- a/qemu/roms/ipxe/src/include/ipxe/rbg.h
+++ b/qemu/roms/ipxe/src/include/ipxe/rbg.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/drbg.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/reboot.h b/qemu/roms/ipxe/src/include/ipxe/reboot.h
index 97e0d5fb6..33606d9d5 100644
--- a/qemu/roms/ipxe/src/include/ipxe/reboot.h
+++ b/qemu/roms/ipxe/src/include/ipxe/reboot.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/api.h>
#include <config/reboot.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/refcnt.h b/qemu/roms/ipxe/src/include/ipxe/refcnt.h
index 0e8b8658c..7f489abc9 100644
--- a/qemu/roms/ipxe/src/include/ipxe/refcnt.h
+++ b/qemu/roms/ipxe/src/include/ipxe/refcnt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <assert.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/resolv.h b/qemu/roms/ipxe/src/include/ipxe/resolv.h
index d9868a5d7..ff48d35ca 100644
--- a/qemu/roms/ipxe/src/include/ipxe/resolv.h
+++ b/qemu/roms/ipxe/src/include/ipxe/resolv.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/interface.h>
#include <ipxe/tables.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/retry.h b/qemu/roms/ipxe/src/include/ipxe/retry.h
index c514822b2..76d45fbd0 100644
--- a/qemu/roms/ipxe/src/include/ipxe/retry.h
+++ b/qemu/roms/ipxe/src/include/ipxe/retry.h
@@ -7,14 +7,14 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/list.h>
-/** Default timeout value */
+/** Default minimum timeout value (in ticks) */
#define DEFAULT_MIN_TIMEOUT ( TICKS_PER_SEC / 4 )
-/** Limit after which the timeout will be deemed permanent */
+/** Default maximum timeout value (in ticks) */
#define DEFAULT_MAX_TIMEOUT ( 10 * TICKS_PER_SEC )
/** A retry timer */
@@ -25,16 +25,18 @@ struct retry_timer {
unsigned int running;
/** Timeout value (in ticks) */
unsigned long timeout;
- /** Minimum timeout value (in ticks)
+ /** Minimum timeout value (in ticks), or zero to use default
*
- * A value of zero means "use default timeout."
+ * The timeout will never be reduced below this value.
*/
- unsigned long min_timeout;
- /** Maximum timeout value before failure (in ticks)
+ unsigned long min;
+ /** Maximum timeout value (in ticks), or zero to use default
*
- * A value of zero means "use default timeout."
+ * The timeout will be deemed permanent (according to the
+ * failure indicator passed to expired()) when it exceeds this
+ * value.
*/
- unsigned long max_timeout;
+ unsigned long max;
/** Start time (in ticks) */
unsigned long start;
/** Retry count */
@@ -46,7 +48,7 @@ struct retry_timer {
*
* The timer will already be stopped when this method is
* called. The failure indicator will be True if the retry
- * timeout has already exceeded @c MAX_TIMEOUT.
+ * timeout has already exceeded @c max_timeout.
*/
void ( * expired ) ( struct retry_timer *timer, int over );
/** Reference counter
@@ -109,4 +111,18 @@ timer_running ( struct retry_timer *timer ) {
return ( timer->running );
}
+/**
+ * Set minimum and maximum timeouts
+ *
+ * @v timer Retry timer
+ * @v min Minimum timeout (in ticks), or zero to use default
+ * @v max Maximum timeout (in ticks), or zero to use default
+ */
+static inline __attribute__ (( always_inline )) void
+set_timer_limits ( struct retry_timer *timer, unsigned long min,
+ unsigned long max ) {
+ timer->min = min;
+ timer->max = max;
+}
+
#endif /* _IPXE_RETRY_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/rndis.h b/qemu/roms/ipxe/src/include/ipxe/rndis.h
new file mode 100644
index 000000000..bcb6d8e6a
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/rndis.h
@@ -0,0 +1,370 @@
+#ifndef _IPXE_RNDIS_H
+#define _IPXE_RNDIS_H
+
+/** @file
+ *
+ * Remote Network Driver Interface Specification
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/iobuf.h>
+
+/** Maximum time to wait for a transaction to complete
+ *
+ * This is a policy decision.
+ */
+#define RNDIS_MAX_WAIT_MS 1000
+
+/** RNDIS message header */
+struct rndis_header {
+ /** Message type */
+ uint32_t type;
+ /** Message length */
+ uint32_t len;
+} __attribute__ (( packed ));
+
+/** RNDIS initialise message */
+#define RNDIS_INITIALISE_MSG 0x00000002UL
+
+/** RNDIS initialise message */
+struct rndis_initialise_message {
+ /** Request ID */
+ uint32_t id;
+ /** Major version */
+ uint32_t major;
+ /** Minor version */
+ uint32_t minor;
+ /** Maximum transfer size */
+ uint32_t mtu;
+} __attribute__ (( packed ));
+
+/** Request ID used for initialisation
+ *
+ * This is a policy decision.
+ */
+#define RNDIS_INIT_ID 0xe110e110UL
+
+/** RNDIS major version */
+#define RNDIS_VERSION_MAJOR 1
+
+/** RNDIS minor version */
+#define RNDIS_VERSION_MINOR 0
+
+/** RNDIS maximum transfer size
+ *
+ * This is a policy decision.
+ */
+#define RNDIS_MTU 2048
+
+/** RNDIS initialise completion */
+#define RNDIS_INITIALISE_CMPLT 0x80000002UL
+
+/** RNDIS initialise completion */
+struct rndis_initialise_completion {
+ /** Request ID */
+ uint32_t id;
+ /** Status */
+ uint32_t status;
+ /** Major version */
+ uint32_t major;
+ /** Minor version */
+ uint32_t minor;
+ /** Device flags */
+ uint32_t flags;
+ /** Medium */
+ uint32_t medium;
+ /** Maximum packets per transfer */
+ uint32_t max_pkts;
+ /** Maximum transfer size */
+ uint32_t mtu;
+ /** Packet alignment factor */
+ uint32_t align;
+ /** Reserved */
+ uint32_t reserved;
+} __attribute__ (( packed ));
+
+/** RNDIS halt message */
+#define RNDIS_HALT_MSG 0x00000003UL
+
+/** RNDIS halt message */
+struct rndis_halt_message {
+ /** Request ID */
+ uint32_t id;
+} __attribute__ (( packed ));
+
+/** RNDIS query OID message */
+#define RNDIS_QUERY_MSG 0x00000004UL
+
+/** RNDIS set OID message */
+#define RNDIS_SET_MSG 0x00000005UL
+
+/** RNDIS query or set OID message */
+struct rndis_oid_message {
+ /** Request ID */
+ uint32_t id;
+ /** Object ID */
+ uint32_t oid;
+ /** Information buffer length */
+ uint32_t len;
+ /** Information buffer offset */
+ uint32_t offset;
+ /** Reserved */
+ uint32_t reserved;
+} __attribute__ (( packed ));
+
+/** RNDIS query OID completion */
+#define RNDIS_QUERY_CMPLT 0x80000004UL
+
+/** RNDIS query OID completion */
+struct rndis_query_completion {
+ /** Request ID */
+ uint32_t id;
+ /** Status */
+ uint32_t status;
+ /** Information buffer length */
+ uint32_t len;
+ /** Information buffer offset */
+ uint32_t offset;
+} __attribute__ (( packed ));
+
+/** RNDIS set OID completion */
+#define RNDIS_SET_CMPLT 0x80000005UL
+
+/** RNDIS set OID completion */
+struct rndis_set_completion {
+ /** Request ID */
+ uint32_t id;
+ /** Status */
+ uint32_t status;
+} __attribute__ (( packed ));
+
+/** RNDIS reset message */
+#define RNDIS_RESET_MSG 0x00000006UL
+
+/** RNDIS reset message */
+struct rndis_reset_message {
+ /** Reserved */
+ uint32_t reserved;
+} __attribute__ (( packed ));
+
+/** RNDIS reset completion */
+#define RNDIS_RESET_CMPLT 0x80000006UL
+
+/** RNDIS reset completion */
+struct rndis_reset_completion {
+ /** Status */
+ uint32_t status;
+ /** Addressing reset */
+ uint32_t addr;
+} __attribute__ (( packed ));
+
+/** RNDIS indicate status message */
+#define RNDIS_INDICATE_STATUS_MSG 0x00000007UL
+
+/** RNDIS diagnostic information */
+struct rndis_diagnostic_info {
+ /** Status */
+ uint32_t status;
+ /** Error offset */
+ uint32_t offset;
+} __attribute__ (( packed ));
+
+/** RNDIS indicate status message */
+struct rndis_indicate_status_message {
+ /** Status */
+ uint32_t status;
+ /** Status buffer length */
+ uint32_t len;
+ /** Status buffer offset */
+ uint32_t offset;
+ /** Diagnostic information (optional) */
+ struct rndis_diagnostic_info diag[0];
+} __attribute__ (( packed ));
+
+/** RNDIS status codes */
+enum rndis_status {
+ /** Device is connected to a network medium */
+ RNDIS_STATUS_MEDIA_CONNECT = 0x4001000bUL,
+ /** Device is disconnected from the medium */
+ RNDIS_STATUS_MEDIA_DISCONNECT = 0x4001000cUL,
+ /** Unknown start-of-day status code */
+ RNDIS_STATUS_WTF_WORLD = 0x40020006UL,
+};
+
+/** RNDIS keepalive message */
+#define RNDIS_KEEPALIVE_MSG 0x00000008UL
+
+/** RNDIS keepalive message */
+struct rndis_keepalive_message {
+ /** Request ID */
+ uint32_t id;
+} __attribute__ (( packed ));
+
+/** RNDIS keepalive completion */
+#define RNDIS_KEEPALIVE_CMPLT 0x80000008UL
+
+/** RNDIS keepalive completion */
+struct rndis_keepalive_completion {
+ /** Request ID */
+ uint32_t id;
+ /** Status */
+ uint32_t status;
+} __attribute__ (( packed ));
+
+/** RNDIS packet message */
+#define RNDIS_PACKET_MSG 0x00000001UL
+
+/** RNDIS packet field */
+struct rndis_packet_field {
+ /** Offset */
+ uint32_t offset;
+ /** Length */
+ uint32_t len;
+} __attribute__ (( packed ));
+
+/** RNDIS packet message */
+struct rndis_packet_message {
+ /** Data */
+ struct rndis_packet_field data;
+ /** Out-of-band data records */
+ struct rndis_packet_field oob;
+ /** Number of out-of-band data records */
+ uint32_t oob_count;
+ /** Per-packet information record */
+ struct rndis_packet_field ppi;
+ /** Reserved */
+ uint32_t reserved;
+} __attribute__ (( packed ));
+
+/** RNDIS packet record */
+struct rndis_packet_record {
+ /** Length */
+ uint32_t len;
+ /** Type */
+ uint32_t type;
+ /** Offset */
+ uint32_t offset;
+} __attribute__ (( packed ));
+
+/** OID for packet filter */
+#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER 0x0001010eUL
+
+/** Packet filter bits */
+enum rndis_packet_filter {
+ /** Unicast packets */
+ RNDIS_FILTER_UNICAST = 0x00000001UL,
+ /** Multicast packets */
+ RNDIS_FILTER_MULTICAST = 0x00000002UL,
+ /** All multicast packets */
+ RNDIS_FILTER_ALL_MULTICAST = 0x00000004UL,
+ /** Broadcast packets */
+ RNDIS_FILTER_BROADCAST = 0x00000008UL,
+ /** All packets */
+ RNDIS_FILTER_PROMISCUOUS = 0x00000020UL
+};
+
+/** OID for media status */
+#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
+
+/** OID for permanent MAC address */
+#define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101UL
+
+/** OID for current MAC address */
+#define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102UL
+
+struct rndis_device;
+
+/** RNDIS device operations */
+struct rndis_operations {
+ /**
+ * Open RNDIS device
+ *
+ * @v rndis RNDIS device
+ * @ret rc Return status code
+ */
+ int ( * open ) ( struct rndis_device *rndis );
+ /**
+ * Close RNDIS device
+ *
+ * @v rndis RNDIS device
+ */
+ void ( * close ) ( struct rndis_device *rndis );
+ /**
+ * Transmit packet
+ *
+ * @v rndis RNDIS device
+ * @v iobuf I/O buffer
+ * @ret rc Return status code
+ *
+ * If this method returns success then the RNDIS device must
+ * eventually report completion via rndis_tx_complete().
+ */
+ int ( * transmit ) ( struct rndis_device *rndis,
+ struct io_buffer *iobuf );
+ /**
+ * Poll for completed and received packets
+ *
+ * @v rndis RNDIS device
+ */
+ void ( * poll ) ( struct rndis_device *rndis );
+};
+
+/** An RNDIS device */
+struct rndis_device {
+ /** Network device */
+ struct net_device *netdev;
+ /** Device name */
+ const char *name;
+ /** RNDIS operations */
+ struct rndis_operations *op;
+ /** Driver private data */
+ void *priv;
+
+ /** Request ID for current blocking request */
+ unsigned int wait_id;
+ /** Return status code for current blocking request */
+ int wait_rc;
+};
+
+/**
+ * Initialise an RNDIS device
+ *
+ * @v rndis RNDIS device
+ * @v op RNDIS device operations
+ */
+static inline void rndis_init ( struct rndis_device *rndis,
+ struct rndis_operations *op ) {
+
+ rndis->op = op;
+}
+
+extern void rndis_tx_complete_err ( struct rndis_device *rndis,
+ struct io_buffer *iobuf, int rc );
+extern int rndis_tx_defer ( struct rndis_device *rndis,
+ struct io_buffer *iobuf );
+extern void rndis_rx ( struct rndis_device *rndis, struct io_buffer *iobuf );
+extern void rndis_rx_err ( struct rndis_device *rndis, struct io_buffer *iobuf,
+ int rc );
+
+extern struct rndis_device * alloc_rndis ( size_t priv_len );
+extern int register_rndis ( struct rndis_device *rndis );
+extern void unregister_rndis ( struct rndis_device *rndis );
+extern void free_rndis ( struct rndis_device *rndis );
+
+/**
+ * Complete message transmission
+ *
+ * @v rndis RNDIS device
+ * @v iobuf I/O buffer
+ */
+static inline void rndis_tx_complete ( struct rndis_device *rndis,
+ struct io_buffer *iobuf ) {
+
+ rndis_tx_complete_err ( rndis, iobuf, 0 );
+}
+
+#endif /* _IPXE_RNDIS_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/rootcert.h b/qemu/roms/ipxe/src/include/ipxe/rootcert.h
index 6525df87a..d4be2e1bc 100644
--- a/qemu/roms/ipxe/src/include/ipxe/rootcert.h
+++ b/qemu/roms/ipxe/src/include/ipxe/rootcert.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/x509.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/rotate.h b/qemu/roms/ipxe/src/include/ipxe/rotate.h
index ba271ca74..b5693e3ca 100644
--- a/qemu/roms/ipxe/src/include/ipxe/rotate.h
+++ b/qemu/roms/ipxe/src/include/ipxe/rotate.h
@@ -6,10 +6,30 @@
* Bit operations
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
+static inline __attribute__ (( always_inline )) uint8_t
+rol8 ( uint8_t data, unsigned int rotation ) {
+ return ( ( data << rotation ) | ( data >> ( 8 - rotation ) ) );
+}
+
+static inline __attribute__ (( always_inline )) uint8_t
+ror8 ( uint8_t data, unsigned int rotation ) {
+ return ( ( data >> rotation ) | ( data << ( 8 - rotation ) ) );
+}
+
+static inline __attribute__ (( always_inline )) uint16_t
+rol16 ( uint16_t data, unsigned int rotation ) {
+ return ( ( data << rotation ) | ( data >> ( 16 - rotation ) ) );
+}
+
+static inline __attribute__ (( always_inline )) uint16_t
+ror16 ( uint16_t data, unsigned int rotation ) {
+ return ( ( data >> rotation ) | ( data << ( 16 - rotation ) ) );
+}
+
static inline __attribute__ (( always_inline )) uint32_t
rol32 ( uint32_t data, unsigned int rotation ) {
return ( ( data << rotation ) | ( data >> ( 32 - rotation ) ) );
diff --git a/qemu/roms/ipxe/src/include/ipxe/rsa.h b/qemu/roms/ipxe/src/include/ipxe/rsa.h
index 1a5ad8bab..d947eec73 100644
--- a/qemu/roms/ipxe/src/include/ipxe/rsa.h
+++ b/qemu/roms/ipxe/src/include/ipxe/rsa.h
@@ -6,8 +6,9 @@
* RSA public-key cryptography
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+#include <stdarg.h>
#include <ipxe/crypto.h>
#include <ipxe/bigint.h>
#include <ipxe/asn1.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/sanboot.h b/qemu/roms/ipxe/src/include/ipxe/sanboot.h
index 14c8a5da4..57025f2c6 100644
--- a/qemu/roms/ipxe/src/include/ipxe/sanboot.h
+++ b/qemu/roms/ipxe/src/include/ipxe/sanboot.h
@@ -16,7 +16,7 @@
* the address parameter.
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/api.h>
#include <config/sanboot.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/script.h b/qemu/roms/ipxe/src/include/ipxe/script.h
index 33420dae4..7e7a9a3a4 100644
--- a/qemu/roms/ipxe/src/include/ipxe/script.h
+++ b/qemu/roms/ipxe/src/include/ipxe/script.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/image.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/scsi.h b/qemu/roms/ipxe/src/include/ipxe/scsi.h
index 4428daac3..28b55b2d5 100644
--- a/qemu/roms/ipxe/src/include/ipxe/scsi.h
+++ b/qemu/roms/ipxe/src/include/ipxe/scsi.h
@@ -11,7 +11,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Maximum block for READ/WRITE (10) commands */
#define SCSI_MAX_BLOCK_10 0xffffffffULL
diff --git a/qemu/roms/ipxe/src/include/ipxe/segment.h b/qemu/roms/ipxe/src/include/ipxe/segment.h
index 37bed0e19..9d5ecbd9b 100644
--- a/qemu/roms/ipxe/src/include/ipxe/segment.h
+++ b/qemu/roms/ipxe/src/include/ipxe/segment.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/uaccess.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/serial.h b/qemu/roms/ipxe/src/include/ipxe/serial.h
index b47b1d125..83be59c31 100644
--- a/qemu/roms/ipxe/src/include/ipxe/serial.h
+++ b/qemu/roms/ipxe/src/include/ipxe/serial.h
@@ -3,15 +3,14 @@
/** @file
*
- * Serial driver functions
+ * Serial console
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-extern void serial_putc ( int ch );
-extern int serial_getc ( void );
-extern int serial_ischar ( void );
-extern int serial_initialized;
+#include <ipxe/uart.h>
+
+extern struct uart serial_console;
#endif /* _IPXE_SERIAL_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/settings.h b/qemu/roms/ipxe/src/include/ipxe/settings.h
index d6929ecd0..95a553cc8 100644
--- a/qemu/roms/ipxe/src/include/ipxe/settings.h
+++ b/qemu/roms/ipxe/src/include/ipxe/settings.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/tables.h>
@@ -415,6 +415,7 @@ extern const struct setting_type setting_type_uint32 __setting_type;
extern const struct setting_type setting_type_hex __setting_type;
extern const struct setting_type setting_type_hexhyp __setting_type;
extern const struct setting_type setting_type_hexraw __setting_type;
+extern const struct setting_type setting_type_base64 __setting_type;
extern const struct setting_type setting_type_uuid __setting_type;
extern const struct setting_type setting_type_busdevfn __setting_type;
extern const struct setting_type setting_type_dnssl __setting_type;
diff --git a/qemu/roms/ipxe/src/include/ipxe/settings_ui.h b/qemu/roms/ipxe/src/include/ipxe/settings_ui.h
index 5f7be30cc..0bf21935d 100644
--- a/qemu/roms/ipxe/src/include/ipxe/settings_ui.h
+++ b/qemu/roms/ipxe/src/include/ipxe/settings_ui.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct settings;
diff --git a/qemu/roms/ipxe/src/include/ipxe/sha256.h b/qemu/roms/ipxe/src/include/ipxe/sha256.h
index 9aa9f3e57..e234cce33 100644
--- a/qemu/roms/ipxe/src/include/ipxe/sha256.h
+++ b/qemu/roms/ipxe/src/include/ipxe/sha256.h
@@ -7,11 +7,14 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/crypto.h>
+/** SHA-256 number of rounds */
+#define SHA256_ROUNDS 64
+
/** An SHA-256 digest */
struct sha256_digest {
/** Hash output */
@@ -58,6 +61,8 @@ union sha256_digest_data_dwords {
struct sha256_context {
/** Amount of accumulated data */
size_t len;
+ /** Digest size */
+ size_t digestsize;
/** Digest and accumulated data */
union sha256_digest_data_dwords ddd;
} __attribute__ (( packed ));
@@ -68,6 +73,16 @@ struct sha256_context {
/** SHA-256 digest size */
#define SHA256_DIGEST_SIZE sizeof ( struct sha256_digest )
+/** SHA-224 digest size */
+#define SHA224_DIGEST_SIZE ( SHA256_DIGEST_SIZE * 224 / 256 )
+
+extern void sha256_family_init ( struct sha256_context *context,
+ const struct sha256_digest *init,
+ size_t digestsize );
+extern void sha256_update ( void *ctx, const void *data, size_t len );
+extern void sha256_final ( void *ctx, void *out );
+
extern struct digest_algorithm sha256_algorithm;
+extern struct digest_algorithm sha224_algorithm;
#endif /* _IPXE_SHA256_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/sha512.h b/qemu/roms/ipxe/src/include/ipxe/sha512.h
new file mode 100644
index 000000000..8e22d8357
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/sha512.h
@@ -0,0 +1,98 @@
+#ifndef _IPXE_SHA512_H
+#define _IPXE_SHA512_H
+
+/** @file
+ *
+ * SHA-512 algorithm
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/crypto.h>
+
+/** SHA-512 number of rounds */
+#define SHA512_ROUNDS 80
+
+/** An SHA-512 digest */
+struct sha512_digest {
+ /** Hash output */
+ uint64_t h[8];
+};
+
+/** An SHA-512 data block */
+union sha512_block {
+ /** Raw bytes */
+ uint8_t byte[128];
+ /** Raw qwords */
+ uint64_t qword[16];
+ /** Final block structure */
+ struct {
+ /** Padding */
+ uint8_t pad[112];
+ /** High 64 bits of length in bits */
+ uint64_t len_hi;
+ /** Low 64 bits of length in bits */
+ uint64_t len_lo;
+ } final;
+};
+
+/** SHA-512 digest and data block
+ *
+ * The order of fields within this structure is designed to minimise
+ * code size.
+ */
+struct sha512_digest_data {
+ /** Digest of data already processed */
+ struct sha512_digest digest;
+ /** Accumulated data */
+ union sha512_block data;
+} __attribute__ (( packed ));
+
+/** SHA-512 digest and data block */
+union sha512_digest_data_qwords {
+ /** Digest and data block */
+ struct sha512_digest_data dd;
+ /** Raw qwords */
+ uint64_t qword[ sizeof ( struct sha512_digest_data ) /
+ sizeof ( uint64_t ) ];
+};
+
+/** An SHA-512 context */
+struct sha512_context {
+ /** Amount of accumulated data */
+ size_t len;
+ /** Digest size */
+ size_t digestsize;
+ /** Digest and accumulated data */
+ union sha512_digest_data_qwords ddq;
+} __attribute__ (( packed ));
+
+/** SHA-512 context size */
+#define SHA512_CTX_SIZE sizeof ( struct sha512_context )
+
+/** SHA-512 digest size */
+#define SHA512_DIGEST_SIZE sizeof ( struct sha512_digest )
+
+/** SHA-384 digest size */
+#define SHA384_DIGEST_SIZE ( SHA512_DIGEST_SIZE * 384 / 512 )
+
+/** SHA-512/256 digest size */
+#define SHA512_256_DIGEST_SIZE ( SHA512_DIGEST_SIZE * 256 / 512 )
+
+/** SHA-512/224 digest size */
+#define SHA512_224_DIGEST_SIZE ( SHA512_DIGEST_SIZE * 224 / 512 )
+
+extern void sha512_family_init ( struct sha512_context *context,
+ const struct sha512_digest *init,
+ size_t digestsize );
+extern void sha512_update ( void *ctx, const void *data, size_t len );
+extern void sha512_final ( void *ctx, void *out );
+
+extern struct digest_algorithm sha512_algorithm;
+extern struct digest_algorithm sha384_algorithm;
+extern struct digest_algorithm sha512_256_algorithm;
+extern struct digest_algorithm sha512_224_algorithm;
+
+#endif /* IPXE_SHA512_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/shell.h b/qemu/roms/ipxe/src/include/ipxe/shell.h
index faa32f422..0d574e028 100644
--- a/qemu/roms/ipxe/src/include/ipxe/shell.h
+++ b/qemu/roms/ipxe/src/include/ipxe/shell.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Shell stop states */
enum shell_stop_state {
diff --git a/qemu/roms/ipxe/src/include/ipxe/smbios.h b/qemu/roms/ipxe/src/include/ipxe/smbios.h
index ef5892a21..24b05ed62 100644
--- a/qemu/roms/ipxe/src/include/ipxe/smbios.h
+++ b/qemu/roms/ipxe/src/include/ipxe/smbios.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/api.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/socket.h b/qemu/roms/ipxe/src/include/ipxe/socket.h
index 7cb3912f4..8c70ea4c0 100644
--- a/qemu/roms/ipxe/src/include/ipxe/socket.h
+++ b/qemu/roms/ipxe/src/include/ipxe/socket.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/tables.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/spi.h b/qemu/roms/ipxe/src/include/ipxe/spi.h
index d92d1aec9..83b53bce3 100644
--- a/qemu/roms/ipxe/src/include/ipxe/spi.h
+++ b/qemu/roms/ipxe/src/include/ipxe/spi.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/nvs.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/spi_bit.h b/qemu/roms/ipxe/src/include/ipxe/spi_bit.h
index 9cfa7b825..049d30a22 100644
--- a/qemu/roms/ipxe/src/include/ipxe/spi_bit.h
+++ b/qemu/roms/ipxe/src/include/ipxe/spi_bit.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/spi.h>
#include <ipxe/bitbash.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/stp.h b/qemu/roms/ipxe/src/include/ipxe/stp.h
new file mode 100644
index 000000000..3d85e5ba4
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/stp.h
@@ -0,0 +1,76 @@
+#ifndef _IPXE_STP_H
+#define _IPXE_STP_H
+
+/** @file
+ *
+ * Spanning Tree Protocol (STP)
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/if_ether.h>
+
+/** "Protocol" value for STP
+ *
+ * This is the concatenated {DSAP,SSAP} value used internally by iPXE
+ * as the network-layer protocol for LLC frames.
+ */
+#define ETH_P_STP 0x4242
+
+/** A switch identifier */
+struct stp_switch {
+ /** Priotity */
+ uint16_t priority;
+ /** MAC address */
+ uint8_t mac[ETH_ALEN];
+} __attribute__ (( packed ));
+
+/** A Spanning Tree bridge protocol data unit */
+struct stp_bpdu {
+ /** LLC DSAP */
+ uint8_t dsap;
+ /** LLC SSAP */
+ uint8_t ssap;
+ /** LLC control field */
+ uint8_t control;
+ /** Protocol ID */
+ uint16_t protocol;
+ /** Protocol version */
+ uint8_t version;
+ /** Message type */
+ uint8_t type;
+ /** Flags */
+ uint8_t flags;
+ /** Root switch */
+ struct stp_switch root;
+ /** Root path cost */
+ uint32_t cost;
+ /** Sender switch */
+ struct stp_switch sender;
+ /** Port */
+ uint16_t port;
+ /** Message age */
+ uint16_t age;
+ /** Maximum age */
+ uint16_t max;
+ /** Hello time */
+ uint16_t hello;
+ /** Forward delay */
+ uint16_t delay;
+} __attribute__ (( packed ));
+
+/** Spanning Tree protocol ID */
+#define STP_PROTOCOL 0x0000
+
+/** Rapid Spanning Tree protocol version */
+#define STP_VERSION_RSTP 0x02
+
+/** Rapid Spanning Tree bridge PDU type */
+#define STP_TYPE_RSTP 0x02
+
+/** Port is forwarding */
+#define STP_FL_FORWARDING 0x20
+
+#endif /* _IPXE_STP_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/string.h b/qemu/roms/ipxe/src/include/ipxe/string.h
new file mode 100644
index 000000000..a8cbe8faa
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/string.h
@@ -0,0 +1,14 @@
+#ifndef _IPXE_STRING_H
+#define _IPXE_STRING_H
+
+/** @file
+ *
+ * String functions
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+extern unsigned int digit_value ( unsigned int digit );
+
+#endif /* _IPXE_STRING_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/syslog.h b/qemu/roms/ipxe/src/include/ipxe/syslog.h
index 131692654..138440d66 100644
--- a/qemu/roms/ipxe/src/include/ipxe/syslog.h
+++ b/qemu/roms/ipxe/src/include/ipxe/syslog.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <syslog.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/tables.h b/qemu/roms/ipxe/src/include/ipxe/tables.h
index e35ce8220..60f8efdea 100644
--- a/qemu/roms/ipxe/src/include/ipxe/tables.h
+++ b/qemu/roms/ipxe/src/include/ipxe/tables.h
@@ -1,7 +1,7 @@
#ifndef _IPXE_TABLES_H
#define _IPXE_TABLES_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @page ifdef_harmful #ifdef considered harmful
*
diff --git a/qemu/roms/ipxe/src/include/ipxe/tcp.h b/qemu/roms/ipxe/src/include/ipxe/tcp.h
index 9baa6391c..063ebaa4b 100644
--- a/qemu/roms/ipxe/src/include/ipxe/tcp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/tcp.h
@@ -9,7 +9,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/tcpip.h>
@@ -79,6 +79,48 @@ struct tcp_window_scale_padded_option {
*/
#define TCP_RX_WINDOW_SCALE 9
+/** TCP selective acknowledgement permitted option */
+struct tcp_sack_permitted_option {
+ uint8_t kind;
+ uint8_t length;
+} __attribute__ (( packed ));
+
+/** Padded TCP selective acknowledgement permitted option (used for sending) */
+struct tcp_sack_permitted_padded_option {
+ uint8_t nop[2];
+ struct tcp_sack_permitted_option spopt;
+} __attribute__ (( packed ));
+
+/** Code for the TCP selective acknowledgement permitted option */
+#define TCP_OPTION_SACK_PERMITTED 4
+
+/** TCP selective acknowledgement option */
+struct tcp_sack_option {
+ uint8_t kind;
+ uint8_t length;
+} __attribute__ (( packed ));
+
+/** TCP selective acknowledgement block */
+struct tcp_sack_block {
+ uint32_t left;
+ uint32_t right;
+} __attribute__ (( packed ));
+
+/** Maximum number of selective acknowledgement blocks
+ *
+ * This allows for the presence of the TCP timestamp option.
+ */
+#define TCP_SACK_MAX 3
+
+/** Padded TCP selective acknowledgement option (used for sending) */
+struct tcp_sack_padded_option {
+ uint8_t nop[2];
+ struct tcp_sack_option sackopt;
+} __attribute__ (( packed ));
+
+/** Code for the TCP selective acknowledgement option */
+#define TCP_OPTION_SACK 5
+
/** TCP timestamp option */
struct tcp_timestamp_option {
uint8_t kind;
@@ -102,6 +144,8 @@ struct tcp_options {
const struct tcp_mss_option *mssopt;
/** Window scale option, if present */
const struct tcp_window_scale_option *wsopt;
+ /** SACK permitted option, if present */
+ const struct tcp_sack_permitted_option *spopt;
/** Timestamp option, if present */
const struct tcp_timestamp_option *tsopt;
};
@@ -376,6 +420,13 @@ static inline int tcp_in_window ( uint32_t seq, uint32_t start,
return ( ( seq - start ) < len );
}
+/** TCP finish wait time
+ *
+ * Currently set to one second, since we should not allow a slowly
+ * responding server to substantially delay a call to shutdown().
+ */
+#define TCP_FINISH_TIMEOUT ( 1 * TICKS_PER_SEC )
+
extern struct tcpip_protocol tcp_protocol __tcpip_protocol;
#endif /* _IPXE_TCP_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/tcpip.h b/qemu/roms/ipxe/src/include/ipxe/tcpip.h
index 200630d6b..3cfc8e3ac 100644
--- a/qemu/roms/ipxe/src/include/ipxe/tcpip.h
+++ b/qemu/roms/ipxe/src/include/ipxe/tcpip.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/socket.h>
@@ -48,6 +48,12 @@ struct sockaddr_tcpip {
uint16_t st_flags;
/** TCP/IP port */
uint16_t st_port;
+ /** Scope ID
+ *
+ * For link-local or multicast addresses, this is the network
+ * device index.
+ */
+ uint16_t st_scope_id;
/** Padding
*
* This ensures that a struct @c sockaddr_tcpip is large
@@ -57,7 +63,8 @@ struct sockaddr_tcpip {
char pad[ sizeof ( struct sockaddr ) -
( sizeof ( sa_family_t ) /* st_family */ +
sizeof ( uint16_t ) /* st_flags */ +
- sizeof ( uint16_t ) /* st_port */ ) ];
+ sizeof ( uint16_t ) /* st_port */ +
+ sizeof ( uint16_t ) /* st_scope_id */ ) ];
} __attribute__ (( packed, may_alias ));
/**
diff --git a/qemu/roms/ipxe/src/include/ipxe/test.h b/qemu/roms/ipxe/src/include/ipxe/test.h
index 028ee29fb..0b65c299c 100644
--- a/qemu/roms/ipxe/src/include/ipxe/test.h
+++ b/qemu/roms/ipxe/src/include/ipxe/test.h
@@ -1,7 +1,7 @@
#ifndef _IPXE_TEST_H
#define _IPXE_TEST_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
diff --git a/qemu/roms/ipxe/src/include/ipxe/tftp.h b/qemu/roms/ipxe/src/include/ipxe/tftp.h
index aecafa2ae..e3661e1ac 100644
--- a/qemu/roms/ipxe/src/include/ipxe/tftp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/tftp.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/time.h b/qemu/roms/ipxe/src/include/ipxe/time.h
index 673fe098a..4c5bb2a00 100644
--- a/qemu/roms/ipxe/src/include/ipxe/time.h
+++ b/qemu/roms/ipxe/src/include/ipxe/time.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <sys/time.h>
#include <ipxe/api.h>
@@ -44,6 +44,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
/* Include all architecture-independent time API headers */
#include <ipxe/null_time.h>
+#include <ipxe/efi/efi_time.h>
#include <ipxe/linux/linux_time.h>
/* Include all architecture-dependent time API headers */
diff --git a/qemu/roms/ipxe/src/include/ipxe/timer.h b/qemu/roms/ipxe/src/include/ipxe/timer.h
index d0309655d..82fbb6764 100644
--- a/qemu/roms/ipxe/src/include/ipxe/timer.h
+++ b/qemu/roms/ipxe/src/include/ipxe/timer.h
@@ -9,7 +9,7 @@
* for a monotonically increasing tick counter.
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/api.h>
#include <config/timer.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/tls.h b/qemu/roms/ipxe/src/include/ipxe/tls.h
index 586da26ec..7d982c326 100644
--- a/qemu/roms/ipxe/src/include/ipxe/tls.h
+++ b/qemu/roms/ipxe/src/include/ipxe/tls.h
@@ -7,7 +7,7 @@
* Transport Layer Security Protocol
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/refcnt.h>
@@ -20,6 +20,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/x509.h>
#include <ipxe/pending.h>
#include <ipxe/iobuf.h>
+#include <ipxe/tables.h>
/** A TLS header */
struct tls_header {
@@ -85,7 +86,10 @@ struct tls_header {
/* TLS hash algorithm identifiers */
#define TLS_MD5_ALGORITHM 1
#define TLS_SHA1_ALGORITHM 2
+#define TLS_SHA224_ALGORITHM 3
#define TLS_SHA256_ALGORITHM 4
+#define TLS_SHA384_ALGORITHM 5
+#define TLS_SHA512_ALGORITHM 6
/* TLS signature algorithm identifiers */
#define TLS_RSA_ALGORITHM 1
@@ -101,6 +105,9 @@ struct tls_header {
#define TLS_MAX_FRAGMENT_LENGTH_2048 3
#define TLS_MAX_FRAGMENT_LENGTH_4096 4
+/* TLS signature algorithms extension */
+#define TLS_SIGNATURE_ALGORITHMS 13
+
/** TLS RX state machine state */
enum tls_rx_state {
TLS_RX_HEADER = 0,
@@ -131,6 +138,14 @@ struct tls_cipher_suite {
uint16_t code;
};
+/** TLS cipher suite table */
+#define TLS_CIPHER_SUITES \
+ __table ( struct tls_cipher_suite, "tls_cipher_suites" )
+
+/** Declare a TLS cipher suite */
+#define __tls_cipher_suite( pref ) \
+ __table_entry ( TLS_CIPHER_SUITES, pref )
+
/** A TLS cipher specification */
struct tls_cipherspec {
/** Cipher suite */
@@ -165,6 +180,19 @@ struct tls_signature_hash_algorithm {
struct tls_signature_hash_id code;
};
+/** TLS signature hash algorithm table
+ *
+ * Note that the default (TLSv1.1 and earlier) algorithm using
+ * MD5+SHA1 is never explicitly specified.
+ */
+#define TLS_SIG_HASH_ALGORITHMS \
+ __table ( struct tls_signature_hash_algorithm, \
+ "tls_sig_hash_algorithms" )
+
+/** Declare a TLS signature hash algorithm */
+#define __tls_sig_hash_algorithm \
+ __table_entry ( TLS_SIG_HASH_ALGORITHMS, 01 )
+
/** TLS pre-master secret */
struct tls_pre_master_secret {
/** TLS version */
diff --git a/qemu/roms/ipxe/src/include/ipxe/uaccess.h b/qemu/roms/ipxe/src/include/ipxe/uaccess.h
index 055bb2ca7..a3f78566a 100644
--- a/qemu/roms/ipxe/src/include/ipxe/uaccess.h
+++ b/qemu/roms/ipxe/src/include/ipxe/uaccess.h
@@ -19,7 +19,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/uart.h b/qemu/roms/ipxe/src/include/ipxe/uart.h
new file mode 100644
index 000000000..c63eae615
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/uart.h
@@ -0,0 +1,132 @@
+#ifndef _IPXE_UART_H
+#define _IPXE_UART_H
+
+/** @file
+ *
+ * 16550-compatible UART
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+
+/** Transmitter holding register */
+#define UART_THR 0x00
+
+/** Receiver buffer register */
+#define UART_RBR 0x00
+
+/** Interrupt enable register */
+#define UART_IER 0x01
+
+/** FIFO control register */
+#define UART_FCR 0x02
+#define UART_FCR_FE 0x01 /**< FIFO enable */
+
+/** Line control register */
+#define UART_LCR 0x03
+#define UART_LCR_WLS0 0x01 /**< Word length select bit 0 */
+#define UART_LCR_WLS1 0x02 /**< Word length select bit 1 */
+#define UART_LCR_STB 0x04 /**< Number of stop bits */
+#define UART_LCR_PEN 0x08 /**< Parity enable */
+#define UART_LCR_EPS 0x10 /**< Even parity select */
+#define UART_LCR_DLAB 0x80 /**< Divisor latch access bit */
+
+#define UART_LCR_WORD_LEN(x) ( ( (x) - 5 ) << 0 ) /**< Word length */
+#define UART_LCR_STOP_BITS(x) ( ( (x) - 1 ) << 2 ) /**< Stop bits */
+#define UART_LCR_PARITY(x) ( ( (x) - 0 ) << 3 ) /**< Parity */
+
+/**
+ * Calculate line control register value
+ *
+ * @v word_len Word length (5-8)
+ * @v parity Parity (0=none, 1=odd, 3=even)
+ * @v stop_bits Stop bits (1-2)
+ * @ret lcr Line control register value
+ */
+#define UART_LCR_WPS( word_len, parity, stop_bits ) \
+ ( UART_LCR_WORD_LEN ( (word_len) ) | \
+ UART_LCR_PARITY ( (parity) ) | \
+ UART_LCR_STOP_BITS ( (stop_bits) ) )
+
+/** Default LCR value: 8 data bits, no parity, one stop bit */
+#define UART_LCR_8N1 UART_LCR_WPS ( 8, 0, 1 )
+
+/** Modem control register */
+#define UART_MCR 0x04
+#define UART_MCR_DTR 0x01 /**< Data terminal ready */
+#define UART_MCR_RTS 0x02 /**< Request to send */
+
+/** Line status register */
+#define UART_LSR 0x05
+#define UART_LSR_DR 0x01 /**< Data ready */
+#define UART_LSR_THRE 0x20 /**< Transmitter holding register empty */
+#define UART_LSR_TEMT 0x40 /**< Transmitter empty */
+
+/** Scratch register */
+#define UART_SCR 0x07
+
+/** Divisor latch (least significant byte) */
+#define UART_DLL 0x00
+
+/** Divisor latch (most significant byte) */
+#define UART_DLM 0x01
+
+/** Maximum baud rate */
+#define UART_MAX_BAUD 115200
+
+/** A 16550-compatible UART */
+struct uart {
+ /** I/O port base address */
+ void *base;
+ /** Baud rate divisor */
+ uint16_t divisor;
+ /** Line control register */
+ uint8_t lcr;
+};
+
+/** Symbolic names for port indexes */
+enum uart_port {
+ COM1 = 1,
+ COM2 = 2,
+ COM3 = 3,
+ COM4 = 4,
+};
+
+#include <bits/uart.h>
+
+void uart_write ( struct uart *uart, unsigned int addr, uint8_t data );
+uint8_t uart_read ( struct uart *uart, unsigned int addr );
+int uart_select ( struct uart *uart, unsigned int port );
+
+/**
+ * Check if received data is ready
+ *
+ * @v uart UART
+ * @ret ready Data is ready
+ */
+static inline int uart_data_ready ( struct uart *uart ) {
+ uint8_t lsr;
+
+ lsr = uart_read ( uart, UART_LSR );
+ return ( lsr & UART_LSR_DR );
+}
+
+/**
+ * Receive data
+ *
+ * @v uart UART
+ * @ret data Data
+ */
+static inline uint8_t uart_receive ( struct uart *uart ) {
+
+ return uart_read ( uart, UART_RBR );
+}
+
+extern void uart_transmit ( struct uart *uart, uint8_t data );
+extern void uart_flush ( struct uart *uart );
+extern int uart_exists ( struct uart *uart );
+extern int uart_init ( struct uart *uart, unsigned int baud, uint8_t lcr );
+
+#endif /* _IPXE_UART_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/udp.h b/qemu/roms/ipxe/src/include/ipxe/udp.h
index 5717ef213..7b0de4dc0 100644
--- a/qemu/roms/ipxe/src/include/ipxe/udp.h
+++ b/qemu/roms/ipxe/src/include/ipxe/udp.h
@@ -9,7 +9,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <ipxe/iobuf.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/umalloc.h b/qemu/roms/ipxe/src/include/ipxe/umalloc.h
index 4b25e182a..3892ef53b 100644
--- a/qemu/roms/ipxe/src/include/ipxe/umalloc.h
+++ b/qemu/roms/ipxe/src/include/ipxe/umalloc.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/api.h>
#include <config/umalloc.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/uri.h b/qemu/roms/ipxe/src/include/ipxe/uri.h
index 7613d578d..00e5a24c4 100644
--- a/qemu/roms/ipxe/src/include/ipxe/uri.h
+++ b/qemu/roms/ipxe/src/include/ipxe/uri.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <stdlib.h>
@@ -203,7 +203,7 @@ extern char * resolve_path ( const char *base_path,
const char *relative_path );
extern struct uri * resolve_uri ( const struct uri *base_uri,
struct uri *relative_uri );
-extern struct uri * tftp_uri ( struct in_addr next_server,
+extern struct uri * tftp_uri ( struct in_addr next_server, unsigned int port,
const char *filename );
extern void churi ( struct uri *uri );
diff --git a/qemu/roms/ipxe/src/include/ipxe/usb.h b/qemu/roms/ipxe/src/include/ipxe/usb.h
new file mode 100644
index 000000000..ab060b8f4
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/usb.h
@@ -0,0 +1,1319 @@
+#ifndef _IPXE_USB_H
+#define _IPXE_USB_H
+
+/** @file
+ *
+ * Universal Serial Bus (USB)
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <byteswap.h>
+#include <ipxe/list.h>
+#include <ipxe/device.h>
+#include <ipxe/process.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/tables.h>
+
+/** USB protocols */
+enum usb_protocol {
+ /** USB 2.0 */
+ USB_PROTO_2_0 = 0x0200,
+ /** USB 3.0 */
+ USB_PROTO_3_0 = 0x0300,
+ /** USB 3.1 */
+ USB_PROTO_3_1 = 0x0301,
+};
+
+/** Define a USB speed
+ *
+ * @v mantissa Mantissa
+ * @v exponent Exponent (in engineering terms: 1=k, 2=M, 3=G)
+ * @ret speed USB speed
+ */
+#define USB_SPEED( mantissa, exponent ) ( (exponent << 16) | (mantissa) )
+
+/** Extract USB speed mantissa */
+#define USB_SPEED_MANTISSA(speed) ( (speed) & 0xffff )
+
+/** Extract USB speed exponent */
+#define USB_SPEED_EXPONENT(speed) ( ( (speed) >> 16 ) & 0x3 )
+
+/** USB device speeds */
+enum usb_speed {
+ /** Not connected */
+ USB_SPEED_NONE = 0,
+ /** Low speed (1.5Mbps) */
+ USB_SPEED_LOW = USB_SPEED ( 1500, 1 ),
+ /** Full speed (12Mbps) */
+ USB_SPEED_FULL = USB_SPEED ( 12, 2 ),
+ /** High speed (480Mbps) */
+ USB_SPEED_HIGH = USB_SPEED ( 480, 2 ),
+ /** Super speed (5Gbps) */
+ USB_SPEED_SUPER = USB_SPEED ( 5, 3 ),
+};
+
+/** USB packet IDs */
+enum usb_pid {
+ /** IN PID */
+ USB_PID_IN = 0x69,
+ /** OUT PID */
+ USB_PID_OUT = 0xe1,
+ /** SETUP PID */
+ USB_PID_SETUP = 0x2d,
+};
+
+/** A USB setup data packet */
+struct usb_setup_packet {
+ /** Request */
+ uint16_t request;
+ /** Value paramer */
+ uint16_t value;
+ /** Index parameter */
+ uint16_t index;
+ /** Length of data stage */
+ uint16_t len;
+} __attribute__ (( packed ));
+
+/** Data transfer is from host to device */
+#define USB_DIR_OUT ( 0 << 7 )
+
+/** Data transfer is from device to host */
+#define USB_DIR_IN ( 1 << 7 )
+
+/** Standard request type */
+#define USB_TYPE_STANDARD ( 0 << 5 )
+
+/** Class-specific request type */
+#define USB_TYPE_CLASS ( 1 << 5 )
+
+/** Vendor-specific request type */
+#define USB_TYPE_VENDOR ( 2 << 5 )
+
+/** Request recipient is the device */
+#define USB_RECIP_DEVICE ( 0 << 0 )
+
+/** Request recipient is an interface */
+#define USB_RECIP_INTERFACE ( 1 << 0 )
+
+/** Request recipient is an endpoint */
+#define USB_RECIP_ENDPOINT ( 2 << 0 )
+
+/** Construct USB request type */
+#define USB_REQUEST_TYPE(type) ( (type) << 8 )
+
+/** Get status */
+#define USB_GET_STATUS ( USB_DIR_IN | USB_REQUEST_TYPE ( 0 ) )
+
+/** Clear feature */
+#define USB_CLEAR_FEATURE ( USB_DIR_OUT | USB_REQUEST_TYPE ( 1 ) )
+
+/** Set feature */
+#define USB_SET_FEATURE ( USB_DIR_OUT | USB_REQUEST_TYPE ( 3 ) )
+
+/** Set address */
+#define USB_SET_ADDRESS ( USB_DIR_OUT | USB_REQUEST_TYPE ( 5 ) )
+
+/** Get descriptor */
+#define USB_GET_DESCRIPTOR ( USB_DIR_IN | USB_REQUEST_TYPE ( 6 ) )
+
+/** Set descriptor */
+#define USB_SET_DESCRIPTOR ( USB_DIR_OUT | USB_REQUEST_TYPE ( 7 ) )
+
+/** Get configuration */
+#define USB_GET_CONFIGURATION ( USB_DIR_IN | USB_REQUEST_TYPE ( 8 ) )
+
+/** Set configuration */
+#define USB_SET_CONFIGURATION ( USB_DIR_OUT | USB_REQUEST_TYPE ( 9 ) )
+
+/** Get interface */
+#define USB_GET_INTERFACE \
+ ( USB_DIR_IN | USB_RECIP_INTERFACE | USB_REQUEST_TYPE ( 10 ) )
+
+/** Set interface */
+#define USB_SET_INTERFACE \
+ ( USB_DIR_OUT | USB_RECIP_INTERFACE | USB_REQUEST_TYPE ( 11 ) )
+
+/** Endpoint halt feature */
+#define USB_ENDPOINT_HALT 0
+
+/** A USB class code tuple */
+struct usb_class {
+ /** Class code */
+ uint8_t class;
+ /** Subclass code */
+ uint8_t subclass;
+ /** Protocol code */
+ uint8_t protocol;
+} __attribute__ (( packed ));
+
+/** Class code for USB hubs */
+#define USB_CLASS_HUB 9
+
+/** A USB descriptor header */
+struct usb_descriptor_header {
+ /** Length of descriptor */
+ uint8_t len;
+ /** Descriptor type */
+ uint8_t type;
+} __attribute__ (( packed ));
+
+/** A USB device descriptor */
+struct usb_device_descriptor {
+ /** Descriptor header */
+ struct usb_descriptor_header header;
+ /** USB specification release number in BCD */
+ uint16_t protocol;
+ /** Device class */
+ struct usb_class class;
+ /** Maximum packet size for endpoint zero */
+ uint8_t mtu;
+ /** Vendor ID */
+ uint16_t vendor;
+ /** Product ID */
+ uint16_t product;
+ /** Device release number in BCD */
+ uint16_t release;
+ /** Manufacturer string */
+ uint8_t manufacturer;
+ /** Product string */
+ uint8_t name;
+ /** Serial number string */
+ uint8_t serial;
+ /** Number of possible configurations */
+ uint8_t configurations;
+} __attribute__ (( packed ));
+
+/** A USB device descriptor */
+#define USB_DEVICE_DESCRIPTOR 1
+
+/** A USB configuration descriptor */
+struct usb_configuration_descriptor {
+ /** Descriptor header */
+ struct usb_descriptor_header header;
+ /** Total length */
+ uint16_t len;
+ /** Number of interfaces */
+ uint8_t interfaces;
+ /** Configuration value */
+ uint8_t config;
+ /** Configuration string */
+ uint8_t name;
+ /** Attributes */
+ uint8_t attributes;
+ /** Maximum power consumption */
+ uint8_t power;
+} __attribute__ (( packed ));
+
+/** A USB configuration descriptor */
+#define USB_CONFIGURATION_DESCRIPTOR 2
+
+/** A USB string descriptor */
+struct usb_string_descriptor {
+ /** Descriptor header */
+ struct usb_descriptor_header header;
+ /** String */
+ char string[0];
+} __attribute__ (( packed ));
+
+/** A USB string descriptor */
+#define USB_STRING_DESCRIPTOR 3
+
+/** A USB interface descriptor */
+struct usb_interface_descriptor {
+ /** Descriptor header */
+ struct usb_descriptor_header header;
+ /** Interface number */
+ uint8_t interface;
+ /** Alternate setting */
+ uint8_t alternate;
+ /** Number of endpoints */
+ uint8_t endpoints;
+ /** Interface class */
+ struct usb_class class;
+ /** Interface name */
+ uint8_t name;
+} __attribute__ (( packed ));
+
+/** A USB interface descriptor */
+#define USB_INTERFACE_DESCRIPTOR 4
+
+/** A USB endpoint descriptor */
+struct usb_endpoint_descriptor {
+ /** Descriptor header */
+ struct usb_descriptor_header header;
+ /** Endpoint address */
+ uint8_t endpoint;
+ /** Attributes */
+ uint8_t attributes;
+ /** Maximum packet size and burst size */
+ uint16_t sizes;
+ /** Polling interval */
+ uint8_t interval;
+} __attribute__ (( packed ));
+
+/** A USB endpoint descriptor */
+#define USB_ENDPOINT_DESCRIPTOR 5
+
+/** Endpoint attribute transfer type mask */
+#define USB_ENDPOINT_ATTR_TYPE_MASK 0x03
+
+/** Endpoint periodic type */
+#define USB_ENDPOINT_ATTR_PERIODIC 0x01
+
+/** Control endpoint transfer type */
+#define USB_ENDPOINT_ATTR_CONTROL 0x00
+
+/** Bulk endpoint transfer type */
+#define USB_ENDPOINT_ATTR_BULK 0x02
+
+/** Interrupt endpoint transfer type */
+#define USB_ENDPOINT_ATTR_INTERRUPT 0x03
+
+/** Bulk OUT endpoint (internal) type */
+#define USB_BULK_OUT ( USB_ENDPOINT_ATTR_BULK | USB_DIR_OUT )
+
+/** Bulk IN endpoint (internal) type */
+#define USB_BULK_IN ( USB_ENDPOINT_ATTR_BULK | USB_DIR_IN )
+
+/** Interrupt IN endpoint (internal) type */
+#define USB_INTERRUPT_IN ( USB_ENDPOINT_ATTR_INTERRUPT | USB_DIR_IN )
+
+/** Interrupt OUT endpoint (internal) type */
+#define USB_INTERRUPT_OUT ( USB_ENDPOINT_ATTR_INTERRUPT | USB_DIR_OUT )
+
+/** USB endpoint MTU */
+#define USB_ENDPOINT_MTU(sizes) ( ( (sizes) >> 0 ) & 0x07ff )
+
+/** USB endpoint maximum burst size */
+#define USB_ENDPOINT_BURST(sizes) ( ( (sizes) >> 11 ) & 0x0003 )
+
+/** A USB endpoint companion descriptor */
+struct usb_endpoint_companion_descriptor {
+ /** Descriptor header */
+ struct usb_descriptor_header header;
+ /** Maximum burst size */
+ uint8_t burst;
+ /** Extended attributes */
+ uint8_t extended;
+ /** Number of bytes per service interval */
+ uint16_t periodic;
+} __attribute__ (( packed ));
+
+/** A USB endpoint companion descriptor */
+#define USB_ENDPOINT_COMPANION_DESCRIPTOR 48
+
+/** A USB interface association descriptor */
+struct usb_interface_association_descriptor {
+ /** Descriptor header */
+ struct usb_descriptor_header header;
+ /** First interface number */
+ uint8_t first;
+ /** Interface count */
+ uint8_t count;
+ /** Association class */
+ struct usb_class class;
+ /** Association name */
+ uint8_t name;
+} __attribute__ (( packed ));
+
+/** A USB interface association descriptor */
+#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR 11
+
+/** A class-specific interface descriptor */
+#define USB_CS_INTERFACE_DESCRIPTOR 36
+
+/** A class-specific endpoint descriptor */
+#define USB_CS_ENDPOINT_DESCRIPTOR 37
+
+/**
+ * Get next USB descriptor
+ *
+ * @v desc USB descriptor header
+ * @ret next Next USB descriptor header
+ */
+static inline __attribute__ (( always_inline )) struct usb_descriptor_header *
+usb_next_descriptor ( struct usb_descriptor_header *desc ) {
+
+ return ( ( ( void * ) desc ) + desc->len );
+}
+
+/**
+ * Check that descriptor lies within a configuration descriptor
+ *
+ * @v config Configuration descriptor
+ * @v desc Descriptor header
+ * @v is_within Descriptor is within the configuration descriptor
+ */
+static inline __attribute__ (( always_inline )) int
+usb_is_within_config ( struct usb_configuration_descriptor *config,
+ struct usb_descriptor_header *desc ) {
+ struct usb_descriptor_header *end =
+ ( ( ( void * ) config ) + le16_to_cpu ( config->len ) );
+
+ /* Check that descriptor starts within the configuration
+ * descriptor, and that the length does not exceed the
+ * configuration descriptor. This relies on the fact that
+ * usb_next_descriptor() needs to access only the first byte
+ * of the descriptor in order to determine the length.
+ */
+ return ( ( desc < end ) && ( usb_next_descriptor ( desc ) <= end ) );
+}
+
+/** Iterate over all configuration descriptors */
+#define for_each_config_descriptor( desc, config ) \
+ for ( desc = container_of ( &(config)->header, \
+ typeof ( *desc ), header ) ; \
+ usb_is_within_config ( (config), &desc->header ) ; \
+ desc = container_of ( usb_next_descriptor ( &desc->header ), \
+ typeof ( *desc ), header ) )
+
+/** Iterate over all configuration descriptors within an interface descriptor */
+#define for_each_interface_descriptor( desc, config, interface ) \
+ for ( desc = container_of ( usb_next_descriptor ( &(interface)-> \
+ header ), \
+ typeof ( *desc ), header ) ; \
+ ( usb_is_within_config ( (config), &desc->header ) && \
+ ( desc->header.type != USB_INTERFACE_DESCRIPTOR ) ) ; \
+ desc = container_of ( usb_next_descriptor ( &desc->header ), \
+ typeof ( *desc ), header ) )
+
+/** A USB endpoint */
+struct usb_endpoint {
+ /** USB device */
+ struct usb_device *usb;
+ /** Endpoint address */
+ unsigned int address;
+ /** Attributes */
+ unsigned int attributes;
+ /** Maximum transfer size */
+ size_t mtu;
+ /** Maximum burst size */
+ unsigned int burst;
+ /** Interval (in microframes) */
+ unsigned int interval;
+
+ /** Endpoint is open */
+ int open;
+ /** Buffer fill level */
+ unsigned int fill;
+
+ /** List of halted endpoints */
+ struct list_head halted;
+
+ /** Host controller operations */
+ struct usb_endpoint_host_operations *host;
+ /** Host controller private data */
+ void *priv;
+ /** Driver operations */
+ struct usb_endpoint_driver_operations *driver;
+
+ /** Recycled I/O buffer list */
+ struct list_head recycled;
+ /** Refill buffer length */
+ size_t len;
+ /** Maximum fill level */
+ unsigned int max;
+};
+
+/** USB endpoint host controller operations */
+struct usb_endpoint_host_operations {
+ /** Open endpoint
+ *
+ * @v ep USB endpoint
+ * @ret rc Return status code
+ */
+ int ( * open ) ( struct usb_endpoint *ep );
+ /** Close endpoint
+ *
+ * @v ep USB endpoint
+ */
+ void ( * close ) ( struct usb_endpoint *ep );
+ /**
+ * Reset endpoint
+ *
+ * @v ep USB endpoint
+ * @ret rc Return status code
+ */
+ int ( * reset ) ( struct usb_endpoint *ep );
+ /** Update MTU
+ *
+ * @v ep USB endpoint
+ * @ret rc Return status code
+ */
+ int ( * mtu ) ( struct usb_endpoint *ep );
+ /** Enqueue message transfer
+ *
+ * @v ep USB endpoint
+ * @v iobuf I/O buffer
+ * @ret rc Return status code
+ */
+ int ( * message ) ( struct usb_endpoint *ep,
+ struct io_buffer *iobuf );
+ /** Enqueue stream transfer
+ *
+ * @v ep USB endpoint
+ * @v iobuf I/O buffer
+ * @v terminate Terminate using a short packet
+ * @ret rc Return status code
+ */
+ int ( * stream ) ( struct usb_endpoint *ep, struct io_buffer *iobuf,
+ int terminate );
+};
+
+/** USB endpoint driver operations */
+struct usb_endpoint_driver_operations {
+ /** Complete transfer
+ *
+ * @v ep USB endpoint
+ * @v iobuf I/O buffer
+ * @v rc Completion status code
+ */
+ void ( * complete ) ( struct usb_endpoint *ep,
+ struct io_buffer *iobuf, int rc );
+};
+
+/** Control endpoint address */
+#define USB_EP0_ADDRESS 0x00
+
+/** Control endpoint attributes */
+#define USB_EP0_ATTRIBUTES 0x00
+
+/** Calculate default MTU based on device speed
+ *
+ * @v speed Device speed
+ * @ret mtu Default MTU
+ */
+#define USB_EP0_DEFAULT_MTU(speed) \
+ ( ( (speed) >= USB_SPEED_SUPER ) ? 512 : \
+ ( ( (speed) >= USB_SPEED_FULL ) ? 64 : 8 ) )
+
+/** Control endpoint maximum burst size */
+#define USB_EP0_BURST 0
+
+/** Control endpoint interval */
+#define USB_EP0_INTERVAL 0
+
+/** Maximum endpoint number */
+#define USB_ENDPOINT_MAX 0x0f
+
+/** Endpoint direction is in */
+#define USB_ENDPOINT_IN 0x80
+
+/** Construct endpoint index from endpoint address */
+#define USB_ENDPOINT_IDX(address) \
+ ( ( (address) & USB_ENDPOINT_MAX ) | \
+ ( ( (address) & USB_ENDPOINT_IN ) >> 3 ) )
+
+/**
+ * Initialise USB endpoint
+ *
+ * @v ep USB endpoint
+ * @v usb USB device
+ * @v driver Driver operations
+ */
+static inline __attribute__ (( always_inline )) void
+usb_endpoint_init ( struct usb_endpoint *ep, struct usb_device *usb,
+ struct usb_endpoint_driver_operations *driver ) {
+
+ ep->usb = usb;
+ ep->driver = driver;
+}
+
+/**
+ * Describe USB endpoint
+ *
+ * @v ep USB endpoint
+ * @v address Endpoint address
+ * @v attributes Attributes
+ * @v mtu Maximum packet size
+ * @v burst Maximum burst size
+ * @v interval Interval (in microframes)
+ */
+static inline __attribute__ (( always_inline )) void
+usb_endpoint_describe ( struct usb_endpoint *ep, unsigned int address,
+ unsigned int attributes, size_t mtu,
+ unsigned int burst, unsigned int interval ) {
+
+ ep->address = address;
+ ep->attributes = attributes;
+ ep->mtu = mtu;
+ ep->burst = burst;
+ ep->interval = interval;
+}
+
+/**
+ * Set USB endpoint host controller private data
+ *
+ * @v ep USB endpoint
+ * @v priv Host controller private data
+ */
+static inline __attribute__ (( always_inline )) void
+usb_endpoint_set_hostdata ( struct usb_endpoint *ep, void *priv ) {
+ ep->priv = priv;
+}
+
+/**
+ * Get USB endpoint host controller private data
+ *
+ * @v ep USB endpoint
+ * @ret priv Host controller private data
+ */
+static inline __attribute__ (( always_inline )) void *
+usb_endpoint_get_hostdata ( struct usb_endpoint *ep ) {
+ return ep->priv;
+}
+
+extern const char * usb_endpoint_name ( struct usb_endpoint *ep );
+extern int
+usb_endpoint_described ( struct usb_endpoint *ep,
+ struct usb_configuration_descriptor *config,
+ struct usb_interface_descriptor *interface,
+ unsigned int type, unsigned int index );
+extern int usb_endpoint_open ( struct usb_endpoint *ep );
+extern void usb_endpoint_close ( struct usb_endpoint *ep );
+extern int usb_message ( struct usb_endpoint *ep, unsigned int request,
+ unsigned int value, unsigned int index,
+ struct io_buffer *iobuf );
+extern int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
+ int terminate );
+extern void usb_complete_err ( struct usb_endpoint *ep,
+ struct io_buffer *iobuf, int rc );
+
+/**
+ * Initialise USB endpoint refill
+ *
+ * @v ep USB endpoint
+ * @v len Refill buffer length (or zero to use endpoint's MTU)
+ * @v max Maximum fill level
+ */
+static inline __attribute__ (( always_inline )) void
+usb_refill_init ( struct usb_endpoint *ep, size_t len, unsigned int max ) {
+
+ INIT_LIST_HEAD ( &ep->recycled );
+ ep->len = len;
+ ep->max = max;
+}
+
+/**
+ * Recycle I/O buffer
+ *
+ * @v ep USB endpoint
+ * @v iobuf I/O buffer
+ */
+static inline __attribute__ (( always_inline )) void
+usb_recycle ( struct usb_endpoint *ep, struct io_buffer *iobuf ) {
+
+ list_add_tail ( &iobuf->list, &ep->recycled );
+}
+
+extern int usb_prefill ( struct usb_endpoint *ep );
+extern int usb_refill ( struct usb_endpoint *ep );
+extern void usb_flush ( struct usb_endpoint *ep );
+
+/**
+ * A USB function
+ *
+ * A USB function represents an association of interfaces within a USB
+ * device.
+ */
+struct usb_function {
+ /** Name */
+ const char *name;
+ /** USB device */
+ struct usb_device *usb;
+ /** Class */
+ struct usb_class class;
+ /** Number of interfaces */
+ unsigned int count;
+ /** Generic device */
+ struct device dev;
+ /** List of functions within this USB device */
+ struct list_head list;
+
+ /** Driver */
+ struct usb_driver *driver;
+ /** Driver private data */
+ void *priv;
+
+ /** List of interface numbers
+ *
+ * This must be the last field within the structure.
+ */
+ uint8_t interface[0];
+};
+
+/**
+ * Set USB function driver private data
+ *
+ * @v func USB function
+ * @v priv Driver private data
+ */
+static inline __attribute__ (( always_inline )) void
+usb_func_set_drvdata ( struct usb_function *func, void *priv ) {
+ func->priv = priv;
+}
+
+/**
+ * Get USB function driver private data
+ *
+ * @v function USB function
+ * @ret priv Driver private data
+ */
+static inline __attribute__ (( always_inline )) void *
+usb_func_get_drvdata ( struct usb_function *func ) {
+ return func->priv;
+}
+
+/** A USB device */
+struct usb_device {
+ /** Name */
+ char name[32];
+ /** USB port */
+ struct usb_port *port;
+ /** List of devices on this bus */
+ struct list_head list;
+ /** Device address, if assigned */
+ unsigned int address;
+ /** Device descriptor */
+ struct usb_device_descriptor device;
+ /** List of functions */
+ struct list_head functions;
+
+ /** Host controller operations */
+ struct usb_device_host_operations *host;
+ /** Host controller private data */
+ void *priv;
+
+ /** Endpoint list */
+ struct usb_endpoint *ep[32];
+
+ /** Control endpoint */
+ struct usb_endpoint control;
+ /** Completed control transfers */
+ struct list_head complete;
+};
+
+/** USB device host controller operations */
+struct usb_device_host_operations {
+ /** Open device
+ *
+ * @v usb USB device
+ * @ret rc Return status code
+ */
+ int ( * open ) ( struct usb_device *usb );
+ /** Close device
+ *
+ * @v usb USB device
+ */
+ void ( * close ) ( struct usb_device *usb );
+ /** Assign device address
+ *
+ * @v usb USB device
+ * @ret rc Return status code
+ */
+ int ( * address ) ( struct usb_device *usb );
+};
+
+/**
+ * Set USB device host controller private data
+ *
+ * @v usb USB device
+ * @v priv Host controller private data
+ */
+static inline __attribute__ (( always_inline )) void
+usb_set_hostdata ( struct usb_device *usb, void *priv ) {
+ usb->priv = priv;
+}
+
+/**
+ * Get USB device host controller private data
+ *
+ * @v usb USB device
+ * @ret priv Host controller private data
+ */
+static inline __attribute__ (( always_inline )) void *
+usb_get_hostdata ( struct usb_device *usb ) {
+ return usb->priv;
+}
+
+/**
+ * Get USB endpoint
+ *
+ * @v usb USB device
+ * @v address Endpoint address
+ * @ret ep USB endpoint, or NULL if not opened
+ */
+static inline struct usb_endpoint * usb_endpoint ( struct usb_device *usb,
+ unsigned int address ) {
+
+ return usb->ep[ USB_ENDPOINT_IDX ( address ) ];
+}
+
+/** A USB port */
+struct usb_port {
+ /** USB hub */
+ struct usb_hub *hub;
+ /** Port address */
+ unsigned int address;
+ /** Port protocol */
+ unsigned int protocol;
+ /** Port speed */
+ unsigned int speed;
+ /** Port disconnection has been detected
+ *
+ * This should be set whenever the underlying hardware reports
+ * a connection status change.
+ */
+ int disconnected;
+ /** Port has an attached device */
+ int attached;
+ /** Currently attached device (if in use)
+ *
+ * Note that this field will be NULL if the attached device
+ * has been freed (e.g. because there were no drivers found).
+ */
+ struct usb_device *usb;
+ /** List of changed ports */
+ struct list_head changed;
+};
+
+/** A USB hub */
+struct usb_hub {
+ /** Name */
+ const char *name;
+ /** USB bus */
+ struct usb_bus *bus;
+ /** Underlying USB device, if any */
+ struct usb_device *usb;
+ /** Hub protocol */
+ unsigned int protocol;
+ /** Number of ports */
+ unsigned int ports;
+
+ /** List of hubs */
+ struct list_head list;
+
+ /** Host controller operations */
+ struct usb_hub_host_operations *host;
+ /** Driver operations */
+ struct usb_hub_driver_operations *driver;
+ /** Driver private data */
+ void *priv;
+
+ /** Port list
+ *
+ * This must be the last field within the structure.
+ */
+ struct usb_port port[0];
+};
+
+/** USB hub host controller operations */
+struct usb_hub_host_operations {
+ /** Open hub
+ *
+ * @v hub USB hub
+ * @ret rc Return status code
+ */
+ int ( * open ) ( struct usb_hub *hub );
+ /** Close hub
+ *
+ * @v hub USB hub
+ */
+ void ( * close ) ( struct usb_hub *hub );
+};
+
+/** USB hub driver operations */
+struct usb_hub_driver_operations {
+ /** Open hub
+ *
+ * @v hub USB hub
+ * @ret rc Return status code
+ */
+ int ( * open ) ( struct usb_hub *hub );
+ /** Close hub
+ *
+ * @v hub USB hub
+ */
+ void ( * close ) ( struct usb_hub *hub );
+ /** Enable port
+ *
+ * @v hub USB hub
+ * @v port USB port
+ * @ret rc Return status code
+ */
+ int ( * enable ) ( struct usb_hub *hub, struct usb_port *port );
+ /** Disable port
+ *
+ * @v hub USB hub
+ * @v port USB port
+ * @ret rc Return status code
+ */
+ int ( * disable ) ( struct usb_hub *hub, struct usb_port *port );
+ /** Update port speed
+ *
+ * @v hub USB hub
+ * @v port USB port
+ * @ret rc Return status code
+ */
+ int ( * speed ) ( struct usb_hub *hub, struct usb_port *port );
+ /** Clear transaction translator buffer
+ *
+ * @v hub USB hub
+ * @v port USB port
+ * @v ep USB endpoint
+ * @ret rc Return status code
+ */
+ int ( * clear_tt ) ( struct usb_hub *hub, struct usb_port *port,
+ struct usb_endpoint *ep );
+};
+
+/**
+ * Set USB hub driver private data
+ *
+ * @v hub USB hub
+ * @v priv Driver private data
+ */
+static inline __attribute__ (( always_inline )) void
+usb_hub_set_drvdata ( struct usb_hub *hub, void *priv ) {
+ hub->priv = priv;
+}
+
+/**
+ * Get USB hub driver private data
+ *
+ * @v hub USB hub
+ * @ret priv Driver private data
+ */
+static inline __attribute__ (( always_inline )) void *
+usb_hub_get_drvdata ( struct usb_hub *hub ) {
+ return hub->priv;
+}
+
+/**
+ * Get USB port
+ *
+ * @v hub USB hub
+ * @v address Port address
+ * @ret port USB port
+ */
+static inline __attribute__ (( always_inline )) struct usb_port *
+usb_port ( struct usb_hub *hub, unsigned int address ) {
+
+ return &hub->port[ address - 1 ];
+}
+
+/** A USB bus */
+struct usb_bus {
+ /** Name */
+ const char *name;
+ /** Underlying hardware device */
+ struct device *dev;
+ /** Host controller operations set */
+ struct usb_host_operations *op;
+
+ /** Largest transfer allowed on the bus */
+ size_t mtu;
+ /** Address in-use mask
+ *
+ * This is used only by buses which perform manual address
+ * assignment. USB allows for addresses in the range [1,127].
+ * We use a simple bitmask which restricts us to the range
+ * [1,64]; this is unlikely to be a problem in practice. For
+ * comparison: controllers which perform autonomous address
+ * assignment (such as xHCI) typically allow for only 32
+ * devices per bus anyway.
+ */
+ unsigned long long addresses;
+
+ /** Root hub */
+ struct usb_hub *hub;
+
+ /** List of USB buses */
+ struct list_head list;
+ /** List of devices */
+ struct list_head devices;
+ /** List of hubs */
+ struct list_head hubs;
+
+ /** Host controller operations */
+ struct usb_bus_host_operations *host;
+ /** Host controller private data */
+ void *priv;
+};
+
+/** USB bus host controller operations */
+struct usb_bus_host_operations {
+ /** Open bus
+ *
+ * @v bus USB bus
+ * @ret rc Return status code
+ */
+ int ( * open ) ( struct usb_bus *bus );
+ /** Close bus
+ *
+ * @v bus USB bus
+ */
+ void ( * close ) ( struct usb_bus *bus );
+ /** Poll bus
+ *
+ * @v bus USB bus
+ */
+ void ( * poll ) ( struct usb_bus *bus );
+};
+
+/** USB host controller operations */
+struct usb_host_operations {
+ /** Endpoint operations */
+ struct usb_endpoint_host_operations endpoint;
+ /** Device operations */
+ struct usb_device_host_operations device;
+ /** Bus operations */
+ struct usb_bus_host_operations bus;
+ /** Hub operations */
+ struct usb_hub_host_operations hub;
+ /** Root hub operations */
+ struct usb_hub_driver_operations root;
+};
+
+/**
+ * Set USB bus host controller private data
+ *
+ * @v bus USB bus
+ * @v priv Host controller private data
+ */
+static inline __attribute__ (( always_inline )) void
+usb_bus_set_hostdata ( struct usb_bus *bus, void *priv ) {
+ bus->priv = priv;
+}
+
+/**
+ * Get USB bus host controller private data
+ *
+ * @v bus USB bus
+ * @ret priv Host controller private data
+ */
+static inline __attribute__ (( always_inline )) void *
+usb_bus_get_hostdata ( struct usb_bus *bus ) {
+ return bus->priv;
+}
+
+/**
+ * Poll USB bus
+ *
+ * @v bus USB bus
+ */
+static inline __attribute__ (( always_inline )) void
+usb_poll ( struct usb_bus *bus ) {
+ bus->host->poll ( bus );
+}
+
+/** Iterate over all USB buses */
+#define for_each_usb_bus( bus ) \
+ list_for_each_entry ( (bus), &usb_buses, list )
+
+/**
+ * Complete transfer (without error)
+ *
+ * @v ep USB endpoint
+ * @v iobuf I/O buffer
+ */
+static inline __attribute__ (( always_inline )) void
+usb_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf ) {
+ usb_complete_err ( ep, iobuf, 0 );
+}
+
+extern int usb_control ( struct usb_device *usb, unsigned int request,
+ unsigned int value, unsigned int index, void *data,
+ size_t len );
+extern int usb_get_string_descriptor ( struct usb_device *usb,
+ unsigned int index,
+ unsigned int language,
+ char *buf, size_t len );
+
+/**
+ * Get status
+ *
+ * @v usb USB device
+ * @v type Request type
+ * @v index Target index
+ * @v data Status to fill in
+ * @v len Length of status descriptor
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+usb_get_status ( struct usb_device *usb, unsigned int type, unsigned int index,
+ void *data, size_t len ) {
+
+ return usb_control ( usb, ( USB_GET_STATUS | type ), 0, index,
+ data, len );
+}
+
+/**
+ * Clear feature
+ *
+ * @v usb USB device
+ * @v type Request type
+ * @v feature Feature selector
+ * @v index Target index
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+usb_clear_feature ( struct usb_device *usb, unsigned int type,
+ unsigned int feature, unsigned int index ) {
+
+ return usb_control ( usb, ( USB_CLEAR_FEATURE | type ),
+ feature, index, NULL, 0 );
+}
+
+/**
+ * Set feature
+ *
+ * @v usb USB device
+ * @v type Request type
+ * @v feature Feature selector
+ * @v index Target index
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+usb_set_feature ( struct usb_device *usb, unsigned int type,
+ unsigned int feature, unsigned int index ) {
+
+ return usb_control ( usb, ( USB_SET_FEATURE | type ),
+ feature, index, NULL, 0 );
+}
+
+/**
+ * Set address
+ *
+ * @v usb USB device
+ * @v address Device address
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+usb_set_address ( struct usb_device *usb, unsigned int address ) {
+
+ return usb_control ( usb, USB_SET_ADDRESS, address, 0, NULL, 0 );
+}
+
+/**
+ * Get USB descriptor
+ *
+ * @v usb USB device
+ * @v type Request type
+ * @v desc Descriptor type
+ * @v index Descriptor index
+ * @v language Language ID (for string descriptors)
+ * @v data Descriptor to fill in
+ * @v len Maximum length of descriptor
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+usb_get_descriptor ( struct usb_device *usb, unsigned int type,
+ unsigned int desc, unsigned int index,
+ unsigned int language, struct usb_descriptor_header *data,
+ size_t len ) {
+
+ return usb_control ( usb, ( USB_GET_DESCRIPTOR | type ),
+ ( ( desc << 8 ) | index ), language, data, len );
+}
+
+/**
+ * Get first part of USB device descriptor (up to and including MTU)
+ *
+ * @v usb USB device
+ * @v data Device descriptor to (partially) fill in
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+usb_get_mtu ( struct usb_device *usb, struct usb_device_descriptor *data ) {
+
+ return usb_get_descriptor ( usb, 0, USB_DEVICE_DESCRIPTOR, 0, 0,
+ &data->header,
+ ( offsetof ( typeof ( *data ), mtu ) +
+ sizeof ( data->mtu ) ) );
+}
+
+/**
+ * Get USB device descriptor
+ *
+ * @v usb USB device
+ * @v data Device descriptor to fill in
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+usb_get_device_descriptor ( struct usb_device *usb,
+ struct usb_device_descriptor *data ) {
+
+ return usb_get_descriptor ( usb, 0, USB_DEVICE_DESCRIPTOR, 0, 0,
+ &data->header, sizeof ( *data ) );
+}
+
+/**
+ * Get USB configuration descriptor
+ *
+ * @v usb USB device
+ * @v index Configuration index
+ * @v data Configuration descriptor to fill in
+ * @ret rc Return status code
+ */
+static inline __attribute (( always_inline )) int
+usb_get_config_descriptor ( struct usb_device *usb, unsigned int index,
+ struct usb_configuration_descriptor *data,
+ size_t len ) {
+
+ return usb_get_descriptor ( usb, 0, USB_CONFIGURATION_DESCRIPTOR, index,
+ 0, &data->header, len );
+}
+
+/**
+ * Set USB configuration
+ *
+ * @v usb USB device
+ * @v index Configuration index
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+usb_set_configuration ( struct usb_device *usb, unsigned int index ) {
+
+ return usb_control ( usb, USB_SET_CONFIGURATION, index, 0, NULL, 0 );
+}
+
+/**
+ * Set USB interface alternate setting
+ *
+ * @v usb USB device
+ * @v interface Interface number
+ * @v alternate Alternate setting
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+usb_set_interface ( struct usb_device *usb, unsigned int interface,
+ unsigned int alternate ) {
+
+ return usb_control ( usb, USB_SET_INTERFACE, alternate, interface,
+ NULL, 0 );
+}
+
+extern struct list_head usb_buses;
+
+extern struct usb_interface_descriptor *
+usb_interface_descriptor ( struct usb_configuration_descriptor *config,
+ unsigned int interface, unsigned int alternate );
+extern struct usb_endpoint_descriptor *
+usb_endpoint_descriptor ( struct usb_configuration_descriptor *config,
+ struct usb_interface_descriptor *interface,
+ unsigned int type, unsigned int index );
+extern struct usb_endpoint_companion_descriptor *
+usb_endpoint_companion_descriptor ( struct usb_configuration_descriptor *config,
+ struct usb_endpoint_descriptor *desc );
+
+extern struct usb_hub * alloc_usb_hub ( struct usb_bus *bus,
+ struct usb_device *usb,
+ unsigned int ports,
+ struct usb_hub_driver_operations *op );
+extern int register_usb_hub ( struct usb_hub *hub );
+extern void unregister_usb_hub ( struct usb_hub *hub );
+extern void free_usb_hub ( struct usb_hub *hub );
+
+extern void usb_port_changed ( struct usb_port *port );
+
+extern struct usb_bus * alloc_usb_bus ( struct device *dev,
+ unsigned int ports, size_t mtu,
+ struct usb_host_operations *op );
+extern int register_usb_bus ( struct usb_bus *bus );
+extern void unregister_usb_bus ( struct usb_bus *bus );
+extern void free_usb_bus ( struct usb_bus *bus );
+extern struct usb_bus * find_usb_bus_by_location ( unsigned int bus_type,
+ unsigned int location );
+
+extern int usb_alloc_address ( struct usb_bus *bus );
+extern void usb_free_address ( struct usb_bus *bus, unsigned int address );
+extern unsigned int usb_route_string ( struct usb_device *usb );
+extern unsigned int usb_depth ( struct usb_device *usb );
+extern struct usb_port * usb_root_hub_port ( struct usb_device *usb );
+extern struct usb_port * usb_transaction_translator ( struct usb_device *usb );
+
+/** Minimum reset time
+ *
+ * Section 7.1.7.5 of the USB2 specification states that root hub
+ * ports should assert reset signalling for at least 50ms.
+ */
+#define USB_RESET_DELAY_MS 50
+
+/** Reset recovery time
+ *
+ * Section 9.2.6.2 of the USB2 specification states that the
+ * "recovery" interval after a port reset is 10ms.
+ */
+#define USB_RESET_RECOVER_DELAY_MS 10
+
+/** Maximum time to wait for a control transaction to complete
+ *
+ * Section 9.2.6.1 of the USB2 specification states that the upper
+ * limit for commands to be processed is 5 seconds.
+ */
+#define USB_CONTROL_MAX_WAIT_MS 5000
+
+/** Set address recovery time
+ *
+ * Section 9.2.6.3 of the USB2 specification states that devices are
+ * allowed a 2ms recovery interval after receiving a new address.
+ */
+#define USB_SET_ADDRESS_RECOVER_DELAY_MS 2
+
+/** Time to wait for ports to stabilise
+ *
+ * Section 7.1.7.3 of the USB specification states that we must allow
+ * 100ms for devices to signal attachment, and an additional 100ms for
+ * connection debouncing. (This delay is parallelised across all
+ * ports on a hub; we do not delay separately for each port.)
+ */
+#define USB_PORT_DELAY_MS 200
+
+/** A USB device ID */
+struct usb_device_id {
+ /** Name */
+ const char *name;
+ /** Vendor ID */
+ uint16_t vendor;
+ /** Product ID */
+ uint16_t product;
+ /** Class */
+ struct usb_class class;
+};
+
+/** Match-anything ID */
+#define USB_ANY_ID 0xffff
+
+/** A USB driver */
+struct usb_driver {
+ /** USB ID table */
+ struct usb_device_id *ids;
+ /** Number of entries in ID table */
+ unsigned int id_count;
+ /**
+ * Probe device
+ *
+ * @v func USB function
+ * @v config Configuration descriptor
+ * @ret rc Return status code
+ */
+ int ( * probe ) ( struct usb_function *func,
+ struct usb_configuration_descriptor *config );
+ /**
+ * Remove device
+ *
+ * @v func USB function
+ */
+ void ( * remove ) ( struct usb_function *func );
+};
+
+/** USB driver table */
+#define USB_DRIVERS __table ( struct usb_driver, "usb_drivers" )
+
+/** Declare a USB driver */
+#define __usb_driver __table_entry ( USB_DRIVERS, 01 )
+
+#endif /* _IPXE_USB_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/usbhid.h b/qemu/roms/ipxe/src/include/ipxe/usbhid.h
new file mode 100644
index 000000000..fe9d84455
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/usbhid.h
@@ -0,0 +1,106 @@
+#ifndef _IPXE_USBHID_H
+#define _IPXE_USBHID_H
+
+/** @file
+ *
+ * USB human interface devices (HID)
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/usb.h>
+
+/** Class code for human interface devices */
+#define USB_CLASS_HID 3
+
+/** Subclass code for boot devices */
+#define USB_SUBCLASS_HID_BOOT 1
+
+/** Set protocol */
+#define USBHID_SET_PROTOCOL \
+ ( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE | \
+ USB_REQUEST_TYPE ( 0x0b ) )
+
+/** Boot protocol */
+#define USBHID_PROTOCOL_BOOT 0
+
+/** Report protocol */
+#define USBHID_PROTOCOL_REPORT 1
+
+/** Set idle time */
+#define USBHID_SET_IDLE \
+ ( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE | \
+ USB_REQUEST_TYPE ( 0x0a ) )
+
+/** A USB human interface device */
+struct usb_hid {
+ /** USB function */
+ struct usb_function *func;
+ /** Interrupt IN endpoint */
+ struct usb_endpoint in;
+ /** Interrupt OUT endpoint (optional) */
+ struct usb_endpoint out;
+};
+
+/**
+ * Initialise USB human interface device
+ *
+ * @v hid USB human interface device
+ * @v func USB function
+ * @v in Interrupt IN endpoint operations
+ * @v out Interrupt OUT endpoint operations (or NULL)
+ */
+static inline __attribute__ (( always_inline )) void
+usbhid_init ( struct usb_hid *hid, struct usb_function *func,
+ struct usb_endpoint_driver_operations *in,
+ struct usb_endpoint_driver_operations *out ) {
+ struct usb_device *usb = func->usb;
+
+ hid->func = func;
+ usb_endpoint_init ( &hid->in, usb, in );
+ if ( out )
+ usb_endpoint_init ( &hid->out, usb, out );
+}
+
+/**
+ * Set protocol
+ *
+ * @v usb USB device
+ * @v interface Interface number
+ * @v protocol HID protocol
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+usbhid_set_protocol ( struct usb_device *usb, unsigned int interface,
+ unsigned int protocol ) {
+
+ return usb_control ( usb, USBHID_SET_PROTOCOL, protocol, interface,
+ NULL, 0 );
+}
+
+/**
+ * Set idle time
+ *
+ * @v usb USB device
+ * @v interface Interface number
+ * @v report Report ID
+ * @v duration Duration (in 4ms units)
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+usbhid_set_idle ( struct usb_device *usb, unsigned int interface,
+ unsigned int report, unsigned int duration ) {
+
+ return usb_control ( usb, USBHID_SET_IDLE,
+ ( ( duration << 8 ) | report ),
+ interface, NULL, 0 );
+}
+
+extern int usbhid_open ( struct usb_hid *hid );
+extern void usbhid_close ( struct usb_hid *hid );
+extern int usbhid_refill ( struct usb_hid *hid );
+extern int usbhid_describe ( struct usb_hid *hid,
+ struct usb_configuration_descriptor *config );
+
+#endif /* _IPXE_USBHID_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/usbnet.h b/qemu/roms/ipxe/src/include/ipxe/usbnet.h
new file mode 100644
index 000000000..33a8f3f58
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/usbnet.h
@@ -0,0 +1,62 @@
+#ifndef _IPXE_USBNET_H
+#define _IPXE_USBNET_H
+
+/** @file
+ *
+ * USB network devices
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/usb.h>
+
+/** A USB network device */
+struct usbnet_device {
+ /** USB function */
+ struct usb_function *func;
+
+ /** Communications interface */
+ unsigned int comms;
+ /** Data interface */
+ unsigned int data;
+ /** Alternate setting for data interface */
+ unsigned int alternate;
+
+ /** Interrupt endpoint */
+ struct usb_endpoint intr;
+ /** Bulk IN endpoint */
+ struct usb_endpoint in;
+ /** Bulk OUT endpoint */
+ struct usb_endpoint out;
+};
+
+/**
+ * Initialise USB network device
+ *
+ * @v usbnet USB network device
+ * @v func USB function
+ * @v intr Interrupt endpoint operations
+ * @v in Bulk IN endpoint operations
+ * @v out Bulk OUT endpoint operations
+ */
+static inline __attribute__ (( always_inline )) void
+usbnet_init ( struct usbnet_device *usbnet, struct usb_function *func,
+ struct usb_endpoint_driver_operations *intr,
+ struct usb_endpoint_driver_operations *in,
+ struct usb_endpoint_driver_operations *out ) {
+ struct usb_device *usb = func->usb;
+
+ usbnet->func = func;
+ usb_endpoint_init ( &usbnet->intr, usb, intr );
+ usb_endpoint_init ( &usbnet->in, usb, in );
+ usb_endpoint_init ( &usbnet->out, usb, out );
+}
+
+extern int usbnet_open ( struct usbnet_device *usbnet );
+extern void usbnet_close ( struct usbnet_device *usbnet );
+extern int usbnet_refill ( struct usbnet_device *usbnet );
+extern int usbnet_describe ( struct usbnet_device *usbnet,
+ struct usb_configuration_descriptor *config );
+
+#endif /* _IPXE_USBNET_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/uuid.h b/qemu/roms/ipxe/src/include/ipxe/uuid.h
index ad515d0cb..6c45eb9aa 100644
--- a/qemu/roms/ipxe/src/include/ipxe/uuid.h
+++ b/qemu/roms/ipxe/src/include/ipxe/uuid.h
@@ -6,7 +6,7 @@
* Universally unique IDs
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <byteswap.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/validator.h b/qemu/roms/ipxe/src/include/ipxe/validator.h
index 23bdab423..0aee56eb0 100644
--- a/qemu/roms/ipxe/src/include/ipxe/validator.h
+++ b/qemu/roms/ipxe/src/include/ipxe/validator.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/interface.h>
#include <ipxe/x509.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/version.h b/qemu/roms/ipxe/src/include/ipxe/version.h
index ae4275db1..a43a33425 100644
--- a/qemu/roms/ipxe/src/include/ipxe/version.h
+++ b/qemu/roms/ipxe/src/include/ipxe/version.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <wchar.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/vlan.h b/qemu/roms/ipxe/src/include/ipxe/vlan.h
index 083c21916..439e0c16d 100644
--- a/qemu/roms/ipxe/src/include/ipxe/vlan.h
+++ b/qemu/roms/ipxe/src/include/ipxe/vlan.h
@@ -8,7 +8,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** A VLAN header */
struct vlan_header {
diff --git a/qemu/roms/ipxe/src/include/ipxe/vmbus.h b/qemu/roms/ipxe/src/include/ipxe/vmbus.h
new file mode 100644
index 000000000..26fc578c6
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/ipxe/vmbus.h
@@ -0,0 +1,634 @@
+#ifndef _IPXE_VMBUS_H
+#define _IPXE_VMBUS_H
+
+/** @file
+ *
+ * Hyper-V virtual machine bus
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <byteswap.h>
+#include <ipxe/uuid.h>
+#include <ipxe/device.h>
+#include <ipxe/tables.h>
+#include <ipxe/uaccess.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/hyperv.h>
+
+/** VMBus message connection ID */
+#define VMBUS_MESSAGE_ID 1
+
+/** VMBus event connection ID */
+#define VMBUS_EVENT_ID 2
+
+/** VMBus message type */
+#define VMBUS_MESSAGE_TYPE 1
+
+/** VMBus message synthetic interrupt */
+#define VMBUS_MESSAGE_SINT 2
+
+/** VMBus version number */
+union vmbus_version {
+ /** Raw version */
+ uint32_t raw;
+ /** Major/minor version */
+ struct {
+ /** Minor version */
+ uint16_t minor;
+ /** Major version */
+ uint16_t major;
+ };
+} __attribute__ (( packed ));
+
+/** Known VMBus protocol versions */
+enum vmbus_raw_version {
+ /** Windows Server 2008 */
+ VMBUS_VERSION_WS2008 = ( ( 0 << 16 ) | ( 13 << 0 ) ),
+ /** Windows 7 */
+ VMBUS_VERSION_WIN7 = ( ( 1 << 16 ) | ( 1 << 0 ) ),
+ /** Windows 8 */
+ VMBUS_VERSION_WIN8 = ( ( 2 << 16 ) | ( 4 << 0 ) ),
+ /** Windows 8.1 */
+ VMBUS_VERSION_WIN8_1 = ( ( 3 << 16 ) | ( 0 << 0 ) ),
+};
+
+/** Guest physical address range descriptor */
+struct vmbus_gpa_range {
+ /** Byte count */
+ uint32_t len;
+ /** Starting byte offset */
+ uint32_t offset;
+ /** Page frame numbers
+ *
+ * The length of this array is implied by the byte count and
+ * starting offset.
+ */
+ uint64_t pfn[0];
+} __attribute__ (( packed ));
+
+/** VMBus message header */
+struct vmbus_message_header {
+ /** Message type */
+ uint32_t type;
+ /** Reserved */
+ uint32_t reserved;
+} __attribute__ (( packed ));
+
+/** VMBus message types */
+enum vmbus_message_type {
+ VMBUS_OFFER_CHANNEL = 1,
+ VMBUS_REQUEST_OFFERS = 3,
+ VMBUS_ALL_OFFERS_DELIVERED = 4,
+ VMBUS_OPEN_CHANNEL = 5,
+ VMBUS_OPEN_CHANNEL_RESULT = 6,
+ VMBUS_CLOSE_CHANNEL = 7,
+ VMBUS_GPADL_HEADER = 8,
+ VMBUS_GPADL_CREATED = 10,
+ VMBUS_GPADL_TEARDOWN = 11,
+ VMBUS_GPADL_TORNDOWN = 12,
+ VMBUS_INITIATE_CONTACT = 14,
+ VMBUS_VERSION_RESPONSE = 15,
+ VMBUS_UNLOAD = 16,
+ VMBUS_UNLOAD_RESPONSE = 17,
+};
+
+/** VMBus "offer channel" message */
+struct vmbus_offer_channel {
+ /** Message header */
+ struct vmbus_message_header header;
+ /** Channel type */
+ union uuid type;
+ /** Channel instance */
+ union uuid instance;
+ /** Reserved */
+ uint8_t reserved_a[16];
+ /** Flags */
+ uint16_t flags;
+ /** Reserved */
+ uint8_t reserved_b[2];
+ /** User data */
+ uint8_t data[120];
+ /** Reserved */
+ uint8_t reserved_c[4];
+ /** Channel ID */
+ uint32_t channel;
+ /** Monitor ID */
+ uint8_t monitor;
+ /** Monitor exists */
+ uint8_t monitored;
+ /** Reserved */
+ uint8_t reserved[2];
+ /** Connection ID */
+ uint32_t connection;
+} __attribute__ (( packed ));
+
+/** VMBus "open channel" message */
+struct vmbus_open_channel {
+ /** Message header */
+ struct vmbus_message_header header;
+ /** Channel ID */
+ uint32_t channel;
+ /** Open ID */
+ uint32_t id;
+ /** Ring buffer GPADL ID */
+ uint32_t gpadl;
+ /** Reserved */
+ uint32_t reserved;
+ /** Outbound ring buffer size (in pages) */
+ uint32_t out_pages;
+ /** User-specific data */
+ uint8_t data[120];
+} __attribute__ (( packed ));
+
+/** VMBus "open channel result" message */
+struct vmbus_open_channel_result {
+ /** Message header */
+ struct vmbus_message_header header;
+ /** Channel ID */
+ uint32_t channel;
+ /** Open ID */
+ uint32_t id;
+ /** Status */
+ uint32_t status;
+} __attribute__ (( packed ));
+
+/** VMBus "close channel" message */
+struct vmbus_close_channel {
+ /** Message header */
+ struct vmbus_message_header header;
+ /** Channel ID */
+ uint32_t channel;
+} __attribute__ (( packed ));
+
+/** VMBus "GPADL header" message */
+struct vmbus_gpadl_header {
+ /** Message header */
+ struct vmbus_message_header header;
+ /** Channel ID */
+ uint32_t channel;
+ /** GPADL ID */
+ uint32_t gpadl;
+ /** Length of range descriptors */
+ uint16_t range_len;
+ /** Number of range descriptors */
+ uint16_t range_count;
+ /** Range descriptors */
+ struct vmbus_gpa_range range[0];
+} __attribute__ (( packed ));
+
+/** VMBus "GPADL created" message */
+struct vmbus_gpadl_created {
+ /** Message header */
+ struct vmbus_message_header header;
+ /** Channel ID */
+ uint32_t channel;
+ /** GPADL ID */
+ uint32_t gpadl;
+ /** Creation status */
+ uint32_t status;
+} __attribute__ (( packed ));
+
+/** VMBus "GPADL teardown" message */
+struct vmbus_gpadl_teardown {
+ /** Message header */
+ struct vmbus_message_header header;
+ /** Channel ID */
+ uint32_t channel;
+ /** GPADL ID */
+ uint32_t gpadl;
+} __attribute__ (( packed ));
+
+/** VMBus "GPADL torndown" message */
+struct vmbus_gpadl_torndown {
+ /** Message header */
+ struct vmbus_message_header header;
+ /** GPADL ID */
+ uint32_t gpadl;
+} __attribute__ (( packed ));
+
+/** VMBus "initiate contact" message */
+struct vmbus_initiate_contact {
+ /** Message header */
+ struct vmbus_message_header header;
+ /** Requested version */
+ union vmbus_version version;
+ /** Target virtual CPU */
+ uint32_t vcpu;
+ /** Interrupt page base address */
+ uint64_t intr;
+ /** Parent to child monitor page base address */
+ uint64_t monitor_in;
+ /** Child to parent monitor page base address */
+ uint64_t monitor_out;
+} __attribute__ (( packed ));
+
+/** VMBus "version response" message */
+struct vmbus_version_response {
+ /** Message header */
+ struct vmbus_message_header header;
+ /** Version is supported */
+ uint8_t supported;
+ /** Reserved */
+ uint8_t reserved[3];
+ /** Version */
+ union vmbus_version version;
+} __attribute__ (( packed ));
+
+/** VMBus message */
+union vmbus_message {
+ /** Common message header */
+ struct vmbus_message_header header;
+ /** "Offer channel" message */
+ struct vmbus_offer_channel offer;
+ /** "Open channel" message */
+ struct vmbus_open_channel open;
+ /** "Open channel result" message */
+ struct vmbus_open_channel_result opened;
+ /** "Close channel" message */
+ struct vmbus_close_channel close;
+ /** "GPADL header" message */
+ struct vmbus_gpadl_header gpadlhdr;
+ /** "GPADL created" message */
+ struct vmbus_gpadl_created created;
+ /** "GPADL teardown" message */
+ struct vmbus_gpadl_teardown teardown;
+ /** "GPADL torndown" message */
+ struct vmbus_gpadl_torndown torndown;
+ /** "Initiate contact" message */
+ struct vmbus_initiate_contact initiate;
+ /** "Version response" message */
+ struct vmbus_version_response version;
+};
+
+/** VMBus packet header */
+struct vmbus_packet_header {
+ /** Type */
+ uint16_t type;
+ /** Length of packet header (in quadwords) */
+ uint16_t hdr_qlen;
+ /** Length of packet (in quadwords) */
+ uint16_t qlen;
+ /** Flags */
+ uint16_t flags;
+ /** Transaction ID
+ *
+ * This is an opaque token: we therefore treat it as
+ * native-endian and don't worry about byte-swapping.
+ */
+ uint64_t xid;
+} __attribute__ (( packed ));
+
+/** VMBus packet types */
+enum vmbus_packet_type {
+ VMBUS_DATA_INBAND = 6,
+ VMBUS_DATA_XFER_PAGES = 7,
+ VMBUS_DATA_GPA_DIRECT = 9,
+ VMBUS_CANCELLATION = 10,
+ VMBUS_COMPLETION = 11,
+};
+
+/** VMBus packet flags */
+enum vmbus_packet_flags {
+ VMBUS_COMPLETION_REQUESTED = 0x0001,
+};
+
+/** VMBus GPA direct header */
+struct vmbus_gpa_direct_header {
+ /** Packet header */
+ struct vmbus_packet_header header;
+ /** Reserved */
+ uint32_t reserved;
+ /** Number of range descriptors */
+ uint32_t range_count;
+ /** Range descriptors */
+ struct vmbus_gpa_range range[0];
+} __attribute__ (( packed ));
+
+/** VMBus transfer page range */
+struct vmbus_xfer_page_range {
+ /** Length */
+ uint32_t len;
+ /** Offset */
+ uint32_t offset;
+} __attribute__ (( packed ));
+
+/** VMBus transfer page header */
+struct vmbus_xfer_page_header {
+ /** Packet header */
+ struct vmbus_packet_header header;
+ /** Page set ID */
+ uint16_t pageset;
+ /** Sender owns page set */
+ uint8_t owner;
+ /** Reserved */
+ uint8_t reserved;
+ /** Number of range descriptors */
+ uint32_t range_count;
+ /** Range descriptors */
+ struct vmbus_xfer_page_range range[0];
+} __attribute__ (( packed ));
+
+/** Maximum expected size of VMBus packet header */
+#define VMBUS_PACKET_MAX_HEADER_LEN 64
+
+/** VMBus maximum-sized packet header */
+union vmbus_packet_header_max {
+ /** Common header */
+ struct vmbus_packet_header header;
+ /** GPA direct header */
+ struct vmbus_gpa_direct_header gpa;
+ /** Transfer page header */
+ struct vmbus_xfer_page_header xfer;
+ /** Padding to maximum supported size */
+ uint8_t padding[VMBUS_PACKET_MAX_HEADER_LEN];
+} __attribute__ (( packed ));
+
+/** VMBus packet footer */
+struct vmbus_packet_footer {
+ /** Reserved */
+ uint32_t reserved;
+ /** Producer index of the first byte of the packet */
+ uint32_t prod;
+} __attribute__ (( packed ));
+
+/** VMBus ring buffer
+ *
+ * This is the structure of the each of the ring buffers created when
+ * a VMBus channel is opened.
+ */
+struct vmbus_ring {
+ /** Producer index (modulo ring length) */
+ uint32_t prod;
+ /** Consumer index (modulo ring length) */
+ uint32_t cons;
+ /** Interrupt mask */
+ uint32_t intr_mask;
+ /** Reserved */
+ uint8_t reserved[4084];
+ /** Ring buffer contents */
+ uint8_t data[0];
+} __attribute__ (( packed ));
+
+/** VMBus interrupt page */
+struct vmbus_interrupt {
+ /** Inbound interrupts */
+ uint8_t in[ PAGE_SIZE / 2 ];
+ /** Outbound interrupts */
+ uint8_t out[ PAGE_SIZE / 2 ];
+} __attribute__ (( packed ));
+
+/** A virtual machine bus */
+struct vmbus {
+ /** Interrupt page */
+ struct vmbus_interrupt *intr;
+ /** Inbound notifications */
+ struct hv_monitor *monitor_in;
+ /** Outbound notifications */
+ struct hv_monitor *monitor_out;
+ /** Received message buffer */
+ const union vmbus_message *message;
+};
+
+struct vmbus_device;
+
+/** VMBus channel operations */
+struct vmbus_channel_operations {
+ /**
+ * Handle received control packet
+ *
+ * @v vmdev VMBus device
+ * @v xid Transaction ID
+ * @v data Data
+ * @v len Length of data
+ * @ret rc Return status code
+ */
+ int ( * recv_control ) ( struct vmbus_device *vmdev, uint64_t xid,
+ const void *data, size_t len );
+ /**
+ * Handle received data packet
+ *
+ * @v vmdev VMBus device
+ * @v xid Transaction ID
+ * @v data Data
+ * @v len Length of data
+ * @v list List of I/O buffers
+ * @ret rc Return status code
+ *
+ * This function takes ownership of the I/O buffer. It should
+ * eventually call vmbus_send_completion() to indicate to the
+ * host that the buffer can be reused.
+ */
+ int ( * recv_data ) ( struct vmbus_device *vmdev, uint64_t xid,
+ const void *data, size_t len,
+ struct list_head *list );
+ /**
+ * Handle received completion packet
+ *
+ * @v vmdev VMBus device
+ * @v xid Transaction ID
+ * @v data Data
+ * @v len Length of data
+ * @ret rc Return status code
+ */
+ int ( * recv_completion ) ( struct vmbus_device *vmdev, uint64_t xid,
+ const void *data, size_t len );
+ /**
+ * Handle received cancellation packet
+ *
+ * @v vmdev VMBus device
+ * @v xid Transaction ID
+ * @ret rc Return status code
+ */
+ int ( * recv_cancellation ) ( struct vmbus_device *vmdev,
+ uint64_t xid );
+};
+
+struct vmbus_xfer_pages;
+
+/** VMBus transfer page set operations */
+struct vmbus_xfer_pages_operations {
+ /**
+ * Copy data from transfer page
+ *
+ * @v pages Transfer page set
+ * @v data Data buffer
+ * @v offset Offset within page set
+ * @v len Length within page set
+ * @ret rc Return status code
+ */
+ int ( * copy ) ( struct vmbus_xfer_pages *pages, void *data,
+ size_t offset, size_t len );
+};
+
+/** VMBus transfer page set */
+struct vmbus_xfer_pages {
+ /** List of all transfer page sets */
+ struct list_head list;
+ /** Page set ID (in protocol byte order) */
+ uint16_t pageset;
+ /** Page set operations */
+ struct vmbus_xfer_pages_operations *op;
+};
+
+/** A VMBus device */
+struct vmbus_device {
+ /** Generic iPXE device */
+ struct device dev;
+ /** Hyper-V hypervisor */
+ struct hv_hypervisor *hv;
+
+ /** Channel ID */
+ unsigned int channel;
+ /** Monitor ID */
+ unsigned int monitor;
+ /** Signal channel
+ *
+ * @v vmdev VMBus device
+ */
+ void ( * signal ) ( struct vmbus_device *vmdev );
+
+ /** Outbound ring buffer length */
+ uint32_t out_len;
+ /** Inbound ring buffer length */
+ uint32_t in_len;
+ /** Outbound ring buffer */
+ struct vmbus_ring *out;
+ /** Inbound ring buffer */
+ struct vmbus_ring *in;
+ /** Ring buffer GPADL ID */
+ unsigned int gpadl;
+
+ /** Channel operations */
+ struct vmbus_channel_operations *op;
+ /** Maximum expected data packet length */
+ size_t mtu;
+ /** Packet buffer */
+ void *packet;
+ /** List of transfer page sets */
+ struct list_head pages;
+
+ /** Driver */
+ struct vmbus_driver *driver;
+ /** Driver-private data */
+ void *priv;
+};
+
+/** A VMBus device driver */
+struct vmbus_driver {
+ /** Name */
+ const char *name;
+ /** Device type */
+ union uuid type;
+ /** Probe device
+ *
+ * @v vmdev VMBus device
+ * @ret rc Return status code
+ */
+ int ( * probe ) ( struct vmbus_device *vmdev );
+ /** Remove device
+ *
+ * @v vmdev VMBus device
+ */
+ void ( * remove ) ( struct vmbus_device *vmdev );
+};
+
+/** VMBus device driver table */
+#define VMBUS_DRIVERS __table ( struct vmbus_driver, "vmbus_drivers" )
+
+/** Declare a VMBus device driver */
+#define __vmbus_driver __table_entry ( VMBUS_DRIVERS, 01 )
+
+/**
+ * Set VMBus device driver-private data
+ *
+ * @v vmdev VMBus device
+ * @v priv Private data
+ */
+static inline void vmbus_set_drvdata ( struct vmbus_device *vmdev, void *priv ){
+ vmdev->priv = priv;
+}
+
+/**
+ * Get VMBus device driver-private data
+ *
+ * @v vmdev VMBus device
+ * @ret priv Private data
+ */
+static inline void * vmbus_get_drvdata ( struct vmbus_device *vmdev ) {
+ return vmdev->priv;
+}
+
+/** Construct VMBus type */
+#define VMBUS_TYPE( a, b, c, d, e0, e1, e2, e3, e4, e5 ) { \
+ .canonical = { \
+ cpu_to_le32 ( a ), cpu_to_le16 ( b ), \
+ cpu_to_le16 ( c ), cpu_to_be16 ( d ), \
+ { e0, e1, e2, e3, e4, e5 } \
+ } }
+
+/**
+ * Check if data is present in ring buffer
+ *
+ * @v vmdev VMBus device
+ * @v has_data Data is present
+ */
+static inline __attribute__ (( always_inline )) int
+vmbus_has_data ( struct vmbus_device *vmdev ) {
+
+ return ( vmdev->in->prod != vmdev->in->cons );
+}
+
+/**
+ * Register transfer page set
+ *
+ * @v vmdev VMBus device
+ * @v pages Transfer page set
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+vmbus_register_pages ( struct vmbus_device *vmdev,
+ struct vmbus_xfer_pages *pages ) {
+
+ list_add ( &pages->list, &vmdev->pages );
+ return 0;
+}
+
+/**
+ * Unregister transfer page set
+ *
+ * @v vmdev VMBus device
+ * @v pages Transfer page set
+ */
+static inline __attribute__ (( always_inline )) void
+vmbus_unregister_pages ( struct vmbus_device *vmdev,
+ struct vmbus_xfer_pages *pages ) {
+
+ list_check_contains_entry ( pages, &vmdev->pages, list );
+ list_del ( &pages->list );
+}
+
+extern int vmbus_establish_gpadl ( struct vmbus_device *vmdev, userptr_t data,
+ size_t len );
+extern int vmbus_gpadl_teardown ( struct vmbus_device *vmdev,
+ unsigned int gpadl );
+extern int vmbus_open ( struct vmbus_device *vmdev,
+ struct vmbus_channel_operations *op,
+ size_t out_len, size_t in_len, size_t mtu );
+extern void vmbus_close ( struct vmbus_device *vmdev );
+extern int vmbus_send_control ( struct vmbus_device *vmdev, uint64_t xid,
+ const void *data, size_t len );
+extern int vmbus_send_data ( struct vmbus_device *vmdev, uint64_t xid,
+ const void *data, size_t len,
+ struct io_buffer *iobuf );
+extern int vmbus_send_completion ( struct vmbus_device *vmdev, uint64_t xid,
+ const void *data, size_t len );
+extern int vmbus_send_cancellation ( struct vmbus_device *vmdev, uint64_t xid );
+extern int vmbus_poll ( struct vmbus_device *vmdev );
+extern void vmbus_dump_channel ( struct vmbus_device *vmdev );
+
+extern int vmbus_probe ( struct hv_hypervisor *hv, struct device *parent );
+extern void vmbus_remove ( struct hv_hypervisor *hv, struct device *parent );
+
+#endif /* _IPXE_VMBUS_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/vsprintf.h b/qemu/roms/ipxe/src/include/ipxe/vsprintf.h
index c48c97a87..9e6297715 100644
--- a/qemu/roms/ipxe/src/include/ipxe/vsprintf.h
+++ b/qemu/roms/ipxe/src/include/ipxe/vsprintf.h
@@ -31,7 +31,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stdarg.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/x509.h b/qemu/roms/ipxe/src/include/ipxe/x509.h
index 802480e54..0daaf5e59 100644
--- a/qemu/roms/ipxe/src/include/ipxe/x509.h
+++ b/qemu/roms/ipxe/src/include/ipxe/x509.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stddef.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/xen.h b/qemu/roms/ipxe/src/include/ipxe/xen.h
index 60aabe03e..eac1145ad 100644
--- a/qemu/roms/ipxe/src/include/ipxe/xen.h
+++ b/qemu/roms/ipxe/src/include/ipxe/xen.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/* Define Xen interface version before including any Xen header files */
#define __XEN_INTERFACE_VERSION__ 0x00040400
diff --git a/qemu/roms/ipxe/src/include/ipxe/xenbus.h b/qemu/roms/ipxe/src/include/ipxe/xenbus.h
index ef2b5496f..ec5782eed 100644
--- a/qemu/roms/ipxe/src/include/ipxe/xenbus.h
+++ b/qemu/roms/ipxe/src/include/ipxe/xenbus.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/device.h>
#include <ipxe/tables.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/xenevent.h b/qemu/roms/ipxe/src/include/ipxe/xenevent.h
index 1dd6a0c0b..f0bd3465e 100644
--- a/qemu/roms/ipxe/src/include/ipxe/xenevent.h
+++ b/qemu/roms/ipxe/src/include/ipxe/xenevent.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/xen.h>
#include <xen/event_channel.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/xengrant.h b/qemu/roms/ipxe/src/include/ipxe/xengrant.h
index f9b3beb21..451a3ceee 100644
--- a/qemu/roms/ipxe/src/include/ipxe/xengrant.h
+++ b/qemu/roms/ipxe/src/include/ipxe/xengrant.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stdlib.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/xenmem.h b/qemu/roms/ipxe/src/include/ipxe/xenmem.h
index 9b9aeda9c..dcc38d460 100644
--- a/qemu/roms/ipxe/src/include/ipxe/xenmem.h
+++ b/qemu/roms/ipxe/src/include/ipxe/xenmem.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/xen.h>
#include <xen/memory.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/xenstore.h b/qemu/roms/ipxe/src/include/ipxe/xenstore.h
index f25f15704..892640755 100644
--- a/qemu/roms/ipxe/src/include/ipxe/xenstore.h
+++ b/qemu/roms/ipxe/src/include/ipxe/xenstore.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/xen.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/xenver.h b/qemu/roms/ipxe/src/include/ipxe/xenver.h
index 5d678c5a3..b29dfb321 100644
--- a/qemu/roms/ipxe/src/include/ipxe/xenver.h
+++ b/qemu/roms/ipxe/src/include/ipxe/xenver.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/xen.h>
#include <xen/version.h>
diff --git a/qemu/roms/ipxe/src/include/ipxe/xfer.h b/qemu/roms/ipxe/src/include/ipxe/xfer.h
index 1167e5cba..3a35fa924 100644
--- a/qemu/roms/ipxe/src/include/ipxe/xfer.h
+++ b/qemu/roms/ipxe/src/include/ipxe/xfer.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <stdarg.h>
@@ -103,5 +103,7 @@ extern int xfer_vprintf ( struct interface *intf,
extern int __attribute__ (( format ( printf, 2, 3 ) ))
xfer_printf ( struct interface *intf, const char *format, ... );
extern int xfer_seek ( struct interface *intf, off_t offset );
+extern int xfer_check_order ( struct xfer_metadata *meta, size_t *pos,
+ size_t len );
#endif /* _IPXE_XFER_H */
diff --git a/qemu/roms/ipxe/src/include/ipxe/xferbuf.h b/qemu/roms/ipxe/src/include/ipxe/xferbuf.h
index 2ca871e59..cb0b1a0e8 100644
--- a/qemu/roms/ipxe/src/include/ipxe/xferbuf.h
+++ b/qemu/roms/ipxe/src/include/ipxe/xferbuf.h
@@ -7,10 +7,12 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/iobuf.h>
+#include <ipxe/uaccess.h>
+#include <ipxe/interface.h>
#include <ipxe/xfer.h>
/** A data transfer buffer */
@@ -21,11 +23,83 @@ struct xfer_buffer {
size_t len;
/** Current offset within data */
size_t pos;
+ /** Data transfer buffer operations */
+ struct xfer_buffer_operations *op;
};
-extern void xferbuf_done ( struct xfer_buffer *xferbuf );
+/** Data transfer buffer operations */
+struct xfer_buffer_operations {
+ /** Reallocate data buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v len New length (or zero to free buffer)
+ * @ret rc Return status code
+ */
+ int ( * realloc ) ( struct xfer_buffer *xferbuf, size_t len );
+ /** Write data to buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v offset Starting offset
+ * @v data Data to write
+ * @v len Length of data
+ *
+ * This call is simply a wrapper for the appropriate
+ * memcpy()-like operation: the caller is responsible for
+ * ensuring that the write does not exceed the buffer length.
+ */
+ void ( * write ) ( struct xfer_buffer *xferbuf, size_t offset,
+ const void *data, size_t len );
+ /** Read data from buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v offset Starting offset
+ * @v data Data to read
+ * @v len Length of data
+ *
+ * This call is simply a wrapper for the appropriate
+ * memcpy()-like operation: the caller is responsible for
+ * ensuring that the read does not exceed the buffer length.
+ */
+ void ( * read ) ( struct xfer_buffer *xferbuf, size_t offset,
+ void *data, size_t len );
+};
+
+extern struct xfer_buffer_operations xferbuf_malloc_operations;
+extern struct xfer_buffer_operations xferbuf_umalloc_operations;
+
+/**
+ * Initialise malloc()-based data transfer buffer
+ *
+ * @v xferbuf Data transfer buffer
+ */
+static inline __attribute__ (( always_inline )) void
+xferbuf_malloc_init ( struct xfer_buffer *xferbuf ) {
+ xferbuf->op = &xferbuf_malloc_operations;
+}
+
+/**
+ * Initialise umalloc()-based data transfer buffer
+ *
+ * @v xferbuf Data transfer buffer
+ * @v data User pointer
+ */
+static inline __attribute__ (( always_inline )) void
+xferbuf_umalloc_init ( struct xfer_buffer *xferbuf, userptr_t *data ) {
+ xferbuf->data = data;
+ xferbuf->op = &xferbuf_umalloc_operations;
+}
+
+extern void xferbuf_free ( struct xfer_buffer *xferbuf );
+extern int xferbuf_write ( struct xfer_buffer *xferbuf, size_t offset,
+ const void *data, size_t len );
+extern int xferbuf_read ( struct xfer_buffer *xferbuf, size_t offset,
+ void *data, size_t len );
extern int xferbuf_deliver ( struct xfer_buffer *xferbuf,
struct io_buffer *iobuf,
struct xfer_metadata *meta );
+extern struct xfer_buffer * xfer_buffer ( struct interface *intf );
+#define xfer_buffer_TYPE( object_type ) \
+ typeof ( struct xfer_buffer * ( object_type ) )
+
#endif /* _IPXE_XFERBUF_H */
diff --git a/qemu/roms/ipxe/src/include/libgen.h b/qemu/roms/ipxe/src/include/libgen.h
index 7e94881a9..ae0861270 100644
--- a/qemu/roms/ipxe/src/include/libgen.h
+++ b/qemu/roms/ipxe/src/include/libgen.h
@@ -1,7 +1,7 @@
#ifndef _LIBGEN_H
#define _LIBGEN_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern char * basename ( char *path );
extern char * dirname ( char *path );
diff --git a/qemu/roms/ipxe/src/include/little_bswap.h b/qemu/roms/ipxe/src/include/little_bswap.h
deleted file mode 100644
index 92dd26ba1..000000000
--- a/qemu/roms/ipxe/src/include/little_bswap.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef ETHERBOOT_LITTLE_BSWAP_H
-#define ETHERBOOT_LITTLE_BSWAP_H
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#define htonll(x) __bswap_64(x)
-#define ntohll(x) __bswap_64(x)
-#define ntohl(x) __bswap_32(x)
-#define htonl(x) __bswap_32(x)
-#define ntohs(x) __bswap_16(x)
-#define htons(x) __bswap_16(x)
-#define cpu_to_le64(x) (x)
-#define cpu_to_le32(x) (x)
-#define cpu_to_le16(x) (x)
-#define cpu_to_be64(x) __bswap_64(x)
-#define cpu_to_be32(x) __bswap_32(x)
-#define cpu_to_be16(x) __bswap_16(x)
-#define le64_to_cpu(x) (x)
-#define le32_to_cpu(x) (x)
-#define le16_to_cpu(x) (x)
-#define be64_to_cpu(x) __bswap_64(x)
-#define be32_to_cpu(x) __bswap_32(x)
-#define be16_to_cpu(x) __bswap_16(x)
-#define cpu_to_le64s(x) do {} while (0)
-#define cpu_to_le32s(x) do {} while (0)
-#define cpu_to_le16s(x) do {} while (0)
-#define cpu_to_be64s(x) __bswap_64s(x)
-#define cpu_to_be32s(x) __bswap_32s(x)
-#define cpu_to_be16s(x) __bswap_16s(x)
-#define le64_to_cpus(x) do {} while (0)
-#define le32_to_cpus(x) do {} while (0)
-#define le16_to_cpus(x) do {} while (0)
-#define be64_to_cpus(x) __bswap_64s(x)
-#define be32_to_cpus(x) __bswap_32s(x)
-#define be16_to_cpus(x) __bswap_16s(x)
-
-#endif /* ETHERBOOT_LITTLE_BSWAP_H */
diff --git a/qemu/roms/ipxe/src/include/nic.h b/qemu/roms/ipxe/src/include/nic.h
index 9aaede8a7..4c91f57a6 100644
--- a/qemu/roms/ipxe/src/include/nic.h
+++ b/qemu/roms/ipxe/src/include/nic.h
@@ -1,8 +1,18 @@
- /*
+/*
* 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, or (at
- * your option) any later version.
+ * 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.
*/
FILE_LICENCE ( GPL2_OR_LATER );
@@ -266,6 +276,7 @@ static inline void * legacy_isa_get_drvdata ( void *hwdev ) {
_name ## _isa_legacy_remove ( struct isa_device *isa ) { \
return legacy_remove ( isa, legacy_isa_get_drvdata, \
_name ## _disable ); \
- }
+ } \
+ PROVIDE_REQUIRING_SYMBOL()
#endif /* NIC_H */
diff --git a/qemu/roms/ipxe/src/include/readline/readline.h b/qemu/roms/ipxe/src/include/readline/readline.h
index 0449a3f98..afafbbdf5 100644
--- a/qemu/roms/ipxe/src/include/readline/readline.h
+++ b/qemu/roms/ipxe/src/include/readline/readline.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** A readline history entry */
struct readline_history_entry {
diff --git a/qemu/roms/ipxe/src/include/stdarg.h b/qemu/roms/ipxe/src/include/stdarg.h
index f317238a9..89e94ce22 100644
--- a/qemu/roms/ipxe/src/include/stdarg.h
+++ b/qemu/roms/ipxe/src/include/stdarg.h
@@ -1,7 +1,7 @@
#ifndef _STDARG_H
#define _STDARG_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
typedef __builtin_va_list va_list;
#define va_start( ap, last ) __builtin_va_start ( ap, last )
diff --git a/qemu/roms/ipxe/src/include/stddef.h b/qemu/roms/ipxe/src/include/stddef.h
index bf792771f..3c056294f 100644
--- a/qemu/roms/ipxe/src/include/stddef.h
+++ b/qemu/roms/ipxe/src/include/stddef.h
@@ -1,25 +1,43 @@
#ifndef STDDEF_H
#define STDDEF_H
-FILE_LICENCE ( GPL2_ONLY );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-/* for size_t */
#include <stdint.h>
+/** EFI headers also define NULL */
#undef NULL
-#define NULL ((void *)0)
-#undef offsetof
-#if ( defined ( __GNUC__ ) && ( __GNUC__ > 3 ) )
-#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+/** Null pointer */
+#define NULL ( ( void * ) 0 )
+
+/**
+ * Get offset of a field within a structure
+ *
+ * @v type Structure type
+ * @v field Field within structure
+ * @ret offset Offset within structure
+ */
+#if defined ( __GNUC__ ) && ( __GNUC__ > 3 )
+#define offsetof( type, field ) __builtin_offsetof ( type, field )
#else
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#define offsetof( type, field ) ( ( size_t ) &( ( ( type * ) NULL )->field ) )
#endif
-#undef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
+/**
+ * Get containing structure
+ *
+ * @v ptr Pointer to contained field
+ * @v type Containing structure type
+ * @v field Field within containing structure
+ * @ret container Pointer to containing structure
+ */
+#define container_of( ptr, type, field ) ( { \
+ type *__container; \
+ const typeof ( __container->field ) *__field = (ptr); \
+ __container = ( ( ( void * ) __field ) - \
+ offsetof ( type, field ) ); \
+ __container; } )
/* __WCHAR_TYPE__ is defined by gcc and will change if -fshort-wchar is used */
#ifndef __WCHAR_TYPE__
diff --git a/qemu/roms/ipxe/src/include/stdint.h b/qemu/roms/ipxe/src/include/stdint.h
index 8cc9b84a5..0a239a517 100644
--- a/qemu/roms/ipxe/src/include/stdint.h
+++ b/qemu/roms/ipxe/src/include/stdint.h
@@ -1,7 +1,7 @@
#ifndef _STDINT_H
#define _STDINT_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/*
* This is a standard predefined macro on all gcc's I've seen. It's
diff --git a/qemu/roms/ipxe/src/include/stdio.h b/qemu/roms/ipxe/src/include/stdio.h
index 91840af5b..a618482ce 100644
--- a/qemu/roms/ipxe/src/include/stdio.h
+++ b/qemu/roms/ipxe/src/include/stdio.h
@@ -1,7 +1,7 @@
#ifndef _STDIO_H
#define _STDIO_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <stdarg.h>
diff --git a/qemu/roms/ipxe/src/include/stdlib.h b/qemu/roms/ipxe/src/include/stdlib.h
index 2951522b8..d7748a07e 100644
--- a/qemu/roms/ipxe/src/include/stdlib.h
+++ b/qemu/roms/ipxe/src/include/stdlib.h
@@ -1,7 +1,7 @@
#ifndef STDLIB_H
#define STDLIB_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <assert.h>
@@ -13,31 +13,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
****************************************************************************
*/
-static inline int strtoul_base ( const char **pp, int base )
-{
- const char *p = *pp;
-
- if ( base == 0 ) {
- base = 10;
- if ( *p == '0' ) {
- p++;
- base = 8;
- if ( ( *p | 0x20 ) == 'x' ) {
- p++;
- base = 16;
- }
- }
- }
-
- *pp = p;
-
- return base;
-}
-
-extern unsigned int strtoul_charval ( unsigned int charval );
-extern unsigned long strtoul ( const char *p, char **endp, int base );
-extern unsigned long long strtoull ( const char *p, char **endp, int base );
-
+extern unsigned long strtoul ( const char *string, char **endp, int base );
+extern unsigned long long strtoull ( const char *string, char **endp,
+ int base );
/*****************************************************************************
*
diff --git a/qemu/roms/ipxe/src/include/string.h b/qemu/roms/ipxe/src/include/string.h
index 3482e1b22..0fab6c74b 100644
--- a/qemu/roms/ipxe/src/include/string.h
+++ b/qemu/roms/ipxe/src/include/string.h
@@ -1,52 +1,53 @@
-/*
- * Copyright (C) 1991, 1992 Linus Torvalds
- * Copyright (C) 2004 Tobias Lorenz
+#ifndef _STRING_H
+#define _STRING_H
+
+/** @file
*
- * string handling functions
- * based on linux/include/linux/ctype.h
- * and linux/include/linux/string.h
+ * String functions
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
-FILE_LICENCE ( GPL2_ONLY );
-
-#ifndef ETHERBOOT_STRING_H
-#define ETHERBOOT_STRING_H
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <bits/string.h>
-int __pure strnicmp(const char *s1, const char *s2, size_t len) __nonnull;
-char * strcpy(char * dest,const char *src) __nonnull;
-char * strncpy(char * dest,const char *src,size_t count) __nonnull;
-char * strcat(char * dest, const char * src) __nonnull;
-char * strncat(char *dest, const char *src, size_t count) __nonnull;
-int __pure strcmp(const char * cs,const char * ct) __nonnull;
-int __pure strncmp(const char * cs,const char * ct,
- size_t count) __nonnull;
-char * __pure strchr(const char * s, int c) __nonnull;
-char * __pure strrchr(const char * s, int c) __nonnull;
-size_t __pure strlen(const char * s) __nonnull;
-size_t __pure strnlen(const char * s, size_t count) __nonnull;
-size_t __pure strspn(const char *s, const char *accept) __nonnull;
-size_t __pure strcspn(const char *s, const char *reject) __nonnull;
-char * __pure strpbrk(const char * cs,const char * ct) __nonnull;
-char * strtok(char * s,const char * ct) __nonnull;
-char * strsep(char **s, const char *ct) __nonnull;
-void * memset(void * s,int c,size_t count) __nonnull;
+/* Architecture-specific code is expected to provide these functions,
+ * but may instead explicitly choose to use the generic versions.
+ */
+void * memset ( void *dest, int character, size_t len ) __nonnull;
void * memcpy ( void *dest, const void *src, size_t len ) __nonnull;
-void * memmove(void * dest,const void *src,size_t count) __nonnull;
-int __pure memcmp(const void * cs,const void * ct,
- size_t count) __nonnull;
-void * __pure memscan(const void * addr, int c, size_t size) __nonnull;
-char * __pure strstr(const char * s1,const char * s2) __nonnull;
-void * __pure memchr(const void *s, int c, size_t n) __nonnull;
-char * __malloc strdup(const char *s) __nonnull;
-char * __malloc strndup(const char *s, size_t n) __nonnull;
+void * memmove ( void *dest, const void *src, size_t len ) __nonnull;
+extern void * generic_memset ( void *dest, int character,
+ size_t len ) __nonnull;
+extern void * generic_memcpy ( void *dest, const void *src,
+ size_t len ) __nonnull;
+extern void * generic_memmove ( void *dest, const void *src,
+ size_t len ) __nonnull;
+
+extern int __pure memcmp ( const void *first, const void *second,
+ size_t len ) __nonnull;
+extern void * __pure memchr ( const void *src, int character,
+ size_t len ) __nonnull;
+extern void * memswap ( void *dest, void *src, size_t len ) __nonnull;
+extern int __pure strcmp ( const char *first, const char *second ) __nonnull;
+extern int __pure strncmp ( const char *first, const char *second,
+ size_t max ) __nonnull;
+extern size_t __pure strlen ( const char *src ) __nonnull;
+extern size_t __pure strnlen ( const char *src, size_t max ) __nonnull;
+extern char * __pure strchr ( const char *src, int character ) __nonnull;
+extern char * __pure strrchr ( const char *src, int character ) __nonnull;
+extern char * __pure strstr ( const char *haystack,
+ const char *needle ) __nonnull;
+extern char * strcpy ( char *dest, const char *src ) __nonnull;
+extern char * strncpy ( char *dest, const char *src, size_t max ) __nonnull;
+extern char * strcat ( char *dest, const char *src ) __nonnull;
+extern char * __malloc strdup ( const char *src ) __nonnull;
+extern char * __malloc strndup ( const char *src, size_t max ) __nonnull;
+extern char * __pure strpbrk ( const char *string,
+ const char *delim ) __nonnull;
+extern char * strsep ( char **string, const char *delim ) __nonnull;
-extern const char * __pure strerror ( int errno );
+extern char * __pure strerror ( int errno );
-#endif /* ETHERBOOT_STRING */
+#endif /* _STRING_H */
diff --git a/qemu/roms/ipxe/src/include/strings.h b/qemu/roms/ipxe/src/include/strings.h
index 6912a1e45..fab26dc28 100644
--- a/qemu/roms/ipxe/src/include/strings.h
+++ b/qemu/roms/ipxe/src/include/strings.h
@@ -1,12 +1,71 @@
#ifndef _STRINGS_H
#define _STRINGS_H
-FILE_LICENCE ( GPL2_OR_LATER );
+/** @file
+ *
+ * String functions
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-#include <limits.h>
#include <string.h>
#include <bits/strings.h>
+/**
+ * Find first (i.e. least significant) set bit
+ *
+ * @v x Value
+ * @ret lsb Least significant bit set in value (LSB=1), or zero
+ */
+static inline __attribute__ (( always_inline )) int
+__constant_ffsll ( unsigned long long x ) {
+ int r = 0;
+
+ if ( ! ( x & 0x00000000ffffffffULL ) ) {
+ x >>= 32;
+ r += 32;
+ }
+ if ( ! ( x & 0x0000ffffUL ) ) {
+ x >>= 16;
+ r += 16;
+ }
+ if ( ! ( x & 0x00ff ) ) {
+ x >>= 8;
+ r += 8;
+ }
+ if ( ! ( x & 0x0f ) ) {
+ x >>= 4;
+ r += 4;
+ }
+ if ( ! ( x & 0x3 ) ) {
+ x >>= 2;
+ r += 2;
+ }
+ if ( ! ( x & 0x1 ) ) {
+ x >>= 1;
+ r += 1;
+ }
+ return ( x ? ( r + 1 ) : 0 );
+}
+
+/**
+ * Find first (i.e. least significant) set bit
+ *
+ * @v x Value
+ * @ret lsb Least significant bit set in value (LSB=1), or zero
+ */
+static inline __attribute__ (( always_inline )) int
+__constant_ffsl ( unsigned long x ) {
+ return __constant_ffsll ( x );
+}
+
+/**
+ * Find last (i.e. most significant) set bit
+ *
+ * @v x Value
+ * @ret msb Most significant bit set in value (LSB=1), or zero
+ */
static inline __attribute__ (( always_inline )) int
__constant_flsll ( unsigned long long x ) {
int r = 0;
@@ -35,38 +94,100 @@ __constant_flsll ( unsigned long long x ) {
x >>= 1;
r += 1;
}
- if ( x & 0x1 ) {
- r += 1;
- }
- return r;
+ return ( x ? ( r + 1 ) : 0 );
}
+/**
+ * Find last (i.e. most significant) set bit
+ *
+ * @v x Value
+ * @ret msb Most significant bit set in value (LSB=1), or zero
+ */
static inline __attribute__ (( always_inline )) int
__constant_flsl ( unsigned long x ) {
return __constant_flsll ( x );
}
+int __ffsll ( long long x );
+int __ffsl ( long x );
int __flsll ( long long x );
int __flsl ( long x );
+/**
+ * Find first (i.e. least significant) set bit
+ *
+ * @v x Value
+ * @ret lsb Least significant bit set in value (LSB=1), or zero
+ */
+#define ffsll( x ) \
+ ( __builtin_constant_p ( x ) ? __constant_ffsll ( x ) : __ffsll ( x ) )
+
+/**
+ * Find first (i.e. least significant) set bit
+ *
+ * @v x Value
+ * @ret lsb Least significant bit set in value (LSB=1), or zero
+ */
+#define ffsl( x ) \
+ ( __builtin_constant_p ( x ) ? __constant_ffsl ( x ) : __ffsl ( x ) )
+
+/**
+ * Find first (i.e. least significant) set bit
+ *
+ * @v x Value
+ * @ret lsb Least significant bit set in value (LSB=1), or zero
+ */
+#define ffs( x ) ffsl ( x )
+
+/**
+ * Find last (i.e. most significant) set bit
+ *
+ * @v x Value
+ * @ret msb Most significant bit set in value (LSB=1), or zero
+ */
#define flsll( x ) \
( __builtin_constant_p ( x ) ? __constant_flsll ( x ) : __flsll ( x ) )
+/**
+ * Find last (i.e. most significant) set bit
+ *
+ * @v x Value
+ * @ret msb Most significant bit set in value (LSB=1), or zero
+ */
#define flsl( x ) \
( __builtin_constant_p ( x ) ? __constant_flsl ( x ) : __flsl ( x ) )
+/**
+ * Find last (i.e. most significant) set bit
+ *
+ * @v x Value
+ * @ret msb Most significant bit set in value (LSB=1), or zero
+ */
#define fls( x ) flsl ( x )
-extern int strcasecmp ( const char *s1, const char *s2 );
-
+/**
+ * Copy memory
+ *
+ * @v src Source
+ * @v dest Destination
+ * @v len Length
+ */
static inline __attribute__ (( always_inline )) void
-bcopy ( const void *src, void *dest, size_t n ) {
- memmove ( dest, src, n );
+bcopy ( const void *src, void *dest, size_t len ) {
+ memmove ( dest, src, len );
}
+/**
+ * Zero memory
+ *
+ * @v dest Destination
+ * @v len Length
+ */
static inline __attribute__ (( always_inline )) void
-bzero ( void *s, size_t n ) {
- memset ( s, 0, n );
+bzero ( void *dest, size_t len ) {
+ memset ( dest, 0, len );
}
+int __pure strcasecmp ( const char *first, const char *second ) __nonnull;
+
#endif /* _STRINGS_H */
diff --git a/qemu/roms/ipxe/src/include/sys/time.h b/qemu/roms/ipxe/src/include/sys/time.h
index 2647d3588..6e2a24447 100644
--- a/qemu/roms/ipxe/src/include/sys/time.h
+++ b/qemu/roms/ipxe/src/include/sys/time.h
@@ -6,7 +6,7 @@
* Date and time
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/syslog.h b/qemu/roms/ipxe/src/include/syslog.h
index 93f32f867..748a4faec 100644
--- a/qemu/roms/ipxe/src/include/syslog.h
+++ b/qemu/roms/ipxe/src/include/syslog.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdarg.h>
#include <ipxe/ansiesc.h>
diff --git a/qemu/roms/ipxe/src/include/time.h b/qemu/roms/ipxe/src/include/time.h
index 452a544bb..462ac6999 100644
--- a/qemu/roms/ipxe/src/include/time.h
+++ b/qemu/roms/ipxe/src/include/time.h
@@ -6,7 +6,7 @@
* Date and time
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <sys/time.h>
#include <ipxe/time.h>
diff --git a/qemu/roms/ipxe/src/include/unistd.h b/qemu/roms/ipxe/src/include/unistd.h
index 3a50a2521..d09e1ae30 100644
--- a/qemu/roms/ipxe/src/include/unistd.h
+++ b/qemu/roms/ipxe/src/include/unistd.h
@@ -1,7 +1,7 @@
#ifndef _UNISTD_H
#define _UNISTD_H
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>
#include <stdarg.h>
diff --git a/qemu/roms/ipxe/src/include/usr/autoboot.h b/qemu/roms/ipxe/src/include/usr/autoboot.h
index bc51aae79..4db226b9c 100644
--- a/qemu/roms/ipxe/src/include/usr/autoboot.h
+++ b/qemu/roms/ipxe/src/include/usr/autoboot.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/device.h>
@@ -35,7 +35,7 @@ extern int uriboot ( struct uri *filename, struct uri *root_path, int drive,
extern struct uri *
fetch_next_server_and_filename ( struct settings *settings );
extern int netboot ( struct net_device *netdev );
-extern void ipxe ( struct net_device *netdev );
+extern int ipxe ( struct net_device *netdev );
extern int pxe_menu_boot ( struct net_device *netdev );
diff --git a/qemu/roms/ipxe/src/include/usr/dhcpmgmt.h b/qemu/roms/ipxe/src/include/usr/dhcpmgmt.h
index af1eceb17..ed669eb9d 100644
--- a/qemu/roms/ipxe/src/include/usr/dhcpmgmt.h
+++ b/qemu/roms/ipxe/src/include/usr/dhcpmgmt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct net_device;
diff --git a/qemu/roms/ipxe/src/include/usr/fcmgmt.h b/qemu/roms/ipxe/src/include/usr/fcmgmt.h
index 9441cefb4..eb568fd20 100644
--- a/qemu/roms/ipxe/src/include/usr/fcmgmt.h
+++ b/qemu/roms/ipxe/src/include/usr/fcmgmt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct fc_port;
struct fc_peer;
diff --git a/qemu/roms/ipxe/src/include/usr/ifmgmt.h b/qemu/roms/ipxe/src/include/usr/ifmgmt.h
index db77f1f1b..5c386327b 100644
--- a/qemu/roms/ipxe/src/include/usr/ifmgmt.h
+++ b/qemu/roms/ipxe/src/include/usr/ifmgmt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct net_device;
struct net_device_configurator;
diff --git a/qemu/roms/ipxe/src/include/usr/imgmgmt.h b/qemu/roms/ipxe/src/include/usr/imgmgmt.h
index 5e25c562b..806df0bfb 100644
--- a/qemu/roms/ipxe/src/include/usr/imgmgmt.h
+++ b/qemu/roms/ipxe/src/include/usr/imgmgmt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/image.h>
diff --git a/qemu/roms/ipxe/src/include/usr/imgtrust.h b/qemu/roms/ipxe/src/include/usr/imgtrust.h
index f47105af0..414e07a80 100644
--- a/qemu/roms/ipxe/src/include/usr/imgtrust.h
+++ b/qemu/roms/ipxe/src/include/usr/imgtrust.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/image.h>
diff --git a/qemu/roms/ipxe/src/include/usr/ipstat.h b/qemu/roms/ipxe/src/include/usr/ipstat.h
index 5ff8b40c3..803254bcb 100644
--- a/qemu/roms/ipxe/src/include/usr/ipstat.h
+++ b/qemu/roms/ipxe/src/include/usr/ipstat.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern void ipstat ( void );
diff --git a/qemu/roms/ipxe/src/include/usr/lotest.h b/qemu/roms/ipxe/src/include/usr/lotest.h
index aa4bbac4d..ce0fe5eda 100644
--- a/qemu/roms/ipxe/src/include/usr/lotest.h
+++ b/qemu/roms/ipxe/src/include/usr/lotest.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern int loopback_test ( struct net_device *sender,
struct net_device *receiver, size_t mtu );
diff --git a/qemu/roms/ipxe/src/include/usr/neighmgmt.h b/qemu/roms/ipxe/src/include/usr/neighmgmt.h
index 3c2b704af..06f03716e 100644
--- a/qemu/roms/ipxe/src/include/usr/neighmgmt.h
+++ b/qemu/roms/ipxe/src/include/usr/neighmgmt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern void nstat ( void );
diff --git a/qemu/roms/ipxe/src/include/usr/pingmgmt.h b/qemu/roms/ipxe/src/include/usr/pingmgmt.h
index d4c2d6cd5..c7a8434be 100644
--- a/qemu/roms/ipxe/src/include/usr/pingmgmt.h
+++ b/qemu/roms/ipxe/src/include/usr/pingmgmt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
diff --git a/qemu/roms/ipxe/src/include/usr/profstat.h b/qemu/roms/ipxe/src/include/usr/profstat.h
index 06ea251a0..b7812ca7f 100644
--- a/qemu/roms/ipxe/src/include/usr/profstat.h
+++ b/qemu/roms/ipxe/src/include/usr/profstat.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern void profstat ( void );
diff --git a/qemu/roms/ipxe/src/include/usr/prompt.h b/qemu/roms/ipxe/src/include/usr/prompt.h
index 57e43d2dc..8d3eeee3c 100644
--- a/qemu/roms/ipxe/src/include/usr/prompt.h
+++ b/qemu/roms/ipxe/src/include/usr/prompt.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern int prompt ( const char *text, unsigned long timeout, int key );
diff --git a/qemu/roms/ipxe/src/include/usr/route.h b/qemu/roms/ipxe/src/include/usr/route.h
index b914f4b84..7ec4a3509 100644
--- a/qemu/roms/ipxe/src/include/usr/route.h
+++ b/qemu/roms/ipxe/src/include/usr/route.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/tables.h>
diff --git a/qemu/roms/ipxe/src/include/usr/sync.h b/qemu/roms/ipxe/src/include/usr/sync.h
index 0047d4ed9..b6f12ad6e 100644
--- a/qemu/roms/ipxe/src/include/usr/sync.h
+++ b/qemu/roms/ipxe/src/include/usr/sync.h
@@ -7,7 +7,7 @@
*
*/
-FILE_LICENCE ( GPL2_OR_LATER );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern int sync ( unsigned long timeout );
diff --git a/qemu/roms/ipxe/src/include/valgrind/memcheck.h b/qemu/roms/ipxe/src/include/valgrind/memcheck.h
new file mode 100644
index 000000000..7d4b56d31
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/valgrind/memcheck.h
@@ -0,0 +1,311 @@
+
+/*
+ ----------------------------------------------------------------
+
+ Notice that the following BSD-style license applies to this one
+ file (memcheck.h) only. The rest of Valgrind is licensed under the
+ terms of the GNU General Public License, version 2, unless
+ otherwise indicated. See the COPYING file in the source
+ distribution for details.
+
+ ----------------------------------------------------------------
+
+ This file is part of MemCheck, a heavyweight Valgrind tool for
+ detecting memory errors.
+
+ Copyright (C) 2000-2010 Julian 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.
+
+ ----------------------------------------------------------------
+
+ Notice that the above BSD-style license applies to this one file
+ (memcheck.h) only. The entire rest of Valgrind is licensed under
+ the terms of the GNU General Public License, version 2. See the
+ COPYING file in the source distribution for details.
+
+ ----------------------------------------------------------------
+*/
+
+
+#ifndef __MEMCHECK_H
+#define __MEMCHECK_H
+
+FILE_LICENCE ( BSD3 );
+
+
+/* This file is for inclusion into client (your!) code.
+
+ You can use these macros to manipulate and query memory permissions
+ inside your own programs.
+
+ See comment near the top of valgrind.h on how to use them.
+*/
+
+#include "valgrind.h"
+
+/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
+ This enum comprises an ABI exported by Valgrind to programs
+ which use client requests. DO NOT CHANGE THE ORDER OF THESE
+ ENTRIES, NOR DELETE ANY -- add new ones at the end. */
+typedef
+ enum {
+ VG_USERREQ__MAKE_MEM_NOACCESS = VG_USERREQ_TOOL_BASE('M','C'),
+ VG_USERREQ__MAKE_MEM_UNDEFINED,
+ VG_USERREQ__MAKE_MEM_DEFINED,
+ VG_USERREQ__DISCARD,
+ VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,
+ VG_USERREQ__CHECK_MEM_IS_DEFINED,
+ VG_USERREQ__DO_LEAK_CHECK,
+ VG_USERREQ__COUNT_LEAKS,
+
+ VG_USERREQ__GET_VBITS,
+ VG_USERREQ__SET_VBITS,
+
+ VG_USERREQ__CREATE_BLOCK,
+
+ VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE,
+
+ /* Not next to VG_USERREQ__COUNT_LEAKS because it was added later. */
+ VG_USERREQ__COUNT_LEAK_BLOCKS,
+
+ /* This is just for memcheck's internal use - don't use it */
+ _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR
+ = VG_USERREQ_TOOL_BASE('M','C') + 256
+ } Vg_MemCheckClientRequest;
+
+
+
+/* Client-code macros to manipulate the state of memory. */
+
+/* Mark memory at _qzz_addr as unaddressable for _qzz_len bytes. */
+#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr,_qzz_len) \
+ (__extension__({unsigned long _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
+ VG_USERREQ__MAKE_MEM_NOACCESS, \
+ _qzz_addr, _qzz_len, 0, 0, 0); \
+ _qzz_res; \
+ }))
+
+/* Similarly, mark memory at _qzz_addr as addressable but undefined
+ for _qzz_len bytes. */
+#define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr,_qzz_len) \
+ (__extension__({unsigned long _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
+ VG_USERREQ__MAKE_MEM_UNDEFINED, \
+ _qzz_addr, _qzz_len, 0, 0, 0); \
+ _qzz_res; \
+ }))
+
+/* Similarly, mark memory at _qzz_addr as addressable and defined
+ for _qzz_len bytes. */
+#define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr,_qzz_len) \
+ (__extension__({unsigned long _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
+ VG_USERREQ__MAKE_MEM_DEFINED, \
+ _qzz_addr, _qzz_len, 0, 0, 0); \
+ _qzz_res; \
+ }))
+
+/* Similar to VALGRIND_MAKE_MEM_DEFINED except that addressability is
+ not altered: bytes which are addressable are marked as defined,
+ but those which are not addressable are left unchanged. */
+#define VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(_qzz_addr,_qzz_len) \
+ (__extension__({unsigned long _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
+ VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, \
+ _qzz_addr, _qzz_len, 0, 0, 0); \
+ _qzz_res; \
+ }))
+
+/* Create a block-description handle. The description is an ascii
+ string which is included in any messages pertaining to addresses
+ within the specified memory range. Has no other effect on the
+ properties of the memory range. */
+#define VALGRIND_CREATE_BLOCK(_qzz_addr,_qzz_len, _qzz_desc) \
+ (__extension__({unsigned long _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
+ VG_USERREQ__CREATE_BLOCK, \
+ _qzz_addr, _qzz_len, _qzz_desc, \
+ 0, 0); \
+ _qzz_res; \
+ }))
+
+/* Discard a block-description-handle. Returns 1 for an
+ invalid handle, 0 for a valid handle. */
+#define VALGRIND_DISCARD(_qzz_blkindex) \
+ (__extension__ ({unsigned long _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
+ VG_USERREQ__DISCARD, \
+ 0, _qzz_blkindex, 0, 0, 0); \
+ _qzz_res; \
+ }))
+
+
+/* Client-code macros to check the state of memory. */
+
+/* Check that memory at _qzz_addr is addressable for _qzz_len bytes.
+ If suitable addressibility is not established, Valgrind prints an
+ error message and returns the address of the first offending byte.
+ Otherwise it returns zero. */
+#define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(_qzz_addr,_qzz_len) \
+ (__extension__({unsigned long _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,\
+ _qzz_addr, _qzz_len, 0, 0, 0); \
+ _qzz_res; \
+ }))
+
+/* Check that memory at _qzz_addr is addressable and defined for
+ _qzz_len bytes. If suitable addressibility and definedness are not
+ established, Valgrind prints an error message and returns the
+ address of the first offending byte. Otherwise it returns zero. */
+#define VALGRIND_CHECK_MEM_IS_DEFINED(_qzz_addr,_qzz_len) \
+ (__extension__({unsigned long _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__CHECK_MEM_IS_DEFINED, \
+ _qzz_addr, _qzz_len, 0, 0, 0); \
+ _qzz_res; \
+ }))
+
+/* Use this macro to force the definedness and addressibility of an
+ lvalue to be checked. If suitable addressibility and definedness
+ are not established, Valgrind prints an error message and returns
+ the address of the first offending byte. Otherwise it returns
+ zero. */
+#define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) \
+ VALGRIND_CHECK_MEM_IS_DEFINED( \
+ (volatile unsigned char *)&(__lvalue), \
+ (unsigned long)(sizeof (__lvalue)))
+
+
+/* Do a full memory leak check (like --leak-check=full) mid-execution. */
+#define VALGRIND_DO_LEAK_CHECK \
+ {unsigned long _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__DO_LEAK_CHECK, \
+ 0, 0, 0, 0, 0); \
+ }
+
+/* Do a summary memory leak check (like --leak-check=summary) mid-execution. */
+#define VALGRIND_DO_QUICK_LEAK_CHECK \
+ {unsigned long _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__DO_LEAK_CHECK, \
+ 1, 0, 0, 0, 0); \
+ }
+
+/* Return number of leaked, dubious, reachable and suppressed bytes found by
+ all previous leak checks. They must be lvalues. */
+#define VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed) \
+ /* For safety on 64-bit platforms we assign the results to private
+ unsigned long variables, then assign these to the lvalues the user
+ specified, which works no matter what type 'leaked', 'dubious', etc
+ are. We also initialise '_qzz_leaked', etc because
+ VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as
+ defined. */ \
+ {unsigned long _qzz_res; \
+ unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \
+ unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__COUNT_LEAKS, \
+ &_qzz_leaked, &_qzz_dubious, \
+ &_qzz_reachable, &_qzz_suppressed, 0); \
+ leaked = _qzz_leaked; \
+ dubious = _qzz_dubious; \
+ reachable = _qzz_reachable; \
+ suppressed = _qzz_suppressed; \
+ }
+
+/* Return number of leaked, dubious, reachable and suppressed bytes found by
+ all previous leak checks. They must be lvalues. */
+#define VALGRIND_COUNT_LEAK_BLOCKS(leaked, dubious, reachable, suppressed) \
+ /* For safety on 64-bit platforms we assign the results to private
+ unsigned long variables, then assign these to the lvalues the user
+ specified, which works no matter what type 'leaked', 'dubious', etc
+ are. We also initialise '_qzz_leaked', etc because
+ VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as
+ defined. */ \
+ {unsigned long _qzz_res; \
+ unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \
+ unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__COUNT_LEAK_BLOCKS, \
+ &_qzz_leaked, &_qzz_dubious, \
+ &_qzz_reachable, &_qzz_suppressed, 0); \
+ leaked = _qzz_leaked; \
+ dubious = _qzz_dubious; \
+ reachable = _qzz_reachable; \
+ suppressed = _qzz_suppressed; \
+ }
+
+
+/* Get the validity data for addresses [zza..zza+zznbytes-1] and copy it
+ into the provided zzvbits array. Return values:
+ 0 if not running on valgrind
+ 1 success
+ 2 [previously indicated unaligned arrays; these are now allowed]
+ 3 if any parts of zzsrc/zzvbits are not addressable.
+ The metadata is not copied in cases 0, 2 or 3 so it should be
+ impossible to segfault your system by using this call.
+*/
+#define VALGRIND_GET_VBITS(zza,zzvbits,zznbytes) \
+ (__extension__({unsigned long _qzz_res; \
+ char* czza = (char*)zza; \
+ char* czzvbits = (char*)zzvbits; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__GET_VBITS, \
+ czza, czzvbits, zznbytes, 0, 0 ); \
+ _qzz_res; \
+ }))
+
+/* Set the validity data for addresses [zza..zza+zznbytes-1], copying it
+ from the provided zzvbits array. Return values:
+ 0 if not running on valgrind
+ 1 success
+ 2 [previously indicated unaligned arrays; these are now allowed]
+ 3 if any parts of zza/zzvbits are not addressable.
+ The metadata is not copied in cases 0, 2 or 3 so it should be
+ impossible to segfault your system by using this call.
+*/
+#define VALGRIND_SET_VBITS(zza,zzvbits,zznbytes) \
+ (__extension__({unsigned int _qzz_res; \
+ char* czza = (char*)zza; \
+ char* czzvbits = (char*)zzvbits; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__SET_VBITS, \
+ czza, czzvbits, zznbytes, 0, 0 ); \
+ _qzz_res; \
+ }))
+
+#endif
+
diff --git a/qemu/roms/ipxe/src/include/valgrind/valgrind.h b/qemu/roms/ipxe/src/include/valgrind/valgrind.h
new file mode 100644
index 000000000..d48bbccae
--- /dev/null
+++ b/qemu/roms/ipxe/src/include/valgrind/valgrind.h
@@ -0,0 +1,4538 @@
+/* -*- c -*-
+ ----------------------------------------------------------------
+
+ Notice that the following BSD-style license applies to this one
+ file (valgrind.h) only. The rest of Valgrind is licensed under the
+ terms of the GNU General Public License, version 2, unless
+ otherwise indicated. See the COPYING file in the source
+ distribution for details.
+
+ ----------------------------------------------------------------
+
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2010 Julian 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.
+
+ ----------------------------------------------------------------
+
+ Notice that the above BSD-style license applies to this one file
+ (valgrind.h) only. The entire rest of Valgrind is licensed under
+ the terms of the GNU General Public License, version 2. See the
+ COPYING file in the source distribution for details.
+
+ ----------------------------------------------------------------
+*/
+
+
+/* This file is for inclusion into client (your!) code.
+
+ You can use these macros to manipulate and query Valgrind's
+ execution inside your own programs.
+
+ The resulting executables will still run without Valgrind, just a
+ little bit more slowly than they otherwise would, but otherwise
+ unchanged. When not running on valgrind, each client request
+ consumes very few (eg. 7) instructions, so the resulting performance
+ loss is negligible unless you plan to execute client requests
+ millions of times per second. Nevertheless, if that is still a
+ problem, you can compile with the NVALGRIND symbol defined (gcc
+ -DNVALGRIND) so that client requests are not even compiled in. */
+
+#ifndef __VALGRIND_H
+#define __VALGRIND_H
+
+FILE_LICENCE ( BSD3 );
+
+
+/* ------------------------------------------------------------------ */
+/* VERSION NUMBER OF VALGRIND */
+/* ------------------------------------------------------------------ */
+
+/* Specify Valgrind's version number, so that user code can
+ conditionally compile based on our version number. Note that these
+ were introduced at version 3.6 and so do not exist in version 3.5
+ or earlier. The recommended way to use them to check for "version
+ X.Y or later" is (eg)
+
+#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \
+ && (__VALGRIND_MAJOR__ > 3 \
+ || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
+*/
+#define __VALGRIND_MAJOR__ 3
+#define __VALGRIND_MINOR__ 6
+
+
+#include <stdarg.h>
+
+/* Nb: this file might be included in a file compiled with -ansi. So
+ we can't use C++ style "//" comments nor the "asm" keyword (instead
+ use "__asm__"). */
+
+/* Derive some tags indicating what the target platform is. Note
+ that in this file we're using the compiler's CPP symbols for
+ identifying architectures, which are different to the ones we use
+ within the rest of Valgrind. Note, __powerpc__ is active for both
+ 32 and 64-bit PPC, whereas __powerpc64__ is only active for the
+ latter (on Linux, that is).
+
+ Misc note: how to find out what's predefined in gcc by default:
+ gcc -Wp,-dM somefile.c
+*/
+#undef PLAT_ppc64_aix5
+#undef PLAT_ppc32_aix5
+#undef PLAT_x86_darwin
+#undef PLAT_amd64_darwin
+#undef PLAT_x86_linux
+#undef PLAT_amd64_linux
+#undef PLAT_ppc32_linux
+#undef PLAT_ppc64_linux
+#undef PLAT_arm_linux
+
+#if defined(_AIX) && defined(__64BIT__)
+# define PLAT_ppc64_aix5 1
+#elif defined(_AIX) && !defined(__64BIT__)
+# define PLAT_ppc32_aix5 1
+#elif defined(__APPLE__) && defined(__i386__)
+# define PLAT_x86_darwin 1
+#elif defined(__APPLE__) && defined(__x86_64__)
+# define PLAT_amd64_darwin 1
+#elif defined(__linux__) && defined(__i386__)
+# define PLAT_x86_linux 1
+#elif defined(__linux__) && defined(__x86_64__)
+# define PLAT_amd64_linux 1
+#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
+# define PLAT_ppc32_linux 1
+#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
+# define PLAT_ppc64_linux 1
+#elif defined(__linux__) && defined(__arm__)
+# define PLAT_arm_linux 1
+#else
+/* If we're not compiling for our target platform, don't generate
+ any inline asms. */
+# if !defined(NVALGRIND)
+# define NVALGRIND 1
+# endif
+#endif
+
+
+/* ------------------------------------------------------------------ */
+/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */
+/* in here of use to end-users -- skip to the next section. */
+/* ------------------------------------------------------------------ */
+
+#if defined(NVALGRIND)
+
+/* Define NVALGRIND to completely remove the Valgrind magic sequence
+ from the compiled code (analogous to NDEBUG's effects on
+ assert()) */
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
+ { \
+ (_zzq_rlval) = (_zzq_default); \
+ }
+
+#else /* ! NVALGRIND */
+
+/* The following defines the magic code sequences which the JITter
+ spots and handles magically. Don't look too closely at them as
+ they will rot your brain.
+
+ The assembly code sequences for all architectures is in this one
+ file. This is because this file must be stand-alone, and we don't
+ want to have multiple files.
+
+ For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
+ value gets put in the return slot, so that everything works when
+ this is executed not under Valgrind. Args are passed in a memory
+ block, and so there's no intrinsic limit to the number that could
+ be passed, but it's currently five.
+
+ The macro args are:
+ _zzq_rlval result lvalue
+ _zzq_default default value (result returned when running on real CPU)
+ _zzq_request request code
+ _zzq_arg1..5 request params
+
+ The other two macros are used to support function wrapping, and are
+ a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the
+ guest's NRADDR pseudo-register and whatever other information is
+ needed to safely run the call original from the wrapper: on
+ ppc64-linux, the R2 value at the divert point is also needed. This
+ information is abstracted into a user-visible type, OrigFn.
+
+ VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
+ guest, but guarantees that the branch instruction will not be
+ redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
+ branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a
+ complete inline asm, since it needs to be combined with more magic
+ inline asm stuff to be useful.
+*/
+
+/* ------------------------- x86-{linux,darwin} ---------------- */
+
+#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin)
+
+typedef
+ struct {
+ unsigned int nraddr; /* where's the code? */
+ }
+ OrigFn;
+
+#define __SPECIAL_INSTRUCTION_PREAMBLE \
+ "roll $3, %%edi ; roll $13, %%edi\n\t" \
+ "roll $29, %%edi ; roll $19, %%edi\n\t"
+
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
+ { volatile unsigned int _zzq_args[6]; \
+ volatile unsigned int _zzq_result; \
+ _zzq_args[0] = (unsigned int)(_zzq_request); \
+ _zzq_args[1] = (unsigned int)(_zzq_arg1); \
+ _zzq_args[2] = (unsigned int)(_zzq_arg2); \
+ _zzq_args[3] = (unsigned int)(_zzq_arg3); \
+ _zzq_args[4] = (unsigned int)(_zzq_arg4); \
+ _zzq_args[5] = (unsigned int)(_zzq_arg5); \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %EDX = client_request ( %EAX ) */ \
+ "xchgl %%ebx,%%ebx" \
+ : "=d" (_zzq_result) \
+ : "a" (&_zzq_args[0]), "0" (_zzq_default) \
+ : "cc", "memory" \
+ ); \
+ _zzq_rlval = _zzq_result; \
+ }
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
+ volatile unsigned int __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %EAX = guest_NRADDR */ \
+ "xchgl %%ecx,%%ecx" \
+ : "=a" (__addr) \
+ : \
+ : "cc", "memory" \
+ ); \
+ _zzq_orig->nraddr = __addr; \
+ }
+
+#define VALGRIND_CALL_NOREDIR_EAX \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* call-noredir *%EAX */ \
+ "xchgl %%edx,%%edx\n\t"
+#endif /* PLAT_x86_linux || PLAT_x86_darwin */
+
+/* ------------------------ amd64-{linux,darwin} --------------- */
+
+#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin)
+
+typedef
+ struct {
+ unsigned long long int nraddr; /* where's the code? */
+ }
+ OrigFn;
+
+#define __SPECIAL_INSTRUCTION_PREAMBLE \
+ "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \
+ "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
+
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
+ { volatile unsigned long long int _zzq_args[6]; \
+ volatile unsigned long long int _zzq_result; \
+ _zzq_args[0] = (unsigned long long int)(_zzq_request); \
+ _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
+ _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
+ _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
+ _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
+ _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %RDX = client_request ( %RAX ) */ \
+ "xchgq %%rbx,%%rbx" \
+ : "=d" (_zzq_result) \
+ : "a" (&_zzq_args[0]), "0" (_zzq_default) \
+ : "cc", "memory" \
+ ); \
+ _zzq_rlval = _zzq_result; \
+ }
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
+ volatile unsigned long long int __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %RAX = guest_NRADDR */ \
+ "xchgq %%rcx,%%rcx" \
+ : "=a" (__addr) \
+ : \
+ : "cc", "memory" \
+ ); \
+ _zzq_orig->nraddr = __addr; \
+ }
+
+#define VALGRIND_CALL_NOREDIR_RAX \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* call-noredir *%RAX */ \
+ "xchgq %%rdx,%%rdx\n\t"
+#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
+
+/* ------------------------ ppc32-linux ------------------------ */
+
+#if defined(PLAT_ppc32_linux)
+
+typedef
+ struct {
+ unsigned int nraddr; /* where's the code? */
+ }
+ OrigFn;
+
+#define __SPECIAL_INSTRUCTION_PREAMBLE \
+ "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \
+ "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
+
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
+ \
+ { unsigned int _zzq_args[6]; \
+ unsigned int _zzq_result; \
+ unsigned int* _zzq_ptr; \
+ _zzq_args[0] = (unsigned int)(_zzq_request); \
+ _zzq_args[1] = (unsigned int)(_zzq_arg1); \
+ _zzq_args[2] = (unsigned int)(_zzq_arg2); \
+ _zzq_args[3] = (unsigned int)(_zzq_arg3); \
+ _zzq_args[4] = (unsigned int)(_zzq_arg4); \
+ _zzq_args[5] = (unsigned int)(_zzq_arg5); \
+ _zzq_ptr = _zzq_args; \
+ __asm__ volatile("mr 3,%1\n\t" /*default*/ \
+ "mr 4,%2\n\t" /*ptr*/ \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %R3 = client_request ( %R4 ) */ \
+ "or 1,1,1\n\t" \
+ "mr %0,3" /*result*/ \
+ : "=b" (_zzq_result) \
+ : "b" (_zzq_default), "b" (_zzq_ptr) \
+ : "cc", "memory", "r3", "r4"); \
+ _zzq_rlval = _zzq_result; \
+ }
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
+ unsigned int __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %R3 = guest_NRADDR */ \
+ "or 2,2,2\n\t" \
+ "mr %0,3" \
+ : "=b" (__addr) \
+ : \
+ : "cc", "memory", "r3" \
+ ); \
+ _zzq_orig->nraddr = __addr; \
+ }
+
+#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* branch-and-link-to-noredir *%R11 */ \
+ "or 3,3,3\n\t"
+#endif /* PLAT_ppc32_linux */
+
+/* ------------------------ ppc64-linux ------------------------ */
+
+#if defined(PLAT_ppc64_linux)
+
+typedef
+ struct {
+ unsigned long long int nraddr; /* where's the code? */
+ unsigned long long int r2; /* what tocptr do we need? */
+ }
+ OrigFn;
+
+#define __SPECIAL_INSTRUCTION_PREAMBLE \
+ "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
+ "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
+
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
+ \
+ { unsigned long long int _zzq_args[6]; \
+ register unsigned long long int _zzq_result __asm__("r3"); \
+ register unsigned long long int* _zzq_ptr __asm__("r4"); \
+ _zzq_args[0] = (unsigned long long int)(_zzq_request); \
+ _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
+ _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
+ _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
+ _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
+ _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \
+ _zzq_ptr = _zzq_args; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %R3 = client_request ( %R4 ) */ \
+ "or 1,1,1" \
+ : "=r" (_zzq_result) \
+ : "0" (_zzq_default), "r" (_zzq_ptr) \
+ : "cc", "memory"); \
+ _zzq_rlval = _zzq_result; \
+ }
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
+ register unsigned long long int __addr __asm__("r3"); \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %R3 = guest_NRADDR */ \
+ "or 2,2,2" \
+ : "=r" (__addr) \
+ : \
+ : "cc", "memory" \
+ ); \
+ _zzq_orig->nraddr = __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %R3 = guest_NRADDR_GPR2 */ \
+ "or 4,4,4" \
+ : "=r" (__addr) \
+ : \
+ : "cc", "memory" \
+ ); \
+ _zzq_orig->r2 = __addr; \
+ }
+
+#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* branch-and-link-to-noredir *%R11 */ \
+ "or 3,3,3\n\t"
+
+#endif /* PLAT_ppc64_linux */
+
+/* ------------------------- arm-linux ------------------------- */
+
+#if defined(PLAT_arm_linux)
+
+typedef
+ struct {
+ unsigned int nraddr; /* where's the code? */
+ }
+ OrigFn;
+
+#define __SPECIAL_INSTRUCTION_PREAMBLE \
+ "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \
+ "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
+
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
+ \
+ { volatile unsigned int _zzq_args[6]; \
+ volatile unsigned int _zzq_result; \
+ _zzq_args[0] = (unsigned int)(_zzq_request); \
+ _zzq_args[1] = (unsigned int)(_zzq_arg1); \
+ _zzq_args[2] = (unsigned int)(_zzq_arg2); \
+ _zzq_args[3] = (unsigned int)(_zzq_arg3); \
+ _zzq_args[4] = (unsigned int)(_zzq_arg4); \
+ _zzq_args[5] = (unsigned int)(_zzq_arg5); \
+ __asm__ volatile("mov r3, %1\n\t" /*default*/ \
+ "mov r4, %2\n\t" /*ptr*/ \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* R3 = client_request ( R4 ) */ \
+ "orr r10, r10, r10\n\t" \
+ "mov %0, r3" /*result*/ \
+ : "=r" (_zzq_result) \
+ : "r" (_zzq_default), "r" (&_zzq_args[0]) \
+ : "cc","memory", "r3", "r4"); \
+ _zzq_rlval = _zzq_result; \
+ }
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
+ unsigned int __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* R3 = guest_NRADDR */ \
+ "orr r11, r11, r11\n\t" \
+ "mov %0, r3" \
+ : "=r" (__addr) \
+ : \
+ : "cc", "memory", "r3" \
+ ); \
+ _zzq_orig->nraddr = __addr; \
+ }
+
+#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* branch-and-link-to-noredir *%R4 */ \
+ "orr r12, r12, r12\n\t"
+
+#endif /* PLAT_arm_linux */
+
+/* ------------------------ ppc32-aix5 ------------------------- */
+
+#if defined(PLAT_ppc32_aix5)
+
+typedef
+ struct {
+ unsigned int nraddr; /* where's the code? */
+ unsigned int r2; /* what tocptr do we need? */
+ }
+ OrigFn;
+
+#define __SPECIAL_INSTRUCTION_PREAMBLE \
+ "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \
+ "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
+
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
+ \
+ { unsigned int _zzq_args[7]; \
+ register unsigned int _zzq_result; \
+ register unsigned int* _zzq_ptr; \
+ _zzq_args[0] = (unsigned int)(_zzq_request); \
+ _zzq_args[1] = (unsigned int)(_zzq_arg1); \
+ _zzq_args[2] = (unsigned int)(_zzq_arg2); \
+ _zzq_args[3] = (unsigned int)(_zzq_arg3); \
+ _zzq_args[4] = (unsigned int)(_zzq_arg4); \
+ _zzq_args[5] = (unsigned int)(_zzq_arg5); \
+ _zzq_args[6] = (unsigned int)(_zzq_default); \
+ _zzq_ptr = _zzq_args; \
+ __asm__ volatile("mr 4,%1\n\t" \
+ "lwz 3, 24(4)\n\t" \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %R3 = client_request ( %R4 ) */ \
+ "or 1,1,1\n\t" \
+ "mr %0,3" \
+ : "=b" (_zzq_result) \
+ : "b" (_zzq_ptr) \
+ : "r3", "r4", "cc", "memory"); \
+ _zzq_rlval = _zzq_result; \
+ }
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
+ register unsigned int __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %R3 = guest_NRADDR */ \
+ "or 2,2,2\n\t" \
+ "mr %0,3" \
+ : "=b" (__addr) \
+ : \
+ : "r3", "cc", "memory" \
+ ); \
+ _zzq_orig->nraddr = __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %R3 = guest_NRADDR_GPR2 */ \
+ "or 4,4,4\n\t" \
+ "mr %0,3" \
+ : "=b" (__addr) \
+ : \
+ : "r3", "cc", "memory" \
+ ); \
+ _zzq_orig->r2 = __addr; \
+ }
+
+#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* branch-and-link-to-noredir *%R11 */ \
+ "or 3,3,3\n\t"
+
+#endif /* PLAT_ppc32_aix5 */
+
+/* ------------------------ ppc64-aix5 ------------------------- */
+
+#if defined(PLAT_ppc64_aix5)
+
+typedef
+ struct {
+ unsigned long long int nraddr; /* where's the code? */
+ unsigned long long int r2; /* what tocptr do we need? */
+ }
+ OrigFn;
+
+#define __SPECIAL_INSTRUCTION_PREAMBLE \
+ "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
+ "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
+
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
+ \
+ { unsigned long long int _zzq_args[7]; \
+ register unsigned long long int _zzq_result; \
+ register unsigned long long int* _zzq_ptr; \
+ _zzq_args[0] = (unsigned int long long)(_zzq_request); \
+ _zzq_args[1] = (unsigned int long long)(_zzq_arg1); \
+ _zzq_args[2] = (unsigned int long long)(_zzq_arg2); \
+ _zzq_args[3] = (unsigned int long long)(_zzq_arg3); \
+ _zzq_args[4] = (unsigned int long long)(_zzq_arg4); \
+ _zzq_args[5] = (unsigned int long long)(_zzq_arg5); \
+ _zzq_args[6] = (unsigned int long long)(_zzq_default); \
+ _zzq_ptr = _zzq_args; \
+ __asm__ volatile("mr 4,%1\n\t" \
+ "ld 3, 48(4)\n\t" \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %R3 = client_request ( %R4 ) */ \
+ "or 1,1,1\n\t" \
+ "mr %0,3" \
+ : "=b" (_zzq_result) \
+ : "b" (_zzq_ptr) \
+ : "r3", "r4", "cc", "memory"); \
+ _zzq_rlval = _zzq_result; \
+ }
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
+ register unsigned long long int __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %R3 = guest_NRADDR */ \
+ "or 2,2,2\n\t" \
+ "mr %0,3" \
+ : "=b" (__addr) \
+ : \
+ : "r3", "cc", "memory" \
+ ); \
+ _zzq_orig->nraddr = __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %R3 = guest_NRADDR_GPR2 */ \
+ "or 4,4,4\n\t" \
+ "mr %0,3" \
+ : "=b" (__addr) \
+ : \
+ : "r3", "cc", "memory" \
+ ); \
+ _zzq_orig->r2 = __addr; \
+ }
+
+#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* branch-and-link-to-noredir *%R11 */ \
+ "or 3,3,3\n\t"
+
+#endif /* PLAT_ppc64_aix5 */
+
+/* Insert assembly code for other platforms here... */
+
+#endif /* NVALGRIND */
+
+
+/* ------------------------------------------------------------------ */
+/* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */
+/* ugly. It's the least-worst tradeoff I can think of. */
+/* ------------------------------------------------------------------ */
+
+/* This section defines magic (a.k.a appalling-hack) macros for doing
+ guaranteed-no-redirection macros, so as to get from function
+ wrappers to the functions they are wrapping. The whole point is to
+ construct standard call sequences, but to do the call itself with a
+ special no-redirect call pseudo-instruction that the JIT
+ understands and handles specially. This section is long and
+ repetitious, and I can't see a way to make it shorter.
+
+ The naming scheme is as follows:
+
+ CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
+
+ 'W' stands for "word" and 'v' for "void". Hence there are
+ different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
+ and for each, the possibility of returning a word-typed result, or
+ no result.
+*/
+
+/* Use these to write the name of your wrapper. NOTE: duplicates
+ VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
+
+/* Use an extra level of macroisation so as to ensure the soname/fnname
+ args are fully macro-expanded before pasting them together. */
+#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
+
+#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \
+ VG_CONCAT4(_vgwZU_,soname,_,fnname)
+
+#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \
+ VG_CONCAT4(_vgwZZ_,soname,_,fnname)
+
+/* Use this macro from within a wrapper function to collect the
+ context (address and possibly other info) of the original function.
+ Once you have that you can then use it in one of the CALL_FN_
+ macros. The type of the argument _lval is OrigFn. */
+#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval)
+
+/* Derivatives of the main macros below, for calling functions
+ returning void. */
+
+#define CALL_FN_v_v(fnptr) \
+ do { volatile unsigned long _junk; \
+ CALL_FN_W_v(_junk,fnptr); } while (0)
+
+#define CALL_FN_v_W(fnptr, arg1) \
+ do { volatile unsigned long _junk; \
+ CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
+
+#define CALL_FN_v_WW(fnptr, arg1,arg2) \
+ do { volatile unsigned long _junk; \
+ CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
+
+#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \
+ do { volatile unsigned long _junk; \
+ CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
+
+#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4) \
+ do { volatile unsigned long _junk; \
+ CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
+
+#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5) \
+ do { volatile unsigned long _junk; \
+ CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
+
+#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \
+ do { volatile unsigned long _junk; \
+ CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
+
+#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7) \
+ do { volatile unsigned long _junk; \
+ CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
+
+/* ------------------------- x86-{linux,darwin} ---------------- */
+
+#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin)
+
+/* These regs are trashed by the hidden call. No need to mention eax
+ as gcc can already see that, plus causes gcc to bomb. */
+#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
+
+/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
+ long) == 4. */
+
+#define CALL_FN_W_v(lval, orig) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[1]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ __asm__ volatile( \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_W(lval, orig, arg1) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[2]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ __asm__ volatile( \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $4, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ __asm__ volatile( \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $8, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[4]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ __asm__ volatile( \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $12, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[5]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ __asm__ volatile( \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $16, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[6]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ __asm__ volatile( \
+ "pushl 20(%%eax)\n\t" \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $20, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[7]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ __asm__ volatile( \
+ "pushl 24(%%eax)\n\t" \
+ "pushl 20(%%eax)\n\t" \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $24, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[8]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ __asm__ volatile( \
+ "pushl 28(%%eax)\n\t" \
+ "pushl 24(%%eax)\n\t" \
+ "pushl 20(%%eax)\n\t" \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $28, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[9]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ __asm__ volatile( \
+ "pushl 32(%%eax)\n\t" \
+ "pushl 28(%%eax)\n\t" \
+ "pushl 24(%%eax)\n\t" \
+ "pushl 20(%%eax)\n\t" \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $32, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[10]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ __asm__ volatile( \
+ "pushl 36(%%eax)\n\t" \
+ "pushl 32(%%eax)\n\t" \
+ "pushl 28(%%eax)\n\t" \
+ "pushl 24(%%eax)\n\t" \
+ "pushl 20(%%eax)\n\t" \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $36, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[11]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ __asm__ volatile( \
+ "pushl 40(%%eax)\n\t" \
+ "pushl 36(%%eax)\n\t" \
+ "pushl 32(%%eax)\n\t" \
+ "pushl 28(%%eax)\n\t" \
+ "pushl 24(%%eax)\n\t" \
+ "pushl 20(%%eax)\n\t" \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $40, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
+ arg6,arg7,arg8,arg9,arg10, \
+ arg11) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[12]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ _argvec[11] = (unsigned long)(arg11); \
+ __asm__ volatile( \
+ "pushl 44(%%eax)\n\t" \
+ "pushl 40(%%eax)\n\t" \
+ "pushl 36(%%eax)\n\t" \
+ "pushl 32(%%eax)\n\t" \
+ "pushl 28(%%eax)\n\t" \
+ "pushl 24(%%eax)\n\t" \
+ "pushl 20(%%eax)\n\t" \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $44, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
+ arg6,arg7,arg8,arg9,arg10, \
+ arg11,arg12) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[13]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ _argvec[11] = (unsigned long)(arg11); \
+ _argvec[12] = (unsigned long)(arg12); \
+ __asm__ volatile( \
+ "pushl 48(%%eax)\n\t" \
+ "pushl 44(%%eax)\n\t" \
+ "pushl 40(%%eax)\n\t" \
+ "pushl 36(%%eax)\n\t" \
+ "pushl 32(%%eax)\n\t" \
+ "pushl 28(%%eax)\n\t" \
+ "pushl 24(%%eax)\n\t" \
+ "pushl 20(%%eax)\n\t" \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $48, %%esp\n" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#endif /* PLAT_x86_linux || PLAT_x86_darwin */
+
+/* ------------------------ amd64-{linux,darwin} --------------- */
+
+#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin)
+
+/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
+
+/* These regs are trashed by the hidden call. */
+#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \
+ "rdi", "r8", "r9", "r10", "r11"
+
+/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
+ long) == 8. */
+
+/* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_
+ macros. In order not to trash the stack redzone, we need to drop
+ %rsp by 128 before the hidden call, and restore afterwards. The
+ nastyness is that it is only by luck that the stack still appears
+ to be unwindable during the hidden call - since then the behaviour
+ of any routine using this macro does not match what the CFI data
+ says. Sigh.
+
+ Why is this important? Imagine that a wrapper has a stack
+ allocated local, and passes to the hidden call, a pointer to it.
+ Because gcc does not know about the hidden call, it may allocate
+ that local in the redzone. Unfortunately the hidden call may then
+ trash it before it comes to use it. So we must step clear of the
+ redzone, for the duration of the hidden call, to make it safe.
+
+ Probably the same problem afflicts the other redzone-style ABIs too
+ (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is
+ self describing (none of this CFI nonsense) so at least messing
+ with the stack pointer doesn't give a danger of non-unwindable
+ stack. */
+
+#define CALL_FN_W_v(lval, orig) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[1]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_W(lval, orig, arg1) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[2]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "movq 16(%%rax), %%rsi\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[4]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "movq 24(%%rax), %%rdx\n\t" \
+ "movq 16(%%rax), %%rsi\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[5]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "movq 32(%%rax), %%rcx\n\t" \
+ "movq 24(%%rax), %%rdx\n\t" \
+ "movq 16(%%rax), %%rsi\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[6]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "movq 40(%%rax), %%r8\n\t" \
+ "movq 32(%%rax), %%rcx\n\t" \
+ "movq 24(%%rax), %%rdx\n\t" \
+ "movq 16(%%rax), %%rsi\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[7]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "movq 48(%%rax), %%r9\n\t" \
+ "movq 40(%%rax), %%r8\n\t" \
+ "movq 32(%%rax), %%rcx\n\t" \
+ "movq 24(%%rax), %%rdx\n\t" \
+ "movq 16(%%rax), %%rsi\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ "addq $128,%%rsp\n\t" \
+ VALGRIND_CALL_NOREDIR_RAX \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[8]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "pushq 56(%%rax)\n\t" \
+ "movq 48(%%rax), %%r9\n\t" \
+ "movq 40(%%rax), %%r8\n\t" \
+ "movq 32(%%rax), %%rcx\n\t" \
+ "movq 24(%%rax), %%rdx\n\t" \
+ "movq 16(%%rax), %%rsi\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $8, %%rsp\n" \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[9]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "pushq 64(%%rax)\n\t" \
+ "pushq 56(%%rax)\n\t" \
+ "movq 48(%%rax), %%r9\n\t" \
+ "movq 40(%%rax), %%r8\n\t" \
+ "movq 32(%%rax), %%rcx\n\t" \
+ "movq 24(%%rax), %%rdx\n\t" \
+ "movq 16(%%rax), %%rsi\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $16, %%rsp\n" \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[10]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "pushq 72(%%rax)\n\t" \
+ "pushq 64(%%rax)\n\t" \
+ "pushq 56(%%rax)\n\t" \
+ "movq 48(%%rax), %%r9\n\t" \
+ "movq 40(%%rax), %%r8\n\t" \
+ "movq 32(%%rax), %%rcx\n\t" \
+ "movq 24(%%rax), %%rdx\n\t" \
+ "movq 16(%%rax), %%rsi\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $24, %%rsp\n" \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[11]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "pushq 80(%%rax)\n\t" \
+ "pushq 72(%%rax)\n\t" \
+ "pushq 64(%%rax)\n\t" \
+ "pushq 56(%%rax)\n\t" \
+ "movq 48(%%rax), %%r9\n\t" \
+ "movq 40(%%rax), %%r8\n\t" \
+ "movq 32(%%rax), %%rcx\n\t" \
+ "movq 24(%%rax), %%rdx\n\t" \
+ "movq 16(%%rax), %%rsi\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $32, %%rsp\n" \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10,arg11) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[12]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ _argvec[11] = (unsigned long)(arg11); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "pushq 88(%%rax)\n\t" \
+ "pushq 80(%%rax)\n\t" \
+ "pushq 72(%%rax)\n\t" \
+ "pushq 64(%%rax)\n\t" \
+ "pushq 56(%%rax)\n\t" \
+ "movq 48(%%rax), %%r9\n\t" \
+ "movq 40(%%rax), %%r8\n\t" \
+ "movq 32(%%rax), %%rcx\n\t" \
+ "movq 24(%%rax), %%rdx\n\t" \
+ "movq 16(%%rax), %%rsi\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $40, %%rsp\n" \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10,arg11,arg12) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[13]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ _argvec[11] = (unsigned long)(arg11); \
+ _argvec[12] = (unsigned long)(arg12); \
+ __asm__ volatile( \
+ "subq $128,%%rsp\n\t" \
+ "pushq 96(%%rax)\n\t" \
+ "pushq 88(%%rax)\n\t" \
+ "pushq 80(%%rax)\n\t" \
+ "pushq 72(%%rax)\n\t" \
+ "pushq 64(%%rax)\n\t" \
+ "pushq 56(%%rax)\n\t" \
+ "movq 48(%%rax), %%r9\n\t" \
+ "movq 40(%%rax), %%r8\n\t" \
+ "movq 32(%%rax), %%rcx\n\t" \
+ "movq 24(%%rax), %%rdx\n\t" \
+ "movq 16(%%rax), %%rsi\n\t" \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ "addq $48, %%rsp\n" \
+ "addq $128,%%rsp\n\t" \
+ : /*out*/ "=a" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
+
+/* ------------------------ ppc32-linux ------------------------ */
+
+#if defined(PLAT_ppc32_linux)
+
+/* This is useful for finding out about the on-stack stuff:
+
+ extern int f9 ( int,int,int,int,int,int,int,int,int );
+ extern int f10 ( int,int,int,int,int,int,int,int,int,int );
+ extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
+ extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
+
+ int g9 ( void ) {
+ return f9(11,22,33,44,55,66,77,88,99);
+ }
+ int g10 ( void ) {
+ return f10(11,22,33,44,55,66,77,88,99,110);
+ }
+ int g11 ( void ) {
+ return f11(11,22,33,44,55,66,77,88,99,110,121);
+ }
+ int g12 ( void ) {
+ return f12(11,22,33,44,55,66,77,88,99,110,121,132);
+ }
+*/
+
+/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
+
+/* These regs are trashed by the hidden call. */
+#define __CALLER_SAVED_REGS \
+ "lr", "ctr", "xer", \
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
+ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
+ "r11", "r12", "r13"
+
+/* These CALL_FN_ macros assume that on ppc32-linux,
+ sizeof(unsigned long) == 4. */
+
+#define CALL_FN_W_v(lval, orig) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[1]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_W(lval, orig, arg1) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[2]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ _argvec[2] = (unsigned long)arg2; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4,8(11)\n\t" \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[4]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ _argvec[2] = (unsigned long)arg2; \
+ _argvec[3] = (unsigned long)arg3; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4,8(11)\n\t" \
+ "lwz 5,12(11)\n\t" \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[5]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ _argvec[2] = (unsigned long)arg2; \
+ _argvec[3] = (unsigned long)arg3; \
+ _argvec[4] = (unsigned long)arg4; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4,8(11)\n\t" \
+ "lwz 5,12(11)\n\t" \
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[6]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ _argvec[2] = (unsigned long)arg2; \
+ _argvec[3] = (unsigned long)arg3; \
+ _argvec[4] = (unsigned long)arg4; \
+ _argvec[5] = (unsigned long)arg5; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4,8(11)\n\t" \
+ "lwz 5,12(11)\n\t" \
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7,20(11)\n\t" \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[7]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ _argvec[2] = (unsigned long)arg2; \
+ _argvec[3] = (unsigned long)arg3; \
+ _argvec[4] = (unsigned long)arg4; \
+ _argvec[5] = (unsigned long)arg5; \
+ _argvec[6] = (unsigned long)arg6; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4,8(11)\n\t" \
+ "lwz 5,12(11)\n\t" \
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7,20(11)\n\t" \
+ "lwz 8,24(11)\n\t" \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[8]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ _argvec[2] = (unsigned long)arg2; \
+ _argvec[3] = (unsigned long)arg3; \
+ _argvec[4] = (unsigned long)arg4; \
+ _argvec[5] = (unsigned long)arg5; \
+ _argvec[6] = (unsigned long)arg6; \
+ _argvec[7] = (unsigned long)arg7; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4,8(11)\n\t" \
+ "lwz 5,12(11)\n\t" \
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7,20(11)\n\t" \
+ "lwz 8,24(11)\n\t" \
+ "lwz 9,28(11)\n\t" \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[9]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ _argvec[2] = (unsigned long)arg2; \
+ _argvec[3] = (unsigned long)arg3; \
+ _argvec[4] = (unsigned long)arg4; \
+ _argvec[5] = (unsigned long)arg5; \
+ _argvec[6] = (unsigned long)arg6; \
+ _argvec[7] = (unsigned long)arg7; \
+ _argvec[8] = (unsigned long)arg8; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4,8(11)\n\t" \
+ "lwz 5,12(11)\n\t" \
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7,20(11)\n\t" \
+ "lwz 8,24(11)\n\t" \
+ "lwz 9,28(11)\n\t" \
+ "lwz 10,32(11)\n\t" /* arg8->r10 */ \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[10]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ _argvec[2] = (unsigned long)arg2; \
+ _argvec[3] = (unsigned long)arg3; \
+ _argvec[4] = (unsigned long)arg4; \
+ _argvec[5] = (unsigned long)arg5; \
+ _argvec[6] = (unsigned long)arg6; \
+ _argvec[7] = (unsigned long)arg7; \
+ _argvec[8] = (unsigned long)arg8; \
+ _argvec[9] = (unsigned long)arg9; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "addi 1,1,-16\n\t" \
+ /* arg9 */ \
+ "lwz 3,36(11)\n\t" \
+ "stw 3,8(1)\n\t" \
+ /* args1-8 */ \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4,8(11)\n\t" \
+ "lwz 5,12(11)\n\t" \
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7,20(11)\n\t" \
+ "lwz 8,24(11)\n\t" \
+ "lwz 9,28(11)\n\t" \
+ "lwz 10,32(11)\n\t" /* arg8->r10 */ \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "addi 1,1,16\n\t" \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[11]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ _argvec[2] = (unsigned long)arg2; \
+ _argvec[3] = (unsigned long)arg3; \
+ _argvec[4] = (unsigned long)arg4; \
+ _argvec[5] = (unsigned long)arg5; \
+ _argvec[6] = (unsigned long)arg6; \
+ _argvec[7] = (unsigned long)arg7; \
+ _argvec[8] = (unsigned long)arg8; \
+ _argvec[9] = (unsigned long)arg9; \
+ _argvec[10] = (unsigned long)arg10; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "addi 1,1,-16\n\t" \
+ /* arg10 */ \
+ "lwz 3,40(11)\n\t" \
+ "stw 3,12(1)\n\t" \
+ /* arg9 */ \
+ "lwz 3,36(11)\n\t" \
+ "stw 3,8(1)\n\t" \
+ /* args1-8 */ \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4,8(11)\n\t" \
+ "lwz 5,12(11)\n\t" \
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7,20(11)\n\t" \
+ "lwz 8,24(11)\n\t" \
+ "lwz 9,28(11)\n\t" \
+ "lwz 10,32(11)\n\t" /* arg8->r10 */ \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "addi 1,1,16\n\t" \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10,arg11) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[12]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ _argvec[2] = (unsigned long)arg2; \
+ _argvec[3] = (unsigned long)arg3; \
+ _argvec[4] = (unsigned long)arg4; \
+ _argvec[5] = (unsigned long)arg5; \
+ _argvec[6] = (unsigned long)arg6; \
+ _argvec[7] = (unsigned long)arg7; \
+ _argvec[8] = (unsigned long)arg8; \
+ _argvec[9] = (unsigned long)arg9; \
+ _argvec[10] = (unsigned long)arg10; \
+ _argvec[11] = (unsigned long)arg11; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "addi 1,1,-32\n\t" \
+ /* arg11 */ \
+ "lwz 3,44(11)\n\t" \
+ "stw 3,16(1)\n\t" \
+ /* arg10 */ \
+ "lwz 3,40(11)\n\t" \
+ "stw 3,12(1)\n\t" \
+ /* arg9 */ \
+ "lwz 3,36(11)\n\t" \
+ "stw 3,8(1)\n\t" \
+ /* args1-8 */ \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4,8(11)\n\t" \
+ "lwz 5,12(11)\n\t" \
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7,20(11)\n\t" \
+ "lwz 8,24(11)\n\t" \
+ "lwz 9,28(11)\n\t" \
+ "lwz 10,32(11)\n\t" /* arg8->r10 */ \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "addi 1,1,32\n\t" \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10,arg11,arg12) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[13]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)arg1; \
+ _argvec[2] = (unsigned long)arg2; \
+ _argvec[3] = (unsigned long)arg3; \
+ _argvec[4] = (unsigned long)arg4; \
+ _argvec[5] = (unsigned long)arg5; \
+ _argvec[6] = (unsigned long)arg6; \
+ _argvec[7] = (unsigned long)arg7; \
+ _argvec[8] = (unsigned long)arg8; \
+ _argvec[9] = (unsigned long)arg9; \
+ _argvec[10] = (unsigned long)arg10; \
+ _argvec[11] = (unsigned long)arg11; \
+ _argvec[12] = (unsigned long)arg12; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "addi 1,1,-32\n\t" \
+ /* arg12 */ \
+ "lwz 3,48(11)\n\t" \
+ "stw 3,20(1)\n\t" \
+ /* arg11 */ \
+ "lwz 3,44(11)\n\t" \
+ "stw 3,16(1)\n\t" \
+ /* arg10 */ \
+ "lwz 3,40(11)\n\t" \
+ "stw 3,12(1)\n\t" \
+ /* arg9 */ \
+ "lwz 3,36(11)\n\t" \
+ "stw 3,8(1)\n\t" \
+ /* args1-8 */ \
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4,8(11)\n\t" \
+ "lwz 5,12(11)\n\t" \
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7,20(11)\n\t" \
+ "lwz 8,24(11)\n\t" \
+ "lwz 9,28(11)\n\t" \
+ "lwz 10,32(11)\n\t" /* arg8->r10 */ \
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "addi 1,1,32\n\t" \
+ "mr %0,3" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#endif /* PLAT_ppc32_linux */
+
+/* ------------------------ ppc64-linux ------------------------ */
+
+#if defined(PLAT_ppc64_linux)
+
+/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
+
+/* These regs are trashed by the hidden call. */
+#define __CALLER_SAVED_REGS \
+ "lr", "ctr", "xer", \
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
+ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
+ "r11", "r12", "r13"
+
+/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
+ long) == 8. */
+
+#define CALL_FN_W_v(lval, orig) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+0]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)" /* restore tocptr */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_W(lval, orig, arg1) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+1]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)" /* restore tocptr */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+2]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)" /* restore tocptr */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+3]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)" /* restore tocptr */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+4]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)" /* restore tocptr */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+5]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)" /* restore tocptr */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+6]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)" /* restore tocptr */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+7]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)" /* restore tocptr */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+8]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)" /* restore tocptr */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+9]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "addi 1,1,-128\n\t" /* expand stack frame */ \
+ /* arg9 */ \
+ "ld 3,72(11)\n\t" \
+ "std 3,112(1)\n\t" \
+ /* args1-8 */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ "addi 1,1,128" /* restore frame */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+10]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ _argvec[2+10] = (unsigned long)arg10; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "addi 1,1,-128\n\t" /* expand stack frame */ \
+ /* arg10 */ \
+ "ld 3,80(11)\n\t" \
+ "std 3,120(1)\n\t" \
+ /* arg9 */ \
+ "ld 3,72(11)\n\t" \
+ "std 3,112(1)\n\t" \
+ /* args1-8 */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ "addi 1,1,128" /* restore frame */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10,arg11) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+11]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ _argvec[2+10] = (unsigned long)arg10; \
+ _argvec[2+11] = (unsigned long)arg11; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "addi 1,1,-144\n\t" /* expand stack frame */ \
+ /* arg11 */ \
+ "ld 3,88(11)\n\t" \
+ "std 3,128(1)\n\t" \
+ /* arg10 */ \
+ "ld 3,80(11)\n\t" \
+ "std 3,120(1)\n\t" \
+ /* arg9 */ \
+ "ld 3,72(11)\n\t" \
+ "std 3,112(1)\n\t" \
+ /* args1-8 */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ "addi 1,1,144" /* restore frame */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10,arg11,arg12) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+12]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ _argvec[2+10] = (unsigned long)arg10; \
+ _argvec[2+11] = (unsigned long)arg11; \
+ _argvec[2+12] = (unsigned long)arg12; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "addi 1,1,-144\n\t" /* expand stack frame */ \
+ /* arg12 */ \
+ "ld 3,96(11)\n\t" \
+ "std 3,136(1)\n\t" \
+ /* arg11 */ \
+ "ld 3,88(11)\n\t" \
+ "std 3,128(1)\n\t" \
+ /* arg10 */ \
+ "ld 3,80(11)\n\t" \
+ "std 3,120(1)\n\t" \
+ /* arg9 */ \
+ "ld 3,72(11)\n\t" \
+ "std 3,112(1)\n\t" \
+ /* args1-8 */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ "addi 1,1,144" /* restore frame */ \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#endif /* PLAT_ppc64_linux */
+
+/* ------------------------- arm-linux ------------------------- */
+
+#if defined(PLAT_arm_linux)
+
+/* These regs are trashed by the hidden call. */
+#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
+
+/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
+ long) == 4. */
+
+#define CALL_FN_W_v(lval, orig) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[1]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ __asm__ volatile( \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "mov %0, r0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_W(lval, orig, arg1) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[2]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "mov %0, r0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r1, [%1, #8] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "mov %0, r0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[4]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r1, [%1, #8] \n\t" \
+ "ldr r2, [%1, #12] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "mov %0, r0\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[5]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r1, [%1, #8] \n\t" \
+ "ldr r2, [%1, #12] \n\t" \
+ "ldr r3, [%1, #16] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "mov %0, r0" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[6]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #20] \n\t" \
+ "push {r0} \n\t" \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r1, [%1, #8] \n\t" \
+ "ldr r2, [%1, #12] \n\t" \
+ "ldr r3, [%1, #16] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "add sp, sp, #4 \n\t" \
+ "mov %0, r0" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[7]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #20] \n\t" \
+ "ldr r1, [%1, #24] \n\t" \
+ "push {r0, r1} \n\t" \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r1, [%1, #8] \n\t" \
+ "ldr r2, [%1, #12] \n\t" \
+ "ldr r3, [%1, #16] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "add sp, sp, #8 \n\t" \
+ "mov %0, r0" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[8]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #20] \n\t" \
+ "ldr r1, [%1, #24] \n\t" \
+ "ldr r2, [%1, #28] \n\t" \
+ "push {r0, r1, r2} \n\t" \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r1, [%1, #8] \n\t" \
+ "ldr r2, [%1, #12] \n\t" \
+ "ldr r3, [%1, #16] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "add sp, sp, #12 \n\t" \
+ "mov %0, r0" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[9]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #20] \n\t" \
+ "ldr r1, [%1, #24] \n\t" \
+ "ldr r2, [%1, #28] \n\t" \
+ "ldr r3, [%1, #32] \n\t" \
+ "push {r0, r1, r2, r3} \n\t" \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r1, [%1, #8] \n\t" \
+ "ldr r2, [%1, #12] \n\t" \
+ "ldr r3, [%1, #16] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "add sp, sp, #16 \n\t" \
+ "mov %0, r0" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[10]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #20] \n\t" \
+ "ldr r1, [%1, #24] \n\t" \
+ "ldr r2, [%1, #28] \n\t" \
+ "ldr r3, [%1, #32] \n\t" \
+ "ldr r4, [%1, #36] \n\t" \
+ "push {r0, r1, r2, r3, r4} \n\t" \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r1, [%1, #8] \n\t" \
+ "ldr r2, [%1, #12] \n\t" \
+ "ldr r3, [%1, #16] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "add sp, sp, #20 \n\t" \
+ "mov %0, r0" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[11]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #40] \n\t" \
+ "push {r0} \n\t" \
+ "ldr r0, [%1, #20] \n\t" \
+ "ldr r1, [%1, #24] \n\t" \
+ "ldr r2, [%1, #28] \n\t" \
+ "ldr r3, [%1, #32] \n\t" \
+ "ldr r4, [%1, #36] \n\t" \
+ "push {r0, r1, r2, r3, r4} \n\t" \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r1, [%1, #8] \n\t" \
+ "ldr r2, [%1, #12] \n\t" \
+ "ldr r3, [%1, #16] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "add sp, sp, #24 \n\t" \
+ "mov %0, r0" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
+ arg6,arg7,arg8,arg9,arg10, \
+ arg11) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[12]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ _argvec[11] = (unsigned long)(arg11); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #40] \n\t" \
+ "ldr r1, [%1, #44] \n\t" \
+ "push {r0, r1} \n\t" \
+ "ldr r0, [%1, #20] \n\t" \
+ "ldr r1, [%1, #24] \n\t" \
+ "ldr r2, [%1, #28] \n\t" \
+ "ldr r3, [%1, #32] \n\t" \
+ "ldr r4, [%1, #36] \n\t" \
+ "push {r0, r1, r2, r3, r4} \n\t" \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r1, [%1, #8] \n\t" \
+ "ldr r2, [%1, #12] \n\t" \
+ "ldr r3, [%1, #16] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "add sp, sp, #28 \n\t" \
+ "mov %0, r0" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory",__CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
+ arg6,arg7,arg8,arg9,arg10, \
+ arg11,arg12) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[13]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ _argvec[11] = (unsigned long)(arg11); \
+ _argvec[12] = (unsigned long)(arg12); \
+ __asm__ volatile( \
+ "ldr r0, [%1, #40] \n\t" \
+ "ldr r1, [%1, #44] \n\t" \
+ "ldr r2, [%1, #48] \n\t" \
+ "push {r0, r1, r2} \n\t" \
+ "ldr r0, [%1, #20] \n\t" \
+ "ldr r1, [%1, #24] \n\t" \
+ "ldr r2, [%1, #28] \n\t" \
+ "ldr r3, [%1, #32] \n\t" \
+ "ldr r4, [%1, #36] \n\t" \
+ "push {r0, r1, r2, r3, r4} \n\t" \
+ "ldr r0, [%1, #4] \n\t" \
+ "ldr r1, [%1, #8] \n\t" \
+ "ldr r2, [%1, #12] \n\t" \
+ "ldr r3, [%1, #16] \n\t" \
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
+ "add sp, sp, #32 \n\t" \
+ "mov %0, r0" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#endif /* PLAT_arm_linux */
+
+/* ------------------------ ppc32-aix5 ------------------------- */
+
+#if defined(PLAT_ppc32_aix5)
+
+/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
+
+/* These regs are trashed by the hidden call. */
+#define __CALLER_SAVED_REGS \
+ "lr", "ctr", "xer", \
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
+ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
+ "r11", "r12", "r13"
+
+/* Expand the stack frame, copying enough info that unwinding
+ still works. Trashes r3. */
+
+#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \
+ "addi 1,1,-" #_n_fr "\n\t" \
+ "lwz 3," #_n_fr "(1)\n\t" \
+ "stw 3,0(1)\n\t"
+
+#define VG_CONTRACT_FRAME_BY(_n_fr) \
+ "addi 1,1," #_n_fr "\n\t"
+
+/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned
+ long) == 4. */
+
+#define CALL_FN_W_v(lval, orig) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+0]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_W(lval, orig, arg1) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+1]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+2]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+3]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+4]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+5]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+6]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+7]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+8]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
+ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+9]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ VG_EXPAND_FRAME_BY_trashes_r3(64) \
+ /* arg9 */ \
+ "lwz 3,36(11)\n\t" \
+ "stw 3,56(1)\n\t" \
+ /* args1-8 */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
+ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(64) \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+10]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ _argvec[2+10] = (unsigned long)arg10; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ VG_EXPAND_FRAME_BY_trashes_r3(64) \
+ /* arg10 */ \
+ "lwz 3,40(11)\n\t" \
+ "stw 3,60(1)\n\t" \
+ /* arg9 */ \
+ "lwz 3,36(11)\n\t" \
+ "stw 3,56(1)\n\t" \
+ /* args1-8 */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
+ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(64) \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10,arg11) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+11]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ _argvec[2+10] = (unsigned long)arg10; \
+ _argvec[2+11] = (unsigned long)arg11; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ VG_EXPAND_FRAME_BY_trashes_r3(72) \
+ /* arg11 */ \
+ "lwz 3,44(11)\n\t" \
+ "stw 3,64(1)\n\t" \
+ /* arg10 */ \
+ "lwz 3,40(11)\n\t" \
+ "stw 3,60(1)\n\t" \
+ /* arg9 */ \
+ "lwz 3,36(11)\n\t" \
+ "stw 3,56(1)\n\t" \
+ /* args1-8 */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
+ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(72) \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10,arg11,arg12) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+12]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ _argvec[2+10] = (unsigned long)arg10; \
+ _argvec[2+11] = (unsigned long)arg11; \
+ _argvec[2+12] = (unsigned long)arg12; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
+ VG_EXPAND_FRAME_BY_trashes_r3(72) \
+ /* arg12 */ \
+ "lwz 3,48(11)\n\t" \
+ "stw 3,68(1)\n\t" \
+ /* arg11 */ \
+ "lwz 3,44(11)\n\t" \
+ "stw 3,64(1)\n\t" \
+ /* arg10 */ \
+ "lwz 3,40(11)\n\t" \
+ "stw 3,60(1)\n\t" \
+ /* arg9 */ \
+ "lwz 3,36(11)\n\t" \
+ "stw 3,56(1)\n\t" \
+ /* args1-8 */ \
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
+ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(72) \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#endif /* PLAT_ppc32_aix5 */
+
+/* ------------------------ ppc64-aix5 ------------------------- */
+
+#if defined(PLAT_ppc64_aix5)
+
+/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
+
+/* These regs are trashed by the hidden call. */
+#define __CALLER_SAVED_REGS \
+ "lr", "ctr", "xer", \
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
+ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
+ "r11", "r12", "r13"
+
+/* Expand the stack frame, copying enough info that unwinding
+ still works. Trashes r3. */
+
+#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \
+ "addi 1,1,-" #_n_fr "\n\t" \
+ "ld 3," #_n_fr "(1)\n\t" \
+ "std 3,0(1)\n\t"
+
+#define VG_CONTRACT_FRAME_BY(_n_fr) \
+ "addi 1,1," #_n_fr "\n\t"
+
+/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned
+ long) == 8. */
+
+#define CALL_FN_W_v(lval, orig) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+0]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_W(lval, orig, arg1) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+1]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+2]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+3]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+4]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+5]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+6]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+7]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+8]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+9]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ VG_EXPAND_FRAME_BY_trashes_r3(128) \
+ /* arg9 */ \
+ "ld 3,72(11)\n\t" \
+ "std 3,112(1)\n\t" \
+ /* args1-8 */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(128) \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+10]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ _argvec[2+10] = (unsigned long)arg10; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ VG_EXPAND_FRAME_BY_trashes_r3(128) \
+ /* arg10 */ \
+ "ld 3,80(11)\n\t" \
+ "std 3,120(1)\n\t" \
+ /* arg9 */ \
+ "ld 3,72(11)\n\t" \
+ "std 3,112(1)\n\t" \
+ /* args1-8 */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(128) \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10,arg11) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+11]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ _argvec[2+10] = (unsigned long)arg10; \
+ _argvec[2+11] = (unsigned long)arg11; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ VG_EXPAND_FRAME_BY_trashes_r3(144) \
+ /* arg11 */ \
+ "ld 3,88(11)\n\t" \
+ "std 3,128(1)\n\t" \
+ /* arg10 */ \
+ "ld 3,80(11)\n\t" \
+ "std 3,120(1)\n\t" \
+ /* arg9 */ \
+ "ld 3,72(11)\n\t" \
+ "std 3,112(1)\n\t" \
+ /* args1-8 */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(144) \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10,arg11,arg12) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3+12]; \
+ volatile unsigned long _res; \
+ /* _argvec[0] holds current r2 across the call */ \
+ _argvec[1] = (unsigned long)_orig.r2; \
+ _argvec[2] = (unsigned long)_orig.nraddr; \
+ _argvec[2+1] = (unsigned long)arg1; \
+ _argvec[2+2] = (unsigned long)arg2; \
+ _argvec[2+3] = (unsigned long)arg3; \
+ _argvec[2+4] = (unsigned long)arg4; \
+ _argvec[2+5] = (unsigned long)arg5; \
+ _argvec[2+6] = (unsigned long)arg6; \
+ _argvec[2+7] = (unsigned long)arg7; \
+ _argvec[2+8] = (unsigned long)arg8; \
+ _argvec[2+9] = (unsigned long)arg9; \
+ _argvec[2+10] = (unsigned long)arg10; \
+ _argvec[2+11] = (unsigned long)arg11; \
+ _argvec[2+12] = (unsigned long)arg12; \
+ __asm__ volatile( \
+ "mr 11,%1\n\t" \
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
+ "std 2,-16(11)\n\t" /* save tocptr */ \
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
+ VG_EXPAND_FRAME_BY_trashes_r3(144) \
+ /* arg12 */ \
+ "ld 3,96(11)\n\t" \
+ "std 3,136(1)\n\t" \
+ /* arg11 */ \
+ "ld 3,88(11)\n\t" \
+ "std 3,128(1)\n\t" \
+ /* arg10 */ \
+ "ld 3,80(11)\n\t" \
+ "std 3,120(1)\n\t" \
+ /* arg9 */ \
+ "ld 3,72(11)\n\t" \
+ "std 3,112(1)\n\t" \
+ /* args1-8 */ \
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
+ "mr 11,%1\n\t" \
+ "mr %0,3\n\t" \
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
+ VG_CONTRACT_FRAME_BY(144) \
+ VG_CONTRACT_FRAME_BY(512) \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[2]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#endif /* PLAT_ppc64_aix5 */
+
+
+/* ------------------------------------------------------------------ */
+/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */
+/* */
+/* ------------------------------------------------------------------ */
+
+/* Some request codes. There are many more of these, but most are not
+ exposed to end-user view. These are the public ones, all of the
+ form 0x1000 + small_number.
+
+ Core ones are in the range 0x00000000--0x0000ffff. The non-public
+ ones start at 0x2000.
+*/
+
+/* These macros are used by tools -- they must be public, but don't
+ embed them into other programs. */
+#define VG_USERREQ_TOOL_BASE(a,b) \
+ ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
+#define VG_IS_TOOL_USERREQ(a, b, v) \
+ (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
+
+/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
+ This enum comprises an ABI exported by Valgrind to programs
+ which use client requests. DO NOT CHANGE THE ORDER OF THESE
+ ENTRIES, NOR DELETE ANY -- add new ones at the end. */
+typedef
+ enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001,
+ VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
+
+ /* These allow any function to be called from the simulated
+ CPU but run on the real CPU. Nb: the first arg passed to
+ the function is always the ThreadId of the running
+ thread! So CLIENT_CALL0 actually requires a 1 arg
+ function, etc. */
+ VG_USERREQ__CLIENT_CALL0 = 0x1101,
+ VG_USERREQ__CLIENT_CALL1 = 0x1102,
+ VG_USERREQ__CLIENT_CALL2 = 0x1103,
+ VG_USERREQ__CLIENT_CALL3 = 0x1104,
+
+ /* Can be useful in regression testing suites -- eg. can
+ send Valgrind's output to /dev/null and still count
+ errors. */
+ VG_USERREQ__COUNT_ERRORS = 0x1201,
+
+ /* These are useful and can be interpreted by any tool that
+ tracks malloc() et al, by using vg_replace_malloc.c. */
+ VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
+ VG_USERREQ__FREELIKE_BLOCK = 0x1302,
+ /* Memory pool support. */
+ VG_USERREQ__CREATE_MEMPOOL = 0x1303,
+ VG_USERREQ__DESTROY_MEMPOOL = 0x1304,
+ VG_USERREQ__MEMPOOL_ALLOC = 0x1305,
+ VG_USERREQ__MEMPOOL_FREE = 0x1306,
+ VG_USERREQ__MEMPOOL_TRIM = 0x1307,
+ VG_USERREQ__MOVE_MEMPOOL = 0x1308,
+ VG_USERREQ__MEMPOOL_CHANGE = 0x1309,
+ VG_USERREQ__MEMPOOL_EXISTS = 0x130a,
+
+ /* Allow printfs to valgrind log. */
+ /* The first two pass the va_list argument by value, which
+ assumes it is the same size as or smaller than a UWord,
+ which generally isn't the case. Hence are deprecated.
+ The second two pass the vargs by reference and so are
+ immune to this problem. */
+ /* both :: char* fmt, va_list vargs (DEPRECATED) */
+ VG_USERREQ__PRINTF = 0x1401,
+ VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
+ /* both :: char* fmt, va_list* vargs */
+ VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
+ VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,
+
+ /* Stack support. */
+ VG_USERREQ__STACK_REGISTER = 0x1501,
+ VG_USERREQ__STACK_DEREGISTER = 0x1502,
+ VG_USERREQ__STACK_CHANGE = 0x1503,
+
+ /* Wine support */
+ VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601
+ } Vg_ClientRequest;
+
+#if !defined(__GNUC__)
+# define __extension__ /* */
+#endif
+
+/* Returns the number of Valgrinds this code is running under. That
+ is, 0 if running natively, 1 if running under Valgrind, 2 if
+ running under Valgrind which is running under another Valgrind,
+ etc. */
+#define RUNNING_ON_VALGRIND __extension__ \
+ ({unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */, \
+ VG_USERREQ__RUNNING_ON_VALGRIND, \
+ 0, 0, 0, 0, 0); \
+ _qzz_res; \
+ })
+
+
+/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
+ _qzz_len - 1]. Useful if you are debugging a JITter or some such,
+ since it provides a way to make sure valgrind will retranslate the
+ invalidated area. Returns no value. */
+#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__DISCARD_TRANSLATIONS, \
+ _qzz_addr, _qzz_len, 0, 0, 0); \
+ }
+
+
+/* These requests are for getting Valgrind itself to print something.
+ Possibly with a backtrace. This is a really ugly hack. The return value
+ is the number of characters printed, excluding the "**<pid>** " part at the
+ start and the backtrace (if present). */
+
+#if defined(NVALGRIND)
+
+# define VALGRIND_PRINTF(...)
+# define VALGRIND_PRINTF_BACKTRACE(...)
+
+#else /* NVALGRIND */
+
+/* Modern GCC will optimize the static routine out if unused,
+ and unused attribute will shut down warnings about it. */
+static int VALGRIND_PRINTF(const char *format, ...)
+ __attribute__((format(__printf__, 1, 2), __unused__));
+static int
+VALGRIND_PRINTF(const char *format, ...)
+{
+ unsigned long _qzz_res;
+ va_list vargs;
+ va_start(vargs, format);
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,
+ VG_USERREQ__PRINTF_VALIST_BY_REF,
+ (unsigned long)format,
+ (unsigned long)&vargs,
+ 0, 0, 0);
+ va_end(vargs);
+ return (int)_qzz_res;
+}
+
+static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
+ __attribute__((format(__printf__, 1, 2), __unused__));
+static int
+VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
+{
+ unsigned long _qzz_res;
+ va_list vargs;
+ va_start(vargs, format);
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,
+ VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
+ (unsigned long)format,
+ (unsigned long)&vargs,
+ 0, 0, 0);
+ va_end(vargs);
+ return (int)_qzz_res;
+}
+
+#endif /* NVALGRIND */
+
+
+/* These requests allow control to move from the simulated CPU to the
+ real CPU, calling an arbitary function.
+
+ Note that the current ThreadId is inserted as the first argument.
+ So this call:
+
+ VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
+
+ requires f to have this signature:
+
+ Word f(Word tid, Word arg1, Word arg2)
+
+ where "Word" is a word-sized type.
+
+ Note that these client requests are not entirely reliable. For example,
+ if you call a function with them that subsequently calls printf(),
+ there's a high chance Valgrind will crash. Generally, your prospects of
+ these working are made higher if the called function does not refer to
+ any global variables, and does not refer to any libc or other functions
+ (printf et al). Any kind of entanglement with libc or dynamic linking is
+ likely to have a bad outcome, for tricky reasons which we've grappled
+ with a lot in the past.
+*/
+#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \
+ __extension__ \
+ ({unsigned long _qyy_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_CALL0, \
+ _qyy_fn, \
+ 0, 0, 0, 0); \
+ _qyy_res; \
+ })
+
+#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \
+ __extension__ \
+ ({unsigned long _qyy_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_CALL1, \
+ _qyy_fn, \
+ _qyy_arg1, 0, 0, 0); \
+ _qyy_res; \
+ })
+
+#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \
+ __extension__ \
+ ({unsigned long _qyy_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_CALL2, \
+ _qyy_fn, \
+ _qyy_arg1, _qyy_arg2, 0, 0); \
+ _qyy_res; \
+ })
+
+#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
+ __extension__ \
+ ({unsigned long _qyy_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_CALL3, \
+ _qyy_fn, \
+ _qyy_arg1, _qyy_arg2, \
+ _qyy_arg3, 0); \
+ _qyy_res; \
+ })
+
+
+/* Counts the number of errors that have been recorded by a tool. Nb:
+ the tool must record the errors with VG_(maybe_record_error)() or
+ VG_(unique_error)() for them to be counted. */
+#define VALGRIND_COUNT_ERRORS \
+ __extension__ \
+ ({unsigned int _qyy_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__COUNT_ERRORS, \
+ 0, 0, 0, 0, 0); \
+ _qyy_res; \
+ })
+
+/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
+ when heap blocks are allocated in order to give accurate results. This
+ happens automatically for the standard allocator functions such as
+ malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
+ delete[], etc.
+
+ But if your program uses a custom allocator, this doesn't automatically
+ happen, and Valgrind will not do as well. For example, if you allocate
+ superblocks with mmap() and then allocates chunks of the superblocks, all
+ Valgrind's observations will be at the mmap() level and it won't know that
+ the chunks should be considered separate entities. In Memcheck's case,
+ that means you probably won't get heap block overrun detection (because
+ there won't be redzones marked as unaddressable) and you definitely won't
+ get any leak detection.
+
+ The following client requests allow a custom allocator to be annotated so
+ that it can be handled accurately by Valgrind.
+
+ VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
+ by a malloc()-like function. For Memcheck (an illustrative case), this
+ does two things:
+
+ - It records that the block has been allocated. This means any addresses
+ within the block mentioned in error messages will be
+ identified as belonging to the block. It also means that if the block
+ isn't freed it will be detected by the leak checker.
+
+ - It marks the block as being addressable and undefined (if 'is_zeroed' is
+ not set), or addressable and defined (if 'is_zeroed' is set). This
+ controls how accesses to the block by the program are handled.
+
+ 'addr' is the start of the usable block (ie. after any
+ redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator
+ can apply redzones -- these are blocks of padding at the start and end of
+ each block. Adding redzones is recommended as it makes it much more likely
+ Valgrind will spot block overruns. `is_zeroed' indicates if the memory is
+ zeroed (or filled with another predictable value), as is the case for
+ calloc().
+
+ VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
+ heap block -- that will be used by the client program -- is allocated.
+ It's best to put it at the outermost level of the allocator if possible;
+ for example, if you have a function my_alloc() which calls
+ internal_alloc(), and the client request is put inside internal_alloc(),
+ stack traces relating to the heap block will contain entries for both
+ my_alloc() and internal_alloc(), which is probably not what you want.
+
+ For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
+ custom blocks from within a heap block, B, that has been allocated with
+ malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
+ -- the custom blocks will take precedence.
+
+ VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK. For
+ Memcheck, it does two things:
+
+ - It records that the block has been deallocated. This assumes that the
+ block was annotated as having been allocated via
+ VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued.
+
+ - It marks the block as being unaddressable.
+
+ VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
+ heap block is deallocated.
+
+ In many cases, these two client requests will not be enough to get your
+ allocator working well with Memcheck. More specifically, if your allocator
+ writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
+ will be necessary to mark the memory as addressable just before the zeroing
+ occurs, otherwise you'll get a lot of invalid write errors. For example,
+ you'll need to do this if your allocator recycles freed blocks, but it
+ zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
+ Alternatively, if your allocator reuses freed blocks for allocator-internal
+ data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
+
+ Really, what's happening is a blurring of the lines between the client
+ program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
+ memory should be considered unaddressable to the client program, but the
+ allocator knows more than the rest of the client program and so may be able
+ to safely access it. Extra client requests are necessary for Valgrind to
+ understand the distinction between the allocator and the rest of the
+ program.
+
+ Note: there is currently no VALGRIND_REALLOCLIKE_BLOCK client request; it
+ has to be emulated with MALLOCLIKE/FREELIKE and memory copying.
+
+ Ignored if addr == 0.
+*/
+#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
+ {unsigned int __unused _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__MALLOCLIKE_BLOCK, \
+ addr, sizeB, rzB, is_zeroed, 0); \
+ }
+
+/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
+ Ignored if addr == 0.
+*/
+#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
+ {unsigned int __unused _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__FREELIKE_BLOCK, \
+ addr, rzB, 0, 0, 0); \
+ }
+
+/* Create a memory pool. */
+#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__CREATE_MEMPOOL, \
+ pool, rzB, is_zeroed, 0, 0); \
+ }
+
+/* Destroy a memory pool. */
+#define VALGRIND_DESTROY_MEMPOOL(pool) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__DESTROY_MEMPOOL, \
+ pool, 0, 0, 0, 0); \
+ }
+
+/* Associate a piece of memory with a memory pool. */
+#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__MEMPOOL_ALLOC, \
+ pool, addr, size, 0, 0); \
+ }
+
+/* Disassociate a piece of memory from a memory pool. */
+#define VALGRIND_MEMPOOL_FREE(pool, addr) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__MEMPOOL_FREE, \
+ pool, addr, 0, 0, 0); \
+ }
+
+/* Disassociate any pieces outside a particular range. */
+#define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__MEMPOOL_TRIM, \
+ pool, addr, size, 0, 0); \
+ }
+
+/* Resize and/or move a piece associated with a memory pool. */
+#define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__MOVE_MEMPOOL, \
+ poolA, poolB, 0, 0, 0); \
+ }
+
+/* Resize and/or move a piece associated with a memory pool. */
+#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__MEMPOOL_CHANGE, \
+ pool, addrA, addrB, size, 0); \
+ }
+
+/* Return 1 if a mempool exists, else 0. */
+#define VALGRIND_MEMPOOL_EXISTS(pool) \
+ __extension__ \
+ ({unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__MEMPOOL_EXISTS, \
+ pool, 0, 0, 0, 0); \
+ _qzz_res; \
+ })
+
+/* Mark a piece of memory as being a stack. Returns a stack id. */
+#define VALGRIND_STACK_REGISTER(start, end) \
+ __extension__ \
+ ({unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__STACK_REGISTER, \
+ start, end, 0, 0, 0); \
+ _qzz_res; \
+ })
+
+/* Unmark the piece of memory associated with a stack id as being a
+ stack. */
+#define VALGRIND_STACK_DEREGISTER(id) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__STACK_DEREGISTER, \
+ id, 0, 0, 0, 0); \
+ }
+
+/* Change the start and end address of the stack id. */
+#define VALGRIND_STACK_CHANGE(id, start, end) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__STACK_CHANGE, \
+ id, start, end, 0, 0); \
+ }
+
+/* Load PDB debug info for Wine PE image_map. */
+#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__LOAD_PDB_DEBUGINFO, \
+ fd, ptr, total_size, delta, 0); \
+ }
+
+
+#undef PLAT_x86_linux
+#undef PLAT_amd64_linux
+#undef PLAT_ppc32_linux
+#undef PLAT_ppc64_linux
+#undef PLAT_arm_linux
+#undef PLAT_ppc32_aix5
+#undef PLAT_ppc64_aix5
+
+#endif /* __VALGRIND_H */
diff --git a/qemu/roms/ipxe/src/include/wchar.h b/qemu/roms/ipxe/src/include/wchar.h
index ba349aae8..d054b8d5b 100644
--- a/qemu/roms/ipxe/src/include/wchar.h
+++ b/qemu/roms/ipxe/src/include/wchar.h
@@ -1,7 +1,7 @@
#ifndef WCHAR_H
#define WCHAR_H
-FILE_LICENCE ( GPL2_ONLY );
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stddef.h>