diff options
Diffstat (limited to 'sys')
550 files changed, 56003 insertions, 6652 deletions
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index fb8473505128..4e710e47fdae 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -309,7 +309,6 @@ device wpi # Intel 3945ABG wireless NICs. device crypto # core crypto support device aesni # AES-NI OpenCrypto module device loop # Network loopback -device rdrand_rng # Intel Bull Mountain RNG device ether # Ethernet support device vlan # 802.1Q VLAN support device tuntap # Packet tunnel. @@ -323,6 +322,13 @@ device xz # lzma decompression # Note that 'bpf' is required for DHCP. device bpf # Berkeley packet filter +# random(4) +device rdrand_rng # Intel Bull Mountain RNG +device tpm # Trusted Platform Module +options RANDOM_ENABLE_TPM # enable entropy from TPM 2.0 +options RANDOM_ENABLE_KBD +options RANDOM_ENABLE_MOUSE + # USB support options USB_DEBUG # enable debug msgs device uhci # UHCI PCI->USB interface diff --git a/sys/amd64/conf/MINIMAL b/sys/amd64/conf/MINIMAL index 61c713c609a4..8df3349b4c34 100644 --- a/sys/amd64/conf/MINIMAL +++ b/sys/amd64/conf/MINIMAL @@ -113,7 +113,6 @@ device uart # Generic UART driver # Pseudo devices. device loop # Network loopback -device rdrand_rng # Intel Bull Mountain RNG device ether # Ethernet support # The `bpf' device enables the Berkeley Packet Filter. @@ -121,6 +120,13 @@ device ether # Ethernet support # Note that 'bpf' is required for DHCP. device bpf # Berkeley packet filter +# random(4) +device rdrand_rng # Intel Bull Mountain RNG +device tpm # Trusted Platform Module +options RANDOM_ENABLE_TPM # enable entropy from TPM 2.0 +options RANDOM_ENABLE_KBD +options RANDOM_ENABLE_MOUSE + # VirtIO support device virtio # Generic VirtIO bus (required) device virtio_pci # VirtIO PCI device diff --git a/sys/amd64/vmm/amd/amdvi_hw.c b/sys/amd64/vmm/amd/amdvi_hw.c index 831c31277570..4dd0339654a9 100644 --- a/sys/amd64/vmm/amd/amdvi_hw.c +++ b/sys/amd64/vmm/amd/amdvi_hw.c @@ -274,6 +274,7 @@ amdvi_get_cmd_tail(struct amdvi_softc *softc) tail = (struct amdvi_cmd *)((uint8_t *)softc->cmd + ctrl->cmd_tail); + memset(tail, 0, sizeof(*tail)); return (tail); } @@ -316,7 +317,6 @@ amdvi_cmd_cmp(struct amdvi_softc *softc, const uint64_t data) uint64_t pa; cmd = amdvi_get_cmd_tail(softc); - KASSERT(cmd != NULL, ("Cmd is NULL")); pa = vtophys(&softc->cmp_data); cmd->opcode = AMDVI_CMP_WAIT_OPCODE; @@ -334,7 +334,6 @@ amdvi_cmd_inv_dte(struct amdvi_softc *softc, uint16_t devid) struct amdvi_cmd *cmd; cmd = amdvi_get_cmd_tail(softc); - KASSERT(cmd != NULL, ("Cmd is NULL")); cmd->opcode = AMDVI_INVD_DTE_OPCODE; cmd->word0 = devid; amdvi_update_cmd_tail(softc); @@ -352,7 +351,6 @@ amdvi_cmd_inv_iommu_pages(struct amdvi_softc *softc, uint16_t domain_id, struct amdvi_cmd *cmd; cmd = amdvi_get_cmd_tail(softc); - KASSERT(cmd != NULL, ("Cmd is NULL")); cmd->opcode = AMDVI_INVD_PAGE_OPCODE; cmd->word1 = domain_id; @@ -383,7 +381,6 @@ amdvi_cmd_inv_iotlb(struct amdvi_softc *softc, uint16_t devid) qlen, RID2PCI_STR(devid)); } cmd = amdvi_get_cmd_tail(softc); - KASSERT(cmd != NULL, ("Cmd is NULL")); #ifdef AMDVI_DEBUG_CMD device_printf(softc->dev, "Invalidate IOTLB devID 0x%x" @@ -406,7 +403,6 @@ amdvi_cmd_inv_intr_map(struct amdvi_softc *softc, struct amdvi_cmd *cmd; cmd = amdvi_get_cmd_tail(softc); - KASSERT(cmd != NULL, ("Cmd is NULL")); cmd->opcode = AMDVI_INVD_INTR_OPCODE; cmd->word0 = devid; amdvi_update_cmd_tail(softc); @@ -420,10 +416,6 @@ amdvi_cmd_inv_intr_map(struct amdvi_softc *softc, static void amdvi_inv_domain(struct amdvi_softc *softc, uint16_t domain_id) { - struct amdvi_cmd *cmd __diagused; - - cmd = amdvi_get_cmd_tail(softc); - KASSERT(cmd != NULL, ("Cmd is NULL")); /* * See section 3.3.3 of IOMMU spec rev 2.0, software note diff --git a/sys/arm/allwinner/a10_codec.c b/sys/arm/allwinner/a10_codec.c index 12d389d24243..d3920eddc1f1 100644 --- a/sys/arm/allwinner/a10_codec.c +++ b/sys/arm/allwinner/a10_codec.c @@ -159,7 +159,7 @@ struct a10codec_chinfo { struct a10codec_info { device_t dev; struct resource *res[2]; - struct mtx *lock; + struct mtx lock; bus_dma_tag_t dmat; unsigned dmasize; void *ih; @@ -680,7 +680,7 @@ a10codec_dmaintr(void *priv) struct a10codec_chinfo *ch = priv; unsigned bufsize; - bufsize = sndbuf_getsize(ch->buffer); + bufsize = ch->buffer->bufsize; ch->pos += ch->blocksize; if (ch->pos >= bufsize) @@ -949,7 +949,7 @@ a10codec_chan_trigger(kobj_t obj, void *data, int go) if (!PCMTRIG_COMMON(go)) return (0); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); switch (go) { case PCMTRIG_START: ch->run = 1; @@ -964,7 +964,7 @@ a10codec_chan_trigger(kobj_t obj, void *data, int go) default: break; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -1075,7 +1075,7 @@ a10codec_attach(device_t dev) sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); sc->cfg = (void *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; sc->dev = dev; - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "a10codec softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "a10codec_softc", MTX_DEF); if (bus_alloc_resources(dev, a10codec_spec, sc->res)) { device_printf(dev, "cannot allocate resources for device\n"); @@ -1180,7 +1180,7 @@ a10codec_attach(device_t dev) fail: bus_release_resources(dev, a10codec_spec, sc->res); - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); free(sc, M_DEVBUF); return (ENXIO); diff --git a/sys/arm/allwinner/aw_i2s.c b/sys/arm/allwinner/aw_i2s.c index 87dfb109363f..31c6d9854171 100644 --- a/sys/arm/allwinner/aw_i2s.c +++ b/sys/arm/allwinner/aw_i2s.c @@ -530,10 +530,10 @@ aw_i2s_dai_intr(device_t dev, struct snd_dbuf *play_buf, struct snd_dbuf *rec_bu val = I2S_READ(sc, DA_FSTA); empty = DA_FSTA_TXE_CNT(val); count = sndbuf_getready(play_buf); - size = sndbuf_getsize(play_buf); + size = play_buf->bufsize; readyptr = sndbuf_getreadyptr(play_buf); - samples = (uint8_t*)sndbuf_getbuf(play_buf); + samples = play_buf->buf; written = 0; if (empty > count / 2) empty = count / 2; @@ -556,9 +556,9 @@ aw_i2s_dai_intr(device_t dev, struct snd_dbuf *play_buf, struct snd_dbuf *rec_bu available = DA_FSTA_RXA_CNT(val); count = sndbuf_getfree(rec_buf); - size = sndbuf_getsize(rec_buf); + size = rec_buf->bufsize; freeptr = sndbuf_getfreeptr(rec_buf); - samples = (uint8_t*)sndbuf_getbuf(rec_buf); + samples = rec_buf->buf; recorded = 0; if (available > count / 2) available = count / 2; diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c index b1b7aacd63ab..c1b2cf626ed8 100644 --- a/sys/arm/arm/gic.c +++ b/sys/arm/arm/gic.c @@ -514,6 +514,12 @@ arm_gic_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) ("arm_gic_read_ivar: Invalid bus type %u", sc->gic_bus)); *result = sc->gic_bus; return (0); + case GIC_IVAR_VGIC: + *result = 0; + return (0); + case GIC_IVAR_SUPPORT_LPIS: + *result = false; + return (0); } return (ENOENT); diff --git a/sys/arm/arm/gic_common.h b/sys/arm/arm/gic_common.h index c45832ec1782..c2d1b1340b9b 100644 --- a/sys/arm/arm/gic_common.h +++ b/sys/arm/arm/gic_common.h @@ -38,6 +38,7 @@ struct arm_gic_range { #define GIC_IVAR_HW_REV 500 #define GIC_IVAR_BUS 501 #define GIC_IVAR_VGIC 502 +#define GIC_IVAR_SUPPORT_LPIS 503 /* GIC_IVAR_BUS values */ #define GIC_BUS_UNKNOWN 0 @@ -48,6 +49,7 @@ struct arm_gic_range { __BUS_ACCESSOR(gic, hw_rev, GIC, HW_REV, u_int); __BUS_ACCESSOR(gic, bus, GIC, BUS, u_int); __BUS_ACCESSOR(gic, vgic, GIC, VGIC, u_int); +__BUS_ACCESSOR(gic, support_lpis, GIC, SUPPORT_LPIS, bool); /* Software Generated Interrupts */ #define GIC_FIRST_SGI 0 /* Irqs 0-15 are SGIs/IPIs. */ diff --git a/sys/arm/broadcom/bcm2835/bcm2835_audio.c b/sys/arm/broadcom/bcm2835/bcm2835_audio.c index 2df6ac76124f..1406fcc3d952 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_audio.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_audio.c @@ -113,6 +113,12 @@ struct bcm2835_audio_chinfo { uint64_t retrieved_samples; uint64_t underruns; int starved; + struct bcm_log_vars { + unsigned int bsize ; + int slept_for_lack_of_space ; + } log_vars; +#define DEFAULT_LOG_VALUES \ + ((struct bcm_log_vars) { .bsize = 0 , .slept_for_lack_of_space = 0 }) }; struct bcm2835_audio_info { @@ -164,6 +170,10 @@ struct bcm2835_audio_info { device_printf((sc)->dev, __VA_ARGS__); \ } while(0) +/* Useful for circular buffer calcs */ +#define MOD_DIFF(front,rear,mod) (((mod) + (front) - (rear)) % (mod)) + + static const char * dest_description(uint32_t dest) { @@ -237,10 +247,21 @@ bcm2835_audio_callback(void *param, const VCHI_CALLBACK_REASON_T reason, void *m m.type); } } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { - struct bcm2835_audio_chinfo *ch = m.u.complete.cookie; + unsigned int signaled = 0; + struct bcm2835_audio_chinfo *ch ; +#if defined(__aarch64__) + ch = (void *) ((((size_t)m.u.complete.callback) << 32) + | ((size_t)m.u.complete.cookie)); +#else + ch = (void *) (m.u.complete.cookie); +#endif int count = m.u.complete.count & 0xffff; int perr = (m.u.complete.count & (1U << 30)) != 0; + + BCM2835_LOG_TRACE(sc, "in:: count:0x%x perr:%d\n", + m.u.complete.count, perr); + ch->callbacks++; if (perr) ch->underruns++; @@ -264,13 +285,31 @@ bcm2835_audio_callback(void *param, const VCHI_CALLBACK_REASON_T reason, void *m (uintmax_t)ch->retrieved_samples, (uintmax_t)ch->submitted_samples); } - ch->available_space += count; - ch->retrieved_samples += count; } - if (perr || (ch->available_space >= VCHIQ_AUDIO_PACKET_SIZE)) - cv_signal(&sc->worker_cv); + ch->available_space += count; + ch->retrieved_samples += count; + /* + * XXXMDC + * Experimental: if VC says it's empty, believe it + * Has to come after the usual adjustments + */ + if(perr){ + ch->available_space = VCHIQ_AUDIO_BUFFER_SIZE; + perr = ch->retrieved_samples; // shd be != 0 + } + + if ((ch->available_space >= 1*VCHIQ_AUDIO_PACKET_SIZE)){ + cv_signal(&sc->worker_cv); + signaled = 1; + } } BCM2835_AUDIO_UNLOCK(sc); + if(perr){ + BCM2835_LOG_WARN(sc, + "VC starved; reported %u for a total of %u\n" + "worker %s\n", count, perr, + (signaled ? "signaled": "not signaled")); + } } else BCM2835_LOG_WARN(sc, "%s: unknown m.type: %d\n", __func__, m.type); @@ -371,6 +410,7 @@ bcm2835_audio_stop(struct bcm2835_audio_chinfo *ch) m.type = VC_AUDIO_MSG_TYPE_STOP; m.u.stop.draining = 0; + BCM2835_LOG_INFO(sc,"sending stop\n"); ret = vchi_msg_queue(sc->vchi_handle, &m, sizeof m, VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL); @@ -449,18 +489,25 @@ static bool bcm2835_audio_buffer_should_sleep(struct bcm2835_audio_chinfo *ch) { + ch->log_vars.slept_for_lack_of_space = 0; if (ch->playback_state != PLAYBACK_PLAYING) return (true); /* Not enough data */ - if (sndbuf_getready(ch->buffer) < VCHIQ_AUDIO_PACKET_SIZE) { - printf("starve\n"); + /* XXXMDC Take unsubmitted stuff into account */ + if (sndbuf_getready(ch->buffer) + - MOD_DIFF( + ch->unsubmittedptr, + sndbuf_getreadyptr(ch->buffer), + ch->buffer->bufsize + ) < VCHIQ_AUDIO_PACKET_SIZE) { ch->starved++; return (true); } /* Not enough free space */ if (ch->available_space < VCHIQ_AUDIO_PACKET_SIZE) { + ch->log_vars.slept_for_lack_of_space = 1; return (true); } @@ -481,8 +528,13 @@ bcm2835_audio_write_samples(struct bcm2835_audio_chinfo *ch, void *buf, uint32_t m.type = VC_AUDIO_MSG_TYPE_WRITE; m.u.write.count = count; m.u.write.max_packet = VCHIQ_AUDIO_PACKET_SIZE; - m.u.write.callback = NULL; - m.u.write.cookie = ch; +#if defined(__aarch64__) + m.u.write.callback = (uint32_t)(((size_t) ch) >> 32) & 0xffffffff; + m.u.write.cookie = (uint32_t)(((size_t) ch) & 0xffffffff); +#else + m.u.write.callback = (uint32_t) NULL; + m.u.write.cookie = (uint32_t) ch; +#endif m.u.write.silence = 0; ret = vchi_msg_queue(sc->vchi_handle, @@ -529,6 +581,11 @@ bcm2835_audio_worker(void *data) while ((sc->flags_pending == 0) && bcm2835_audio_buffer_should_sleep(ch)) { cv_wait_sig(&sc->worker_cv, &sc->lock); + if ((sc->flags_pending == 0) && + (ch->log_vars.slept_for_lack_of_space)) { + BCM2835_LOG_TRACE(sc, + "slept for lack of space\n"); + } } flags = sc->flags_pending; /* Clear pending flags */ @@ -555,16 +612,25 @@ bcm2835_audio_worker(void *data) BCM2835_AUDIO_LOCK(sc); bcm2835_audio_reset_channel(&sc->pch); ch->playback_state = PLAYBACK_IDLE; + long sub_total = ch->submitted_samples; + long retd = ch->retrieved_samples; BCM2835_AUDIO_UNLOCK(sc); + BCM2835_LOG_INFO(sc, + "stopped audio. submitted a total of %lu " + "having been acked %lu\n", sub_total, retd); continue; } /* Requested to start playback */ if ((flags & AUDIO_PLAY) && (ch->playback_state == PLAYBACK_IDLE)) { + BCM2835_LOG_INFO(sc, "starting audio\n"); + unsigned int bsize = ch->buffer->bufsize; BCM2835_AUDIO_LOCK(sc); ch->playback_state = PLAYBACK_PLAYING; + ch->log_vars.bsize = bsize; BCM2835_AUDIO_UNLOCK(sc); + BCM2835_LOG_INFO(sc, "buffer size is %u\n", bsize); bcm2835_audio_start(ch); } @@ -574,29 +640,84 @@ bcm2835_audio_worker(void *data) if (sndbuf_getready(ch->buffer) == 0) continue; - count = sndbuf_getready(ch->buffer); - size = sndbuf_getsize(ch->buffer); - readyptr = sndbuf_getreadyptr(ch->buffer); + uint32_t i_count; + + /* XXXMDC Take unsubmitted stuff into account */ + count = i_count = sndbuf_getready(ch->buffer) + - MOD_DIFF(ch->unsubmittedptr, + sndbuf_getreadyptr(ch->buffer), + ch->buffer->bufsize); + size = ch->buffer->bufsize; + readyptr = ch->unsubmittedptr; + + int size_changed = 0; + unsigned int available; BCM2835_AUDIO_LOCK(sc); - if (readyptr + count > size) + if (size != ch->log_vars.bsize) { + ch->log_vars.bsize = size; + size_changed = 1; + } + available = ch->available_space; + /* + * XXXMDC + * + * On arm64, got into situations where + * readyptr was less than a packet away + * from the end of the buffer, which led + * to count being set to 0 and, inexorably, starvation. + * Code below tries to take that into account. + * The problem might have been fixed with some of the + * other changes that were made in the meantime, + * but for now this works fine. + */ + if (readyptr + count > size) { count = size - readyptr; - count = min(count, ch->available_space); - count -= (count % VCHIQ_AUDIO_PACKET_SIZE); + } + if(count > ch->available_space){ + count = ch->available_space; + count -= (count % VCHIQ_AUDIO_PACKET_SIZE); + }else if (count > VCHIQ_AUDIO_PACKET_SIZE){ + count -= (count % VCHIQ_AUDIO_PACKET_SIZE); + }else if (size > count + readyptr) { + count = 0; + } BCM2835_AUDIO_UNLOCK(sc); - if (count < VCHIQ_AUDIO_PACKET_SIZE) + if (count % VCHIQ_AUDIO_PACKET_SIZE != 0) { + BCM2835_LOG_WARN(sc, "count: %u initial count: %u " + "size: %u readyptr: %u available: %u\n", count, + i_count,size,readyptr,available); + } + if (size_changed) + BCM2835_LOG_INFO(sc, "bsize changed to %u\n", size); + + if (count == 0) { + BCM2835_LOG_WARN(sc, + "not enough room for a packet: count %d," + " i_count %d, rptr %d, size %d\n", + count, i_count, readyptr, size); continue; + } - buf = (uint8_t*)sndbuf_getbuf(ch->buffer) + readyptr; + buf = ch->buffer->buf + readyptr; bcm2835_audio_write_samples(ch, buf, count); BCM2835_AUDIO_LOCK(sc); - ch->unsubmittedptr = (ch->unsubmittedptr + count) % sndbuf_getsize(ch->buffer); + ch->unsubmittedptr = (ch->unsubmittedptr + count) % + ch->buffer->bufsize; ch->available_space -= count; ch->submitted_samples += count; + long sub = count; + long sub_total = ch->submitted_samples; + long retd = ch->retrieved_samples; KASSERT(ch->available_space >= 0, ("ch->available_space == %d\n", ch->available_space)); BCM2835_AUDIO_UNLOCK(sc); + + BCM2835_LOG_TRACE(sc, + "submitted %lu for a total of %lu having been acked %lu; " + "rptr %d, had %u available\n", sub, sub_total, retd, + readyptr, available); } BCM2835_AUDIO_LOCK(sc); @@ -649,6 +770,8 @@ bcmchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel * return NULL; } + ch->log_vars = DEFAULT_LOG_VALUES; + BCM2835_AUDIO_LOCK(sc); bcm2835_worker_update_params(sc); BCM2835_AUDIO_UNLOCK(sc); @@ -662,7 +785,7 @@ bcmchan_free(kobj_t obj, void *data) struct bcm2835_audio_chinfo *ch = data; void *buffer; - buffer = sndbuf_getbuf(ch->buffer); + buffer = ch->buffer->buf; if (buffer) free(buffer, M_DEVBUF); diff --git a/sys/arm/broadcom/bcm2835/vc_vchi_audioserv_defs.h b/sys/arm/broadcom/bcm2835/vc_vchi_audioserv_defs.h index 896e706ff492..ea972ff2d001 100644 --- a/sys/arm/broadcom/bcm2835/vc_vchi_audioserv_defs.h +++ b/sys/arm/broadcom/bcm2835/vc_vchi_audioserv_defs.h @@ -112,8 +112,8 @@ typedef struct typedef struct { uint32_t count; /* in bytes */ - void *callback; - void *cookie; + uint32_t callback; + uint32_t cookie; uint16_t silence; uint16_t max_packet; } VC_AUDIO_WRITE_T; @@ -129,8 +129,8 @@ typedef struct typedef struct { int32_t count; /* Success value */ - void *callback; - void *cookie; + uint32_t callback; + uint32_t cookie; } VC_AUDIO_COMPLETE_T; /* Message header for all messages in HOST->VC direction */ diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC index 22bb75993834..89841947713d 100644 --- a/sys/arm/conf/GENERIC +++ b/sys/arm/conf/GENERIC @@ -216,6 +216,12 @@ device ffec # Freescale Fast Ethernet Controller device neta # Marvell 10/100/1000 Network controller device smsc # SMSC LAN91C111 +# random(4) +device tpm # Trusted Platform Module +options RANDOM_ENABLE_TPM # enable entropy from TPM 2.0 +options RANDOM_ENABLE_KBD +options RANDOM_ENABLE_MOUSE + # Sound support device sound diff --git a/sys/arm/freescale/imx/imx6_ssi.c b/sys/arm/freescale/imx/imx6_ssi.c index cb77f1454e63..76870cfb29c9 100644 --- a/sys/arm/freescale/imx/imx6_ssi.c +++ b/sys/arm/freescale/imx/imx6_ssi.c @@ -173,7 +173,7 @@ struct sc_info { bus_space_tag_t bst; bus_space_handle_t bsh; device_t dev; - struct mtx *lock; + struct mtx lock; void *ih; int pos; int dma_size; @@ -242,10 +242,10 @@ ssimixer_init(struct snd_mixer *m) mask = SOUND_MASK_PCM; mask |= SOUND_MASK_VOLUME; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL); mix_setdevs(m, mask); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -290,14 +290,14 @@ ssichan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, scp = (struct sc_pcminfo *)devinfo; sc = scp->sc; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); ch = &scp->chan[0]; ch->dir = dir; ch->run = 0; ch->buffer = b; ch->channel = c; ch->parent = scp; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); if (sndbuf_setup(ch->buffer, sc->buf_base, sc->dma_size) != 0) { device_printf(scp->dev, "Can't setup sndbuf.\n"); @@ -318,9 +318,9 @@ ssichan_free(kobj_t obj, void *data) device_printf(scp->dev, "ssichan_free()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); /* TODO: free channel buffer */ - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -398,7 +398,7 @@ ssichan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) setup_dma(scp); - return (sndbuf_getblksz(ch->buffer)); + return (ch->buffer->blksz); } uint32_t @@ -415,7 +415,7 @@ ssi_dma_intr(void *arg, int chn) sc = scp->sc; conf = sc->conf; - bufsize = sndbuf_getsize(ch->buffer); + bufsize = ch->buffer->bufsize; sc->pos += conf->period; if (sc->pos >= bufsize) @@ -487,8 +487,8 @@ setup_dma(struct sc_pcminfo *scp) conf->saddr = sc->buf_base_phys; conf->daddr = rman_get_start(sc->res[0]) + SSI_STX0; conf->event = sc->sdma_ev_tx; /* SDMA TX event */ - conf->period = sndbuf_getblksz(ch->buffer); - conf->num_bd = sndbuf_getblkcnt(ch->buffer); + conf->period = ch->buffer->blksz; + conf->num_bd = ch->buffer->blkcnt; /* * Word Length @@ -497,7 +497,7 @@ setup_dma(struct sc_pcminfo *scp) * SSI supports 24 at max. */ - fmt = sndbuf_getfmt(ch->buffer); + fmt = ch->buffer->fmt; if (fmt & AFMT_16BIT) { conf->word_length = 16; @@ -565,7 +565,7 @@ ssichan_trigger(kobj_t obj, void *data, int go) scp = ch->parent; sc = scp->sc; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); switch (go) { case PCMTRIG_START: @@ -590,7 +590,7 @@ ssichan_trigger(kobj_t obj, void *data, int go) break; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -736,7 +736,7 @@ ssi_attach(device_t dev) sc->pos = 0; sc->conf = malloc(sizeof(struct sdma_conf), M_DEVBUF, M_WAITOK | M_ZERO); - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "ssi softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "ssi softc"); if (sc->lock == NULL) { device_printf(dev, "Can't create mtx\n"); return (ENXIO); diff --git a/sys/arm/freescale/vybrid/vf_sai.c b/sys/arm/freescale/vybrid/vf_sai.c index e895529c4810..6ccfcae2bc2e 100644 --- a/sys/arm/freescale/vybrid/vf_sai.c +++ b/sys/arm/freescale/vybrid/vf_sai.c @@ -138,7 +138,7 @@ struct sc_info { bus_space_tag_t bst; bus_space_handle_t bsh; device_t dev; - struct mtx *lock; + struct mtx lock; uint32_t speed; uint32_t period; void *ih; @@ -206,10 +206,10 @@ saimixer_init(struct snd_mixer *m) mask = SOUND_MASK_PCM; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL); mix_setdevs(m, mask); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -252,14 +252,14 @@ saichan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, scp = (struct sc_pcminfo *)devinfo; sc = scp->sc; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); ch = &scp->chan[0]; ch->dir = dir; ch->run = 0; ch->buffer = b; ch->channel = c; ch->parent = scp; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); if (sndbuf_setup(ch->buffer, sc->buf_base, sc->dma_size) != 0) { device_printf(scp->dev, "Can't setup sndbuf.\n"); @@ -280,9 +280,9 @@ saichan_free(kobj_t obj, void *data) device_printf(scp->dev, "saichan_free()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); /* TODO: free channel buffer */ - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -369,7 +369,7 @@ saichan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize); - sc->period = sndbuf_getblksz(ch->buffer); + sc->period = ch->buffer->blksz; return (sc->period); } @@ -513,7 +513,7 @@ saichan_trigger(kobj_t obj, void *data, int go) struct sc_pcminfo *scp = ch->parent; struct sc_info *sc = scp->sc; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); switch (go) { case PCMTRIG_START: @@ -532,7 +532,7 @@ saichan_trigger(kobj_t obj, void *data, int go) break; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -691,7 +691,7 @@ sai_attach(device_t dev) sc->sr = &rate_map[0]; sc->pos = 0; - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sai softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "sai softc"); if (sc->lock == NULL) { device_printf(dev, "Cant create mtx\n"); return (ENXIO); diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c index 201cdae6de09..641b6d6dbc5e 100644 --- a/sys/arm64/arm64/gic_v3.c +++ b/sys/arm64/arm64/gic_v3.c @@ -494,7 +494,7 @@ gic_v3_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) case GICV3_IVAR_REDIST: *result = (uintptr_t)&sc->gic_redists.pcpu[PCPU_GET(cpuid)]; return (0); - case GICV3_IVAR_SUPPORT_LPIS: + case GIC_IVAR_SUPPORT_LPIS: *result = (gic_d_read(sc, 4, GICD_TYPER) & GICD_TYPER_LPIS) != 0; return (0); diff --git a/sys/arm64/arm64/gic_v3_var.h b/sys/arm64/arm64/gic_v3_var.h index 8bc0f456d91e..2570834c2818 100644 --- a/sys/arm64/arm64/gic_v3_var.h +++ b/sys/arm64/arm64/gic_v3_var.h @@ -108,11 +108,9 @@ MALLOC_DECLARE(M_GIC_V3); #define GICV3_IVAR_NIRQS 1000 /* 1001 was GICV3_IVAR_REDIST_VADDR */ #define GICV3_IVAR_REDIST 1002 -#define GICV3_IVAR_SUPPORT_LPIS 1003 __BUS_ACCESSOR(gicv3, nirqs, GICV3, NIRQS, u_int); __BUS_ACCESSOR(gicv3, redist, GICV3, REDIST, void *); -__BUS_ACCESSOR(gicv3, support_lpis, GICV3, SUPPORT_LPIS, bool); /* Device methods */ int gic_v3_attach(device_t dev); diff --git a/sys/arm64/arm64/gicv3_its.c b/sys/arm64/arm64/gicv3_its.c index 546a225abf09..7821b1512083 100644 --- a/sys/arm64/arm64/gicv3_its.c +++ b/sys/arm64/arm64/gicv3_its.c @@ -2222,7 +2222,7 @@ gicv3_its_fdt_probe(device_t dev) if (!ofw_bus_is_compatible(dev, "arm,gic-v3-its")) return (ENXIO); - if (!gicv3_get_support_lpis(dev)) + if (!gic_get_support_lpis(dev)) return (ENXIO); device_set_desc(dev, "ARM GIC Interrupt Translation Service"); @@ -2294,7 +2294,7 @@ gicv3_its_acpi_probe(device_t dev) if (gic_get_hw_rev(dev) < 3) return (EINVAL); - if (!gicv3_get_support_lpis(dev)) + if (!gic_get_support_lpis(dev)) return (ENXIO); device_set_desc(dev, "ARM GIC Interrupt Translation Service"); diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S index 3ec12140f139..c22d5fe76468 100644 --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -445,6 +445,10 @@ LENTRY(enter_kernel_el) ldr x3, =(CNTHCTL_EL1PCTEN_NOTRAP | CNTHCTL_EL1PCEN_NOTRAP) ldr x5, =(PSR_DAIF | PSR_M_EL1h) + /* Enable SPE at EL1 via Monitor Debug Configuration Register */ + mov x6, MDCR_EL2_E2PB_EL1_0_NO_TRAP + msr mdcr_el2, x6 + .Ldone_vhe: msr cptr_el2, x2 diff --git a/sys/arm64/arm64/machdep_boot.c b/sys/arm64/arm64/machdep_boot.c index 83bd74ea7317..1c5e8189e436 100644 --- a/sys/arm64/arm64/machdep_boot.c +++ b/sys/arm64/arm64/machdep_boot.c @@ -106,7 +106,8 @@ fake_preload_metadata(void *dtb_ptr, size_t dtb_size) PRELOAD_PUSH_VALUE(uint32_t, MODINFO_SIZE); PRELOAD_PUSH_VALUE(uint32_t, sizeof(size_t)); - PRELOAD_PUSH_VALUE(uint64_t, (size_t)(&end - VM_MIN_KERNEL_ADDRESS)); + PRELOAD_PUSH_VALUE(uint64_t, + (size_t)((vm_offset_t)&end - VM_MIN_KERNEL_ADDRESS)); if (dtb_ptr != NULL) { /* Copy DTB to KVA space and insert it into module chain. */ diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c index 0bdd2ecfd8a7..ba673ce9d6ee 100644 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -270,6 +270,8 @@ init_secondary(uint64_t cpu) install_cpu_errata(); enable_cpu_feat(CPU_FEAT_AFTER_DEV); + intr_pic_init_secondary(); + /* Signal we are done */ atomic_add_int(&aps_started, 1); @@ -288,8 +290,6 @@ init_secondary(uint64_t cpu) ("pmap0 doesn't match cpu %ld's ttbr0", cpu)); pcpup->pc_curpmap = pmap0; - intr_pic_init_secondary(); - /* Start per-CPU event timers. */ cpu_initclocks_ap(); diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c index 26b3389db172..012bf859eb3c 100644 --- a/sys/arm64/arm64/nexus.c +++ b/sys/arm64/arm64/nexus.c @@ -72,6 +72,8 @@ #include "acpi_bus_if.h" #endif +#include "pcib_if.h" + extern struct bus_space memmap_bus; static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device"); @@ -123,6 +125,15 @@ static bus_get_bus_tag_t nexus_get_bus_tag; #ifdef FDT static ofw_bus_map_intr_t nexus_ofw_map_intr; +/* + * PCIB interface + */ +static pcib_alloc_msi_t nexus_fdt_pcib_alloc_msi; +static pcib_release_msi_t nexus_fdt_pcib_release_msi; +static pcib_alloc_msix_t nexus_fdt_pcib_alloc_msix; +static pcib_release_msix_t nexus_fdt_pcib_release_msix; +static pcib_map_msi_t nexus_fdt_pcib_map_msi; + #endif static device_method_t nexus_methods[] = { @@ -441,6 +452,13 @@ static device_method_t nexus_fdt_methods[] = { /* OFW interface */ DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr), + /* PCIB interface */ + DEVMETHOD(pcib_alloc_msi, nexus_fdt_pcib_alloc_msi), + DEVMETHOD(pcib_release_msi, nexus_fdt_pcib_release_msi), + DEVMETHOD(pcib_alloc_msix, nexus_fdt_pcib_alloc_msix), + DEVMETHOD(pcib_release_msix, nexus_fdt_pcib_release_msix), + DEVMETHOD(pcib_map_msi, nexus_fdt_pcib_map_msi), + DEVMETHOD_END, }; @@ -518,6 +536,73 @@ nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells, irq = intr_map_irq(NULL, iparent, (struct intr_map_data *)fdt_data); return (irq); } + +static int +nexus_fdt_pcib_alloc_msi(device_t dev, device_t child, int count, int maxcount, + int *irqs) +{ + phandle_t msi_parent; + int error; + + error = ofw_bus_msimap(ofw_bus_get_node(child), 0, &msi_parent, NULL); + if (error != 0) + return (error); + + return (intr_alloc_msi(dev, child, msi_parent, count, maxcount, irqs)); +} + +static int +nexus_fdt_pcib_release_msi(device_t dev, device_t child, int count, int *irqs) +{ + phandle_t msi_parent; + int error; + + error = ofw_bus_msimap(ofw_bus_get_node(child), 0, &msi_parent, NULL); + if (error != 0) + return (error); + + return (intr_release_msi(dev, child, msi_parent, count, irqs)); +} + +static int +nexus_fdt_pcib_alloc_msix(device_t dev, device_t child, int *irq) +{ + phandle_t msi_parent; + int error; + + error = ofw_bus_msimap(ofw_bus_get_node(child), 0, &msi_parent, NULL); + if (error != 0) + return (error); + + return (intr_alloc_msix(dev, child, msi_parent, irq)); +} + +static int +nexus_fdt_pcib_release_msix(device_t dev, device_t child, int irq) +{ + phandle_t msi_parent; + int error; + + error = ofw_bus_msimap(ofw_bus_get_node(child), 0, &msi_parent, NULL); + if (error != 0) + return (error); + + return (intr_release_msix(dev, child, msi_parent, irq)); +} + +static int +nexus_fdt_pcib_map_msi(device_t dev, device_t child, int irq, uint64_t *addr, + uint32_t *data) +{ + phandle_t msi_parent; + int error; + + error = ofw_bus_msimap(ofw_bus_get_node(child), 0, &msi_parent, NULL); + if (error != 0) + return (error); + + return (intr_map_msi(dev, child, msi_parent, irq, addr, data)); +} #endif #ifdef DEV_ACPI diff --git a/sys/arm64/conf/std.arm64 b/sys/arm64/conf/std.arm64 index a0568466cfaf..02bdd25f2d52 100644 --- a/sys/arm64/conf/std.arm64 +++ b/sys/arm64/conf/std.arm64 @@ -106,3 +106,9 @@ device efirtc # EFI RTC # SMBIOS -- all EFI platforms device smbios + +# random(4) +device tpm # Trusted Platform Module +options RANDOM_ENABLE_TPM # enable entropy from TPM 2.0 +options RANDOM_ENABLE_KBD +options RANDOM_ENABLE_MOUSE diff --git a/sys/arm64/conf/std.broadcom b/sys/arm64/conf/std.broadcom index 3332aaac0826..65bee16e315d 100644 --- a/sys/arm64/conf/std.broadcom +++ b/sys/arm64/conf/std.broadcom @@ -33,5 +33,8 @@ device sdhci options FDT device acpi +# Sound support +device vchiq + # DTBs makeoptions MODULES_EXTRA+="dtb/rpi" diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index aa9b672ad85a..27b02c44cd76 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -2251,6 +2251,7 @@ #define PMBSR_MSS_SHIFT 0 #define PMBSR_MSS_MASK (UL(0xffff) << PMBSR_MSS_SHIFT) #define PMBSR_MSS_BSC_MASK (UL(0x3f) << PMBSR_MSS_SHIFT) +#define PMBSR_MSS_BSC_BUFFER_FILLED (UL(0x01) << PMBSR_MSS_SHIFT) #define PMBSR_MSS_FSC_MASK (UL(0x3f) << PMBSR_MSS_SHIFT) #define PMBSR_COLL_SHIFT 16 #define PMBSR_COLL (UL(0x1) << PMBSR_COLL_SHIFT) diff --git a/sys/arm64/include/hypervisor.h b/sys/arm64/include/hypervisor.h index 7d405e63cd8d..f3d7027269c9 100644 --- a/sys/arm64/include/hypervisor.h +++ b/sys/arm64/include/hypervisor.h @@ -268,6 +268,7 @@ #define MDCR_EL2_TDRA (0x1UL << MDCR_EL2_TDRA_SHIFT) #define MDCR_EL2_E2PB_SHIFT 12 #define MDCR_EL2_E2PB_MASK (0x3UL << MDCR_EL2_E2PB_SHIFT) +#define MDCR_EL2_E2PB_EL1_0_NO_TRAP (0x3UL << MDCR_EL2_E2PB_SHIFT) #define MDCR_EL2_TPMS_SHIFT 14 #define MDCR_EL2_TPMS (0x1UL << MDCR_EL2_TPMS_SHIFT) #define MDCR_EL2_EnSPM_SHIFT 15 diff --git a/sys/arm64/rockchip/rk_i2s.c b/sys/arm64/rockchip/rk_i2s.c index 5f1b6bbdeabf..856fa20e6ce4 100644 --- a/sys/arm64/rockchip/rk_i2s.c +++ b/sys/arm64/rockchip/rk_i2s.c @@ -403,10 +403,10 @@ rk_i2s_dai_intr(device_t dev, struct snd_dbuf *play_buf, struct snd_dbuf *rec_bu count = sndbuf_getready(play_buf); if (count > FIFO_SIZE - 1) count = FIFO_SIZE - 1; - size = sndbuf_getsize(play_buf); + size = play_buf->bufsize; readyptr = sndbuf_getreadyptr(play_buf); - samples = (uint8_t*)sndbuf_getbuf(play_buf); + samples = play_buf->buf; written = 0; for (; level < count; level++) { val = (samples[readyptr++ % size] << 0); @@ -426,9 +426,9 @@ rk_i2s_dai_intr(device_t dev, struct snd_dbuf *play_buf, struct snd_dbuf *rec_bu uint8_t *samples; uint32_t count, size, freeptr, recorded; count = sndbuf_getfree(rec_buf); - size = sndbuf_getsize(rec_buf); + size = rec_buf->bufsize; freeptr = sndbuf_getfreeptr(rec_buf); - samples = (uint8_t*)sndbuf_getbuf(rec_buf); + samples = rec_buf->buf; recorded = 0; if (level > count / 4) level = count / 4; diff --git a/sys/arm64/spe/arm_spe.h b/sys/arm64/spe/arm_spe.h new file mode 100644 index 000000000000..5dba20673a77 --- /dev/null +++ b/sys/arm64/spe/arm_spe.h @@ -0,0 +1,77 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024 Arm Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ARM64_ARM_SPE_H_ +#define _ARM64_ARM_SPE_H_ + +/* kqueue events */ +#define ARM_SPE_KQ_BUF 138 +#define ARM_SPE_KQ_SHUTDOWN 139 +#define ARM_SPE_KQ_SIGNAL 140 + +/* spe_backend_read() u64 data encoding */ +#define KQ_BUF_POS_SHIFT 0 +#define KQ_BUF_POS (1 << KQ_BUF_POS_SHIFT) +#define KQ_PARTREC_SHIFT 1 +#define KQ_PARTREC (1 << KQ_PARTREC_SHIFT) +#define KQ_FINAL_BUF_SHIFT 2 +#define KQ_FINAL_BUF (1 << KQ_FINAL_BUF_SHIFT) + +enum arm_spe_ctx_field { + ARM_SPE_CTX_NONE, + ARM_SPE_CTX_PID, + ARM_SPE_CTX_CPU_ID +}; + +enum arm_spe_profiling_level { + ARM_SPE_KERNEL_AND_USER, + ARM_SPE_KERNEL_ONLY, + ARM_SPE_USER_ONLY +}; +struct arm_spe_config { + /* Minimum interval is IMP DEF up to maximum 24 bit value */ + uint32_t interval; + + /* Profile kernel (EL1), userspace (EL0) or both */ + enum arm_spe_profiling_level level; + + /* + * Configure context field in SPE records to store either the + * current PID, the CPU ID or neither + * + * In PID mode, kernel threads without a process context are + * logged as PID 0 + */ + enum arm_spe_ctx_field ctx_field; +}; + +struct arm_spe_svc_buf { + uint32_t ident; + uint8_t buf_idx : 1; +}; + +#endif /* _ARM64_ARM_SPE_H_ */ diff --git a/sys/arm64/spe/arm_spe_acpi.c b/sys/arm64/spe/arm_spe_acpi.c new file mode 100644 index 000000000000..b9f40448d940 --- /dev/null +++ b/sys/arm64/spe/arm_spe_acpi.c @@ -0,0 +1,146 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024 Arm Ltd + * Copyright (c) 2022 The FreeBSD Foundation + * + * Portions of this software were developed by Andrew Turner under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/module.h> +#include <sys/mutex.h> + +#include <contrib/dev/acpica/include/acpi.h> +#include <dev/acpica/acpivar.h> + +#include <arm64/spe/arm_spe_dev.h> + +static device_identify_t arm_spe_acpi_identify; +static device_probe_t arm_spe_acpi_probe; + +static device_method_t arm_spe_acpi_methods[] = { + /* Device interface */ + DEVMETHOD(device_identify, arm_spe_acpi_identify), + DEVMETHOD(device_probe, arm_spe_acpi_probe), + + DEVMETHOD_END, +}; + +DEFINE_CLASS_1(spe, arm_spe_acpi_driver, arm_spe_acpi_methods, + sizeof(struct arm_spe_softc), arm_spe_driver); + +DRIVER_MODULE(spe, acpi, arm_spe_acpi_driver, 0, 0); + +struct madt_data { + u_int irq; + bool found; + bool valid; +}; + +static void +madt_handler(ACPI_SUBTABLE_HEADER *entry, void *arg) +{ + ACPI_MADT_GENERIC_INTERRUPT *intr; + struct madt_data *madt_data; + u_int irq; + + madt_data = (struct madt_data *)arg; + + /* Exit early if we are have decided to not attach */ + if (!madt_data->valid) + return; + + switch(entry->Type) { + case ACPI_MADT_TYPE_GENERIC_INTERRUPT: + intr = (ACPI_MADT_GENERIC_INTERRUPT *)entry; + irq = intr->SpeInterrupt; + + if (irq == 0) { + madt_data->valid = false; + } else if (!madt_data->found) { + madt_data->found = true; + madt_data->irq = irq; + } else if (madt_data->irq != irq) { + madt_data->valid = false; + } + break; + + default: + break; + } +} + +static void +arm_spe_acpi_identify(driver_t *driver, device_t parent) +{ + struct madt_data madt_data; + ACPI_TABLE_MADT *madt; + device_t dev; + vm_paddr_t physaddr; + + physaddr = acpi_find_table(ACPI_SIG_MADT); + if (physaddr == 0) + return; + + madt = acpi_map_table(physaddr, ACPI_SIG_MADT); + if (madt == NULL) { + device_printf(parent, "spe: Unable to map the MADT\n"); + return; + } + + madt_data.irq = 0; + madt_data.found = false; + madt_data.valid = true; + + acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, + madt_handler, &madt_data); + + if (!madt_data.found || !madt_data.valid) + goto out; + + MPASS(madt_data.irq != 0); + + dev = BUS_ADD_CHILD(parent, 0, "spe", -1); + if (dev == NULL) { + device_printf(parent, "add spe child failed\n"); + goto out; + } + + BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 0, madt_data.irq, 1); + +out: + acpi_unmap_table(madt); +} + +static int +arm_spe_acpi_probe(device_t dev) +{ + device_set_desc(dev, "ARM Statistical Profiling Extension"); + return (BUS_PROBE_NOWILDCARD); +} diff --git a/sys/arm64/spe/arm_spe_backend.c b/sys/arm64/spe/arm_spe_backend.c new file mode 100644 index 000000000000..b4e1132f9cbc --- /dev/null +++ b/sys/arm64/spe/arm_spe_backend.c @@ -0,0 +1,586 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024 Arm Ltd + * Copyright (c) 2022 The FreeBSD Foundation + * + * Portions of this software were developed by Andrew Turner under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Arm Statistical Profiling Extension (SPE) backend + * + * Basic SPE operation + * + * SPE is enabled and configured on a per-core basis, with each core requiring + * separate code to enable and configure. Each core also requires a separate + * buffer passed as config where the CPU will write profiling data. When the + * profiling buffer is full, an interrupt will be taken on the same CPU. + * + * Driver Design + * + * - HWT allocates a large single buffer per core. This buffer is split in half + * to create a 2 element circular buffer (aka ping-pong buffer) where the + * kernel writes to one half while userspace is copying the other half + * - SMP calls are used to enable and configure each core, with SPE initially + * configured to write to the first half of the buffer + * - When the first half of the buffer is full, a buffer full interrupt will + * immediately switch writing to the second half. The kernel adds the details + * of the half that needs copying to a FIFO STAILQ and notifies userspace via + * kqueue by sending a ARM_SPE_KQ_BUF kevent with how many buffers on the + * queue need servicing + * - The kernel responds to HWT_IOC_BUFPTR_GET ioctl by sending details of the + * first item from the queue + * - The buffers pending copying will not be overwritten until an + * HWT_IOC_SVC_BUF ioctl is received from userspace confirming the data has + * been copied out + * - In the case where both halfs of the buffer are full, profiling will be + * paused until notification via HWT_IOC_SVC_BUF is received + * + * Future improvements and limitations + * + * - Using large buffer sizes should minimise pauses and loss of profiling + * data while kernel is waiting for userspace to copy out data. Since it is + * generally expected that consuming (copying) this data is faster than + * producing it, in practice this has not so far been an issue. If it does + * prove to be an issue even with large buffer sizes then additional buffering + * i.e. n element circular buffers might be required. + * + * - kqueue can only notify and queue one kevent of the same type, with + * subsequent events overwriting data in the first event. The kevent + * ARM_SPE_KQ_BUF can therefore only contain the number of buffers on the + * STAILQ, incrementing each time a new buffer is full. In this case kqueue + * serves just as a notification to userspace to wake up and query the kernel + * with the appropriate ioctl. An alternative might be custom kevents where + * the kevent identifier is encoded with something like n+cpu_id or n+tid. In + * this case data could be sent directly with kqueue via the kevent data and + * fflags elements, avoiding the extra ioctl. + * + */ + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/conf.h> +#include <sys/hwt.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/mman.h> +#include <sys/module.h> +#include <sys/mutex.h> +#include <sys/proc.h> +#include <sys/rman.h> +#include <sys/rwlock.h> +#include <sys/smp.h> +#include <sys/sysctl.h> +#include <sys/systm.h> + +#include <machine/bus.h> + +#include <arm64/spe/arm_spe_dev.h> + +#include <dev/hwt/hwt_vm.h> +#include <dev/hwt/hwt_backend.h> +#include <dev/hwt/hwt_config.h> +#include <dev/hwt/hwt_context.h> +#include <dev/hwt/hwt_cpu.h> +#include <dev/hwt/hwt_thread.h> + +MALLOC_DECLARE(M_ARM_SPE); + +extern u_int mp_maxid; +extern struct taskqueue *taskqueue_arm_spe; + +int spe_backend_disable_smp(struct hwt_context *ctx); + +static device_t spe_dev; +static struct hwt_backend_ops spe_ops; +static struct hwt_backend backend = { + .ops = &spe_ops, + .name = "spe", + .kva_req = 1, +}; + +static struct arm_spe_info *spe_info; + +static int +spe_backend_init_thread(struct hwt_context *ctx) +{ + return (ENOTSUP); +} + +static void +spe_backend_init_cpu(struct hwt_context *ctx) +{ + struct arm_spe_info *info; + struct arm_spe_softc *sc = device_get_softc(spe_dev); + char lock_name[32]; + char *tmp = "Arm SPE lock/cpu/"; + int cpu_id; + + spe_info = malloc(sizeof(struct arm_spe_info) * mp_ncpus, + M_ARM_SPE, M_WAITOK | M_ZERO); + + sc->spe_info = spe_info; + + CPU_FOREACH_ISSET(cpu_id, &ctx->cpu_map) { + info = &spe_info[cpu_id]; + info->sc = sc; + info->ident = cpu_id; + info->buf_info[0].info = info; + info->buf_info[0].buf_idx = 0; + info->buf_info[1].info = info; + info->buf_info[1].buf_idx = 1; + snprintf(lock_name, sizeof(lock_name), "%s%d", tmp, cpu_id); + mtx_init(&info->lock, lock_name, NULL, MTX_SPIN); + } +} + +static int +spe_backend_init(struct hwt_context *ctx) +{ + struct arm_spe_softc *sc = device_get_softc(spe_dev); + int error = 0; + + /* + * HWT currently specifies buffer size must be a multiple of PAGE_SIZE, + * i.e. minimum 4KB + the maximum PMBIDR.Align is 2KB + * This should never happen but it's good to sense check + */ + if (ctx->bufsize % sc->kva_align != 0) + return (EINVAL); + + /* + * Since we're splitting the buffer in half + PMBLIMITR needs to be page + * aligned, minimum buffer size needs to be 2x PAGE_SIZE + */ + if (ctx->bufsize < (2 * PAGE_SIZE)) + return (EINVAL); + + sc->ctx = ctx; + sc->kqueue_fd = ctx->kqueue_fd; + sc->hwt_td = ctx->hwt_td; + + if (ctx->mode == HWT_MODE_THREAD) + error = spe_backend_init_thread(ctx); + else + spe_backend_init_cpu(ctx); + + return (error); +} + +#ifdef ARM_SPE_DEBUG +static void hex_dump(uint8_t *buf, size_t len) +{ + size_t i; + + printf("--------------------------------------------------------------\n"); + for (i = 0; i < len; ++i) { + if (i % 8 == 0) { + printf(" "); + } + if (i % 16 == 0) { + if (i != 0) { + printf("\r\n"); + } + printf("\t"); + } + printf("%02X ", buf[i]); + } + printf("\r\n"); +} +#endif + +static int +spe_backend_deinit(struct hwt_context *ctx) +{ +#ifdef ARM_SPE_DEBUG + struct arm_spe_info *info; + int cpu_id; + + CPU_FOREACH_ISSET(cpu_id, &ctx->cpu_map) { + info = &spe_info[cpu_id]; + hex_dump((void *)info->kvaddr, 128); + hex_dump((void *)(info->kvaddr + (info->buf_size/2)), 128); + } +#endif + + if (ctx->state == CTX_STATE_RUNNING) { + spe_backend_disable_smp(ctx); + ctx->state = CTX_STATE_STOPPED; + } + + free(spe_info, M_ARM_SPE); + + return (0); +} + +static uint64_t +arm_spe_min_interval(struct arm_spe_softc *sc) +{ + /* IMPLEMENTATION DEFINED */ + switch (PMSIDR_Interval_VAL(sc->pmsidr)) + { + case PMSIDR_Interval_256: + return (256); + case PMSIDR_Interval_512: + return (512); + case PMSIDR_Interval_768: + return (768); + case PMSIDR_Interval_1024: + return (1024); + case PMSIDR_Interval_1536: + return (1536); + case PMSIDR_Interval_2048: + return (2048); + case PMSIDR_Interval_3072: + return (3072); + case PMSIDR_Interval_4096: + return (4096); + default: + return (4096); + } +} + +static inline void +arm_spe_set_interval(struct arm_spe_info *info, uint64_t interval) +{ + uint64_t min_interval = arm_spe_min_interval(info->sc); + + interval = MAX(interval, min_interval); + interval = MIN(interval, 1 << 24); /* max 24 bits */ + + dprintf("%s %lu\n", __func__, interval); + + info->pmsirr &= ~(PMSIRR_INTERVAL_MASK); + info->pmsirr |= (interval << PMSIRR_INTERVAL_SHIFT); +} + +static int +spe_backend_configure(struct hwt_context *ctx, int cpu_id, int session_id) +{ + struct arm_spe_info *info = &spe_info[cpu_id]; + struct arm_spe_config *cfg; + int err = 0; + + mtx_lock_spin(&info->lock); + info->ident = cpu_id; + /* Set defaults */ + info->pmsfcr = 0; + info->pmsevfr = 0xFFFFFFFFFFFFFFFFUL; + info->pmslatfr = 0; + info->pmsirr = + (arm_spe_min_interval(info->sc) << PMSIRR_INTERVAL_SHIFT) + | PMSIRR_RND; + info->pmsicr = 0; + info->pmscr = PMSCR_TS | PMSCR_PA | PMSCR_CX | PMSCR_E1SPE | PMSCR_E0SPE; + + if (ctx->config != NULL && + ctx->config_size == sizeof(struct arm_spe_config) && + ctx->config_version == 1) { + cfg = (struct arm_spe_config *)ctx->config; + if (cfg->interval) + arm_spe_set_interval(info, cfg->interval); + if (cfg->level == ARM_SPE_KERNEL_ONLY) + info->pmscr &= ~(PMSCR_E0SPE); /* turn off user */ + if (cfg->level == ARM_SPE_USER_ONLY) + info->pmscr &= ~(PMSCR_E1SPE); /* turn off kern */ + if (cfg->ctx_field) + info->ctx_field = cfg->ctx_field; + } else + err = (EINVAL); + mtx_unlock_spin(&info->lock); + + return (err); +} + + +static void +arm_spe_enable(void *arg __unused) +{ + struct arm_spe_info *info = &spe_info[PCPU_GET(cpuid)]; + uint64_t base, limit; + + dprintf("%s on cpu:%d\n", __func__, PCPU_GET(cpuid)); + + mtx_lock_spin(&info->lock); + + if (info->ctx_field == ARM_SPE_CTX_CPU_ID) + WRITE_SPECIALREG(CONTEXTIDR_EL1_REG, PCPU_GET(cpuid)); + + WRITE_SPECIALREG(PMSFCR_EL1_REG, info->pmsfcr); + WRITE_SPECIALREG(PMSEVFR_EL1_REG, info->pmsevfr); + WRITE_SPECIALREG(PMSLATFR_EL1_REG, info->pmslatfr); + + /* Set the sampling interval */ + WRITE_SPECIALREG(PMSIRR_EL1_REG, info->pmsirr); + isb(); + + /* Write 0 here before enabling sampling */ + WRITE_SPECIALREG(PMSICR_EL1_REG, info->pmsicr); + isb(); + + base = info->kvaddr; + limit = base + (info->buf_size/2); + /* Enable the buffer */ + limit &= PMBLIMITR_LIMIT_MASK; /* Zero lower 12 bits */ + limit |= PMBLIMITR_E; + /* Set the base and limit */ + WRITE_SPECIALREG(PMBPTR_EL1_REG, base); + WRITE_SPECIALREG(PMBLIMITR_EL1_REG, limit); + isb(); + + /* Enable sampling */ + WRITE_SPECIALREG(PMSCR_EL1_REG, info->pmscr); + isb(); + + info->enabled = true; + + mtx_unlock_spin(&info->lock); +} + +static int +spe_backend_enable_smp(struct hwt_context *ctx) +{ + struct arm_spe_info *info; + struct hwt_vm *vm; + int cpu_id; + + HWT_CTX_LOCK(ctx); + CPU_FOREACH_ISSET(cpu_id, &ctx->cpu_map) { + vm = hwt_cpu_get(ctx, cpu_id)->vm; + + info = &spe_info[cpu_id]; + + mtx_lock_spin(&info->lock); + info->kvaddr = vm->kvaddr; + info->buf_size = ctx->bufsize; + mtx_unlock_spin(&info->lock); + } + HWT_CTX_UNLOCK(ctx); + + cpu_id = CPU_FFS(&ctx->cpu_map) - 1; + info = &spe_info[cpu_id]; + if (info->ctx_field == ARM_SPE_CTX_PID) + arm64_pid_in_contextidr = true; + else + arm64_pid_in_contextidr = false; + + smp_rendezvous_cpus(ctx->cpu_map, smp_no_rendezvous_barrier, + arm_spe_enable, smp_no_rendezvous_barrier, NULL); + + return (0); +} + +void +arm_spe_disable(void *arg __unused) +{ + struct arm_spe_info *info = &spe_info[PCPU_GET(cpuid)]; + struct arm_spe_buf_info *buf = &info->buf_info[info->buf_idx]; + + if (!info->enabled) + return; + + dprintf("%s on cpu:%d\n", __func__, PCPU_GET(cpuid)); + + /* Disable profiling */ + WRITE_SPECIALREG(PMSCR_EL1_REG, 0x0); + isb(); + + /* Drain any remaining tracing data */ + psb_csync(); + dsb(nsh); + + /* Disable the profiling buffer */ + WRITE_SPECIALREG(PMBLIMITR_EL1_REG, 0); + isb(); + + /* Clear interrupt status reg */ + WRITE_SPECIALREG(PMBSR_EL1_REG, 0x0); + + /* Clear PID/CPU_ID from context ID reg */ + WRITE_SPECIALREG(CONTEXTIDR_EL1_REG, 0); + + mtx_lock_spin(&info->lock); + buf->pmbptr = READ_SPECIALREG(PMBPTR_EL1_REG); + info->enabled = false; + mtx_unlock_spin(&info->lock); +} + +int +spe_backend_disable_smp(struct hwt_context *ctx) +{ + struct kevent kev; + struct arm_spe_info *info; + struct arm_spe_buf_info *buf; + int cpu_id; + int ret; + + /* Disable and send out remaining data in bufs */ + smp_rendezvous_cpus(ctx->cpu_map, smp_no_rendezvous_barrier, + arm_spe_disable, smp_no_rendezvous_barrier, NULL); + + CPU_FOREACH_ISSET(cpu_id, &ctx->cpu_map) { + info = &spe_info[cpu_id]; + buf = &info->buf_info[info->buf_idx]; + arm_spe_send_buffer(buf, 0); + } + + arm64_pid_in_contextidr = false; + + /* + * Tracing on all CPUs has been disabled, and we've sent write ptr + * offsets for all bufs - let userspace know it can shutdown + */ + EV_SET(&kev, ARM_SPE_KQ_SHUTDOWN, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); + ret = kqfd_register(ctx->kqueue_fd, &kev, ctx->hwt_td, M_WAITOK); + if (ret) + dprintf("%s kqfd_register ret:%d\n", __func__, ret); + + return (0); +} + +static void +spe_backend_stop(struct hwt_context *ctx) +{ + spe_backend_disable_smp(ctx); +} + +static void +arm_spe_reenable(void *arg __unused) +{ + struct arm_spe_info *info = &spe_info[PCPU_GET(cpuid)];; + + WRITE_SPECIALREG(PMSCR_EL1_REG, info->pmscr); + isb(); +} + +static int +spe_backend_svc_buf(struct hwt_context *ctx, void *data, size_t data_size, + int data_version) +{ + struct arm_spe_info *info; + struct arm_spe_buf_info *buf; + struct arm_spe_svc_buf *s; + int err = 0; + cpuset_t cpu_set; + + if (data_size != sizeof(struct arm_spe_svc_buf)) + return (E2BIG); + + if (data_version != 1) + return (EINVAL); + + s = (struct arm_spe_svc_buf *)data; + if (s->buf_idx > 1) + return (ENODEV); + if (s->ident >= mp_ncpus) + return (EINVAL); + + info = &spe_info[s->ident]; + mtx_lock_spin(&info->lock); + + buf = &info->buf_info[s->buf_idx]; + + if (!info->enabled) { + err = ENXIO; + goto end; + } + + /* Clear the flag the signals buffer needs servicing */ + buf->buf_svc = false; + + /* Re-enable profiling if we've been waiting for this notification */ + if (buf->buf_wait) { + CPU_SETOF(s->ident, &cpu_set); + + mtx_unlock_spin(&info->lock); + smp_rendezvous_cpus(cpu_set, smp_no_rendezvous_barrier, + arm_spe_reenable, smp_no_rendezvous_barrier, NULL); + mtx_lock_spin(&info->lock); + + buf->buf_wait = false; + } + +end: + mtx_unlock_spin(&info->lock); + return (err); +} + +static int +spe_backend_read(struct hwt_vm *vm, int *ident, vm_offset_t *offset, + uint64_t *data) +{ + struct arm_spe_queue *q; + struct arm_spe_softc *sc = device_get_softc(spe_dev); + int error = 0; + + mtx_lock_spin(&sc->sc_lock); + + /* Return the first pending buffer that needs servicing */ + q = STAILQ_FIRST(&sc->pending); + if (q == NULL) { + error = ENOENT; + goto error; + } + *ident = q->ident; + *offset = q->offset; + *data = (q->buf_idx << KQ_BUF_POS_SHIFT) | + (q->partial_rec << KQ_PARTREC_SHIFT) | + (q->final_buf << KQ_FINAL_BUF_SHIFT); + + STAILQ_REMOVE_HEAD(&sc->pending, next); + sc->npending--; + +error: + mtx_unlock_spin(&sc->sc_lock); + if (error) + return (error); + + free(q, M_ARM_SPE); + return (0); +} + +static struct hwt_backend_ops spe_ops = { + .hwt_backend_init = spe_backend_init, + .hwt_backend_deinit = spe_backend_deinit, + + .hwt_backend_configure = spe_backend_configure, + .hwt_backend_svc_buf = spe_backend_svc_buf, + .hwt_backend_stop = spe_backend_stop, + + .hwt_backend_enable_smp = spe_backend_enable_smp, + .hwt_backend_disable_smp = spe_backend_disable_smp, + + .hwt_backend_read = spe_backend_read, +}; + +int +spe_register(device_t dev) +{ + spe_dev = dev; + + return (hwt_backend_register(&backend)); +} diff --git a/sys/arm64/spe/arm_spe_dev.c b/sys/arm64/spe/arm_spe_dev.c new file mode 100644 index 000000000000..8a834197eeef --- /dev/null +++ b/sys/arm64/spe/arm_spe_dev.c @@ -0,0 +1,324 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024 Arm Ltd + * Copyright (c) 2022 The FreeBSD Foundation + * + * Portions of this software were developed by Andrew Turner under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/conf.h> +#include <sys/event.h> +#include <sys/hwt.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> +#include <sys/rman.h> +#include <sys/smp.h> +#include <sys/systm.h> +#include <sys/taskqueue.h> + +#include <machine/bus.h> + +#include <arm64/spe/arm_spe.h> +#include <arm64/spe/arm_spe_dev.h> + +MALLOC_DEFINE(M_ARM_SPE, "armspe", "Arm SPE tracing"); + +/* + * taskqueue(9) used for sleepable routines called from interrupt handlers + */ +TASKQUEUE_FAST_DEFINE_THREAD(arm_spe); + +void arm_spe_send_buffer(void *, int); +static void arm_spe_error(void *, int); +static int arm_spe_intr(void *); +device_attach_t arm_spe_attach; + +static device_method_t arm_spe_methods[] = { + /* Device interface */ + DEVMETHOD(device_attach, arm_spe_attach), + + DEVMETHOD_END, +}; + +DEFINE_CLASS_0(spe, arm_spe_driver, arm_spe_methods, + sizeof(struct arm_spe_softc)); + +#define ARM_SPE_KVA_MAX_ALIGN UL(2048) + +int +arm_spe_attach(device_t dev) +{ + struct arm_spe_softc *sc; + int error, rid; + + sc = device_get_softc(dev); + sc->dev = dev; + + sc->pmbidr = READ_SPECIALREG(PMBIDR_EL1_REG); + sc->pmsidr = READ_SPECIALREG(PMSIDR_EL1_REG); + device_printf(dev, "PMBIDR_EL1: %#lx\n", sc->pmbidr); + device_printf(dev, "PMSIDR_EL1: %#lx\n", sc->pmsidr); + if ((sc->pmbidr & PMBIDR_P) != 0) { + device_printf(dev, "Profiling Buffer is owned by a higher Exception level\n"); + return (EPERM); + } + + sc->kva_align = 1 << ((sc->pmbidr & PMBIDR_Align_MASK) >> PMBIDR_Align_SHIFT); + if (sc->kva_align > ARM_SPE_KVA_MAX_ALIGN) { + device_printf(dev, "Invalid PMBIDR.Align value of %d\n", sc->kva_align); + return (EINVAL); + } + + rid = 0; + sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); + if (sc->sc_irq_res == NULL) { + device_printf(dev, "Unable to allocate interrupt\n"); + return (ENXIO); + } + error = bus_setup_intr(dev, sc->sc_irq_res, + INTR_TYPE_MISC | INTR_MPSAFE, arm_spe_intr, NULL, sc, + &sc->sc_irq_cookie); + if (error != 0) { + device_printf(dev, "Unable to set up interrupt\n"); + return (error); + } + + mtx_init(&sc->sc_lock, "Arm SPE lock", NULL, MTX_SPIN); + + STAILQ_INIT(&sc->pending); + sc->npending = 0; + + spe_register(dev); + + return (0); +} + +/* Interrupt handler runs on the same core that triggered the exception */ +static int +arm_spe_intr(void *arg) +{ + int cpu_id = PCPU_GET(cpuid); + struct arm_spe_softc *sc = arg; + uint64_t pmbsr; + uint64_t base, limit; + uint8_t ec; + struct arm_spe_info *info = &sc->spe_info[cpu_id]; + uint8_t i = info->buf_idx; + struct arm_spe_buf_info *buf = &info->buf_info[i]; + struct arm_spe_buf_info *prev_buf = &info->buf_info[!i]; + device_t dev = sc->dev; + + /* Make sure the profiling data is visible to the CPU */ + psb_csync(); + dsb(nsh); + + /* Make sure any HW update of PMBPTR_EL1 is visible to the CPU */ + isb(); + + pmbsr = READ_SPECIALREG(PMBSR_EL1_REG); + + if (!(pmbsr & PMBSR_S)) + return (FILTER_STRAY); + + /* Event Class */ + ec = PMBSR_EC_VAL(pmbsr); + switch (ec) + { + case PMBSR_EC_OTHER_BUF_MGMT: /* Other buffer management event */ + break; + case PMBSR_EC_GRAN_PROT_CHK: /* Granule Protection Check fault */ + device_printf(dev, "PMBSR_EC_GRAN_PROT_CHK\n"); + break; + case PMBSR_EC_STAGE1_DA: /* Stage 1 Data Abort */ + device_printf(dev, "PMBSR_EC_STAGE1_DA\n"); + break; + case PMBSR_EC_STAGE2_DA: /* Stage 2 Data Abort */ + device_printf(dev, "PMBSR_EC_STAGE2_DA\n"); + break; + default: + /* Unknown EC */ + device_printf(dev, "unknown PMBSR_EC: %#x\n", ec); + arm_spe_disable(NULL); + TASK_INIT(&sc->task, 0, (task_fn_t *)arm_spe_error, sc->ctx); + taskqueue_enqueue(taskqueue_arm_spe, &sc->task); + return (FILTER_HANDLED); + } + + switch (ec) { + case PMBSR_EC_OTHER_BUF_MGMT: + /* Buffer Status Code = buffer filled */ + if ((pmbsr & PMBSR_MSS_BSC_MASK) == PMBSR_MSS_BSC_BUFFER_FILLED) { + dprintf("%s SPE buffer full event (cpu:%d)\n", + __func__, cpu_id); + break; + } + case PMBSR_EC_GRAN_PROT_CHK: + case PMBSR_EC_STAGE1_DA: + case PMBSR_EC_STAGE2_DA: + /* + * If we have one of these, we've messed up the + * programming somehow (e.g. passed invalid memory to + * SPE) and can't recover + */ + arm_spe_disable(NULL); + TASK_INIT(&sc->task, 0, (task_fn_t *)arm_spe_error, sc->ctx); + taskqueue_enqueue(taskqueue_arm_spe, &sc->task); + /* PMBPTR_EL1 is fault address if PMBSR_DL is 1 */ + device_printf(dev, "CPU:%d PMBSR_EL1:%#lx\n", cpu_id, pmbsr); + device_printf(dev, "PMBPTR_EL1:%#lx PMBLIMITR_EL1:%#lx\n", + READ_SPECIALREG(PMBPTR_EL1_REG), + READ_SPECIALREG(PMBLIMITR_EL1_REG)); + return (FILTER_HANDLED); + } + + mtx_lock_spin(&info->lock); + + /* + * Data Loss bit - pmbptr might not be pointing to the end of the last + * complete record + */ + if ((pmbsr & PMBSR_DL) == PMBSR_DL) + buf->partial_rec = 1; + buf->pmbptr = READ_SPECIALREG(PMBPTR_EL1_REG); + buf->buf_svc = true; + + /* Setup regs ready to start writing to the other half of the buffer */ + info->buf_idx = !info->buf_idx; + base = buf_start_addr(info->buf_idx, info); + limit = base + (info->buf_size/2); + limit &= PMBLIMITR_LIMIT_MASK; + limit |= PMBLIMITR_E; + WRITE_SPECIALREG(PMBPTR_EL1_REG, base); + WRITE_SPECIALREG(PMBLIMITR_EL1_REG, limit); + isb(); + + /* + * Notify userspace via kqueue that buffer is full and needs copying + * out - since kqueue can sleep, don't do this in the interrupt handler, + * add to a taskqueue to be scheduled later instead + */ + TASK_INIT(&info->task[i], 0, (task_fn_t *)arm_spe_send_buffer, buf); + taskqueue_enqueue(taskqueue_arm_spe, &info->task[i]); + + /* + * It's possible userspace hasn't yet notified us they've copied out the + * other half of the buffer + * + * This might be because: + * a) Kernel hasn't scheduled the task via taskqueue to notify + * userspace to copy out the data + * b) Userspace is still copying the buffer or hasn't notified us + * back via the HWT_IOC_SVC_BUF ioctl + * + * Either way we need to avoid overwriting uncopied data in the + * buffer, so disable profiling until we receive that SVC_BUF + * ioctl + * + * Using a larger buffer size should help to minimise these events and + * loss of profiling data while profiling is disabled + */ + if (prev_buf->buf_svc) { + device_printf(sc->dev, "cpu%d: buffer full interrupt, but other" + " half of buffer has not been copied out - consider" + " increasing buffer size to minimise loss of profiling data\n", + cpu_id); + WRITE_SPECIALREG(PMSCR_EL1_REG, 0x0); + prev_buf->buf_wait = true; + } + + mtx_unlock_spin(&info->lock); + + /* Clear Profiling Buffer Status Register */ + WRITE_SPECIALREG(PMBSR_EL1_REG, 0); + + isb(); + + return (FILTER_HANDLED); +} + +/* note: Scheduled and run via taskqueue, so can run on any CPU at any time */ +void +arm_spe_send_buffer(void *arg, int pending __unused) +{ + struct arm_spe_buf_info *buf = (struct arm_spe_buf_info *)arg; + struct arm_spe_info *info = buf->info; + struct arm_spe_queue *queue; + struct kevent kev; + int ret; + + queue = malloc(sizeof(struct arm_spe_queue), M_ARM_SPE, + M_WAITOK | M_ZERO); + + mtx_lock_spin(&info->lock); + + /* Add to queue for userspace to pickup */ + queue->ident = info->ident; + queue->offset = buf->pmbptr - buf_start_addr(buf->buf_idx, info); + queue->buf_idx = buf->buf_idx; + queue->final_buf = !info->enabled; + queue->partial_rec = buf->partial_rec; + mtx_unlock_spin(&info->lock); + + mtx_lock_spin(&info->sc->sc_lock); + STAILQ_INSERT_TAIL(&info->sc->pending, queue, next); + info->sc->npending++; + EV_SET(&kev, ARM_SPE_KQ_BUF, EVFILT_USER, 0, NOTE_TRIGGER, + info->sc->npending, NULL); + mtx_unlock_spin(&info->sc->sc_lock); + + /* Notify userspace */ + ret = kqfd_register(info->sc->kqueue_fd, &kev, info->sc->hwt_td, + M_WAITOK); + if (ret) { + dprintf("%s kqfd_register ret:%d\n", __func__, ret); + arm_spe_error(info->sc->ctx, 0); + } +} + +static void +arm_spe_error(void *arg, int pending __unused) +{ + struct hwt_context *ctx = arg; + struct kevent kev; + int ret; + + smp_rendezvous_cpus(ctx->cpu_map, smp_no_rendezvous_barrier, + arm_spe_disable, smp_no_rendezvous_barrier, NULL); + + EV_SET(&kev, ARM_SPE_KQ_SHUTDOWN, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); + ret = kqfd_register(ctx->kqueue_fd, &kev, ctx->hwt_td, M_WAITOK); + if (ret) + dprintf("%s kqfd_register ret:%d\n", __func__, ret); +} + +MODULE_DEPEND(spe, hwt, 1, 1, 1); +MODULE_VERSION(spe, 1); diff --git a/sys/arm64/spe/arm_spe_dev.h b/sys/arm64/spe/arm_spe_dev.h new file mode 100644 index 000000000000..df88d98ef1c0 --- /dev/null +++ b/sys/arm64/spe/arm_spe_dev.h @@ -0,0 +1,162 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024 Arm Ltd + * Copyright (c) 2022 The FreeBSD Foundation + * + * Portions of this software were developed by Andrew Turner under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ARM64_ARM_SPE_DEV_H_ +#define _ARM64_ARM_SPE_DEV_H_ + +#include <sys/mutex.h> +#include <sys/taskqueue.h> + +#include <vm/vm.h> + +#include <arm64/spe/arm_spe.h> + +#include <dev/hwt/hwt_context.h> + +#define ARM_SPE_DEBUG +#undef ARM_SPE_DEBUG + +#ifdef ARM_SPE_DEBUG +#define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__) +#else +#define dprintf(fmt, ...) +#endif + +DECLARE_CLASS(arm_spe_driver); + +struct cdev; +struct resource; + +extern bool arm64_pid_in_contextidr; + +int spe_register(device_t dev); +void arm_spe_disable(void *arg __unused); +int spe_backend_disable_smp(struct hwt_context *ctx); +void arm_spe_send_buffer(void *arg, int pending __unused); + +/* + PSB CSYNC is a Profiling Synchronization Barrier encoded in the hint space + * so it is a NOP on earlier architecture. + */ +#define psb_csync() __asm __volatile("hint #17" ::: "memory"); + +struct arm_spe_softc { + device_t dev; + + struct resource *sc_irq_res; + void *sc_irq_cookie; + struct cdev *sc_cdev; + struct mtx sc_lock; + struct task task; + + int64_t sc_pmsidr; + int kqueue_fd; + struct thread *hwt_td; + struct arm_spe_info *spe_info; + struct hwt_context *ctx; + STAILQ_HEAD(, arm_spe_queue) pending; + uint64_t npending; + + uint64_t pmbidr; + uint64_t pmsidr; + + uint16_t kva_align; +}; + +struct arm_spe_buf_info { + struct arm_spe_info *info; + uint64_t pmbptr; + uint8_t buf_idx : 1; + bool buf_svc : 1; + bool buf_wait : 1; + bool partial_rec : 1; +}; + +struct arm_spe_info { + int ident; /* tid or cpu_id */ + struct mtx lock; + struct arm_spe_softc *sc; + struct task task[2]; + bool enabled : 1; + + /* buffer is split in half as a ping-pong buffer */ + vm_object_t bufobj; + vm_offset_t kvaddr; + size_t buf_size; + uint8_t buf_idx : 1; /* 0 = first half of buf, 1 = 2nd half */ + struct arm_spe_buf_info buf_info[2]; + + /* config */ + enum arm_spe_profiling_level level; + enum arm_spe_ctx_field ctx_field; + /* filters */ + uint64_t pmsfcr; + uint64_t pmsevfr; + uint64_t pmslatfr; + /* interval */ + uint64_t pmsirr; + uint64_t pmsicr; + /* control */ + uint64_t pmscr; +}; + +struct arm_spe_queue { + int ident; + u_int buf_idx : 1; + bool partial_rec : 1; + bool final_buf : 1; + vm_offset_t offset; + STAILQ_ENTRY(arm_spe_queue) next; +}; + +static inline vm_offset_t buf_start_addr(u_int buf_idx, struct arm_spe_info *info) +{ + vm_offset_t addr; + if (buf_idx == 0) + addr = info->kvaddr; + if (buf_idx == 1) + addr = info->kvaddr + (info->buf_size/2); + + return (addr); +} + +static inline vm_offset_t buf_end_addr(u_int buf_idx, struct arm_spe_info *info) +{ + vm_offset_t addr; + if (buf_idx == 0) + addr = info->kvaddr + (info->buf_size/2); + if (buf_idx == 1) + addr = info->kvaddr + info->buf_size; + + return (addr); +} + +#endif /* _ARM64_ARM_SPE_DEV_H_ */ diff --git a/sys/arm64/spe/arm_spe_fdt.c b/sys/arm64/spe/arm_spe_fdt.c new file mode 100644 index 000000000000..d16f1dee2ac8 --- /dev/null +++ b/sys/arm64/spe/arm_spe_fdt.c @@ -0,0 +1,75 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024 Arm Ltd + * Copyright (c) 2022 The FreeBSD Foundation + * + * Portions of this software were developed by Andrew Turner under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/module.h> +#include <sys/mutex.h> + +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> +#include <dev/ofw/openfirm.h> + +#include <arm64/spe/arm_spe_dev.h> + +static device_probe_t arm_spe_fdt_probe; + +static struct ofw_compat_data compat_data[] = { + {"arm,statistical-profiling-extension-v1", true}, + {NULL, false}, +}; + +static device_method_t arm_spe_fdt_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, arm_spe_fdt_probe), + + DEVMETHOD_END, +}; + +DEFINE_CLASS_1(spe, arm_spe_fdt_driver, arm_spe_fdt_methods, + sizeof(struct arm_spe_softc), arm_spe_driver); + +DRIVER_MODULE(spe, simplebus, arm_spe_fdt_driver, 0, 0); + +static int +arm_spe_fdt_probe(device_t dev) +{ + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + return (ENXIO); + + device_set_desc(dev, "ARM Statistical Profiling Extension"); + return (BUS_PROBE_DEFAULT); +} diff --git a/sys/arm64/vmm/vmm_arm64.c b/sys/arm64/vmm/vmm_arm64.c index 006239431f29..aa1361049f49 100644 --- a/sys/arm64/vmm/vmm_arm64.c +++ b/sys/arm64/vmm/vmm_arm64.c @@ -1364,7 +1364,7 @@ vmmops_setcap(void *vcpui, int num, int val) break; if (val != 0) hypctx->mdcr_el2 |= MDCR_EL2_TDE; - else + else if ((hypctx->setcaps & (1ul << VM_CAP_SS_EXIT)) == 0) hypctx->mdcr_el2 &= ~MDCR_EL2_TDE; break; case VM_CAP_SS_EXIT: @@ -1373,20 +1373,20 @@ vmmops_setcap(void *vcpui, int num, int val) if (val != 0) { hypctx->debug_spsr |= (hypctx->tf.tf_spsr & PSR_SS); - hypctx->debug_mdscr |= hypctx->mdscr_el1 & - (MDSCR_SS | MDSCR_KDE); + hypctx->debug_mdscr |= (hypctx->mdscr_el1 & MDSCR_SS); hypctx->tf.tf_spsr |= PSR_SS; - hypctx->mdscr_el1 |= MDSCR_SS | MDSCR_KDE; + hypctx->mdscr_el1 |= MDSCR_SS; hypctx->mdcr_el2 |= MDCR_EL2_TDE; } else { hypctx->tf.tf_spsr &= ~PSR_SS; hypctx->tf.tf_spsr |= hypctx->debug_spsr; hypctx->debug_spsr &= ~PSR_SS; - hypctx->mdscr_el1 &= ~(MDSCR_SS | MDSCR_KDE); + hypctx->mdscr_el1 &= ~MDSCR_SS; hypctx->mdscr_el1 |= hypctx->debug_mdscr; - hypctx->debug_mdscr &= ~(MDSCR_SS | MDSCR_KDE); - hypctx->mdcr_el2 &= ~MDCR_EL2_TDE; + hypctx->debug_mdscr &= ~MDSCR_SS; + if ((hypctx->setcaps & (1ul << VM_CAP_BRK_EXIT)) == 0) + hypctx->mdcr_el2 &= ~MDCR_EL2_TDE; } break; case VM_CAP_MASK_HWINTR: diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c index 08747cd59131..9434756b87f9 100644 --- a/sys/cam/ata/ata_da.c +++ b/sys/cam/ata/ata_da.c @@ -2328,15 +2328,38 @@ adastart(struct cam_periph *periph, union ccb *start_ccb) { struct ada_softc *softc = (struct ada_softc *)periph->softc; struct ccb_ataio *ataio = &start_ccb->ataio; + uint32_t priority = start_ccb->ccb_h.pinfo.priority; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastart\n")); + /* + * When we're running the state machine, we should only accept DEV CCBs. + * When we're doing normal I/O we should only accept NORMAL CCBs. + * + * While in the state machine, we carefully single step the queue, but + * there's no protection for 'extra' calls to xpt_schedule() at the + * wrong priority. Guard against that so that we filter any CCBs that + * are offered at the wrong priority. This avoids generating requests + * that are at normal priority. +` */ + if ((softc->state != ADA_STATE_NORMAL && priority != CAM_PRIORITY_DEV) || + (softc->state == ADA_STATE_NORMAL && priority != CAM_PRIORITY_NORMAL)) { + xpt_print(periph->path, "Bad priority for state %d prio %d\n", + softc->state, priority); + xpt_release_ccb(start_ccb); + return; + } + switch (softc->state) { case ADA_STATE_NORMAL: { struct bio *bp; uint8_t tag_code; + KASSERT(priority == CAM_PRIORITY_NORMAL, + ("Expected priority %d, found %d in state normal", + CAM_PRIORITY_NORMAL, priority)); + bp = cam_iosched_next_bio(softc->cam_iosched); if (bp == NULL) { xpt_release_ccb(start_ccb); @@ -2555,6 +2578,11 @@ out: case ADA_STATE_RAHEAD: case ADA_STATE_WCACHE: { + KASSERT(priority == CAM_PRIORITY_DEV, + ("Expected priority %d, found %d in state %s", + CAM_PRIORITY_DEV, priority, + softc->state == ADA_STATE_RAHEAD ? "rahead" : "wcache")); + cam_fill_ataio(ataio, 1, adadone, @@ -2581,6 +2609,10 @@ out: { struct ata_gp_log_dir *log_dir; + KASSERT(priority == CAM_PRIORITY_DEV, + ("Expected priority %d, found %d in state logdir", + CAM_PRIORITY_DEV, priority)); + if ((softc->flags & ADA_FLAG_CAN_LOG) == 0) { adaprobedone(periph, start_ccb); break; @@ -2615,6 +2647,10 @@ out: { struct ata_identify_log_pages *id_dir; + KASSERT(priority == CAM_PRIORITY_DEV, + ("Expected priority %d, found %d in state iddir", + CAM_PRIORITY_DEV, priority)); + id_dir = malloc(sizeof(*id_dir), M_ATADA, M_NOWAIT | M_ZERO); if (id_dir == NULL) { xpt_print(periph->path, "Couldn't malloc id_dir " @@ -2643,6 +2679,10 @@ out: { struct ata_identify_log_sup_cap *sup_cap; + KASSERT(priority == CAM_PRIORITY_DEV, + ("Expected priority %d, found %d in state sup_cap", + CAM_PRIORITY_DEV, priority)); + sup_cap = malloc(sizeof(*sup_cap), M_ATADA, M_NOWAIT|M_ZERO); if (sup_cap == NULL) { xpt_print(periph->path, "Couldn't malloc sup_cap " @@ -2671,6 +2711,10 @@ out: { struct ata_zoned_info_log *ata_zone; + KASSERT(priority == CAM_PRIORITY_DEV, + ("Expected priority %d, found %d in state zone", + CAM_PRIORITY_DEV, priority)); + ata_zone = malloc(sizeof(*ata_zone), M_ATADA, M_NOWAIT|M_ZERO); if (ata_zone == NULL) { xpt_print(periph->path, "Couldn't malloc ata_zone " @@ -2896,6 +2940,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb) struct bio *bp; int error; + KASSERT(priority == CAM_PRIORITY_NORMAL, + ("Expected priority %d, found %d for normal I/O", + CAM_PRIORITY_NORMAL, priority)); + cam_periph_lock(periph); bp = (struct bio *)done_ccb->ccb_h.ccb_bp; if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { @@ -3000,6 +3048,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb) } case ADA_CCB_RAHEAD: { + KASSERT(priority == CAM_PRIORITY_DEV, + ("Expected priority %d, found %d in ccb state rahead", + CAM_PRIORITY_DEV, priority)); + if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (adaerror(done_ccb, 0, 0) == ERESTART) { /* Drop freeze taken due to CAM_DEV_QFREEZE */ @@ -3023,6 +3075,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb) } case ADA_CCB_WCACHE: { + KASSERT(priority == CAM_PRIORITY_DEV, + ("Expected priority %d, found %d in ccb state wcache", + CAM_PRIORITY_DEV, priority)); + if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (adaerror(done_ccb, 0, 0) == ERESTART) { /* Drop freeze taken due to CAM_DEV_QFREEZE */ @@ -3054,6 +3110,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb) { int error; + KASSERT(priority == CAM_PRIORITY_DEV, + ("Expected priority %d, found %d in ccb state logdir", + CAM_PRIORITY_DEV, priority)); + if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { error = 0; softc->valid_logdir_len = 0; @@ -3123,6 +3183,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb) case ADA_CCB_IDDIR: { int error; + KASSERT(priority == CAM_PRIORITY_DEV, + ("Expected priority %d, found %d in ccb state iddir", + CAM_PRIORITY_DEV, priority)); + if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { off_t entries_offset, max_entries; error = 0; @@ -3208,6 +3272,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb) case ADA_CCB_SUP_CAP: { int error; + KASSERT(priority == CAM_PRIORITY_DEV, + ("Expected priority %d, found %d in ccb state sup_cap", + CAM_PRIORITY_DEV, priority)); + if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { uint32_t valid_len; size_t needed_size; @@ -3312,6 +3380,10 @@ adadone(struct cam_periph *periph, union ccb *done_ccb) case ADA_CCB_ZONE: { int error; + KASSERT(priority == CAM_PRIORITY_DEV, + ("Expected priority %d, found %d in ccb state zone", + CAM_PRIORITY_DEV, priority)); + if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { struct ata_zoned_info_log *zi_log; uint32_t valid_len; diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c index 9c4707da482c..506fce3d99d3 100644 --- a/sys/cam/nvme/nvme_da.c +++ b/sys/cam/nvme/nvme_da.c @@ -645,12 +645,40 @@ ndacleanup(struct cam_periph *periph) } static void -ndaasync(void *callback_arg, uint32_t code, - struct cam_path *path, void *arg) +ndasetgeom(struct nda_softc *softc, struct cam_periph *periph) { - struct cam_periph *periph; + struct disk *disk = softc->disk; + struct ccb_pathinq cpi; + const struct nvme_namespace_data *nsd; + const struct nvme_controller_data *cd; + uint8_t flbas_fmt, lbads, vwc_present; + + nsd = nvme_get_identify_ns(periph); + cd = nvme_get_identify_cntrl(periph); + + flbas_fmt = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, nsd->flbas); + lbads = NVMEV(NVME_NS_DATA_LBAF_LBADS, nsd->lbaf[flbas_fmt]); + disk->d_sectorsize = 1 << lbads; + disk->d_mediasize = (off_t)(disk->d_sectorsize * nsd->nsze); + disk->d_delmaxsize = disk->d_mediasize; + disk->d_flags = DISKFLAG_DIRECT_COMPLETION; + if (nvme_ctrlr_has_dataset_mgmt(cd)) + disk->d_flags |= DISKFLAG_CANDELETE; + vwc_present = NVMEV(NVME_CTRLR_DATA_VWC_PRESENT, cd->vwc); + if (vwc_present) + disk->d_flags |= DISKFLAG_CANFLUSHCACHE; + if ((cpi.hba_misc & PIM_UNMAPPED) != 0) { + disk->d_flags |= DISKFLAG_UNMAPPED_BIO; + softc->unmappedio = 1; + } +} + +static void +ndaasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg) +{ + struct cam_periph *periph = callback_arg; + struct nda_softc *softc; - periph = (struct cam_periph *)callback_arg; switch (code) { case AC_FOUND_DEVICE: { @@ -681,17 +709,29 @@ ndaasync(void *callback_arg, uint32_t code, "due to status 0x%x\n", status); break; } + case AC_GETDEV_CHANGED: + { + int error; + + softc = periph->softc; + ndasetgeom(softc, periph); + error = disk_resize(softc->disk, M_NOWAIT); + if (error != 0) { + xpt_print(periph->path, "disk_resize(9) failed, error = %d\n", error); + break; + } + break; + + } case AC_ADVINFO_CHANGED: { uintptr_t buftype; + softc = periph->softc; buftype = (uintptr_t)arg; if (buftype == CDAI_TYPE_PHYS_PATH) { - struct nda_softc *softc; - - softc = periph->softc; disk_attr_changed(softc->disk, "GEOM::physpath", - M_NOWAIT); + M_NOWAIT); } break; } @@ -847,7 +887,6 @@ ndaregister(struct cam_periph *periph, void *arg) const struct nvme_namespace_data *nsd; const struct nvme_controller_data *cd; char announce_buf[80]; - uint8_t flbas_fmt, lbads, vwc_present; u_int maxio; int quirks; @@ -904,21 +943,8 @@ ndaregister(struct cam_periph *periph, void *arg) else if (maxio > maxphys) maxio = maxphys; /* for safety */ disk->d_maxsize = maxio; - flbas_fmt = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, nsd->flbas); - lbads = NVMEV(NVME_NS_DATA_LBAF_LBADS, nsd->lbaf[flbas_fmt]); - disk->d_sectorsize = 1 << lbads; - disk->d_mediasize = (off_t)(disk->d_sectorsize * nsd->nsze); - disk->d_delmaxsize = disk->d_mediasize; - disk->d_flags = DISKFLAG_DIRECT_COMPLETION; - if (nvme_ctrlr_has_dataset_mgmt(cd)) - disk->d_flags |= DISKFLAG_CANDELETE; - vwc_present = NVMEV(NVME_CTRLR_DATA_VWC_PRESENT, cd->vwc); - if (vwc_present) - disk->d_flags |= DISKFLAG_CANFLUSHCACHE; - if ((cpi.hba_misc & PIM_UNMAPPED) != 0) { - disk->d_flags |= DISKFLAG_UNMAPPED_BIO; - softc->unmappedio = 1; - } + ndasetgeom(softc, periph); + /* * d_ident and d_descr are both far bigger than the length of either * the serial or model number strings. @@ -983,7 +1009,7 @@ ndaregister(struct cam_periph *periph, void *arg) * Register for device going away and info about the drive * changing (though with NVMe, it can't) */ - xpt_register_async(AC_LOST_DEVICE | AC_ADVINFO_CHANGED, + xpt_register_async(AC_LOST_DEVICE | AC_ADVINFO_CHANGED | AC_GETDEV_CHANGED, ndaasync, periph, periph->path); softc->state = NDA_STATE_NORMAL; diff --git a/sys/cam/nvme/nvme_xpt.c b/sys/cam/nvme/nvme_xpt.c index f6667df07be0..c22d5fed350c 100644 --- a/sys/cam/nvme/nvme_xpt.c +++ b/sys/cam/nvme/nvme_xpt.c @@ -463,6 +463,8 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action(done_ccb); xpt_async(AC_FOUND_DEVICE, path, done_ccb); + } else { + xpt_async(AC_GETDEV_CHANGED, path, NULL); } NVME_PROBE_SET_ACTION(softc, NVME_PROBE_DONE); break; diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index c0c0be12856b..773a786d08f7 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -3369,12 +3369,33 @@ static void dastart(struct cam_periph *periph, union ccb *start_ccb) { struct da_softc *softc; + uint32_t priority = start_ccb->ccb_h.pinfo.priority; cam_periph_assert(periph, MA_OWNED); softc = (struct da_softc *)periph->softc; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastart\n")); + /* + * When we're running the state machine, we should only accept DEV CCBs. + * When we're doing normal I/O we should only accept NORMAL CCBs. + * + * While in the state machine, we carefully single step the queue, but + * there's no protection for 'extra' calls to xpt_schedule() at the + * wrong priority. Guard against that so that we filter any CCBs that + * are offered at the wrong priority. This avoids generating requests + * that are at normal priority. In addition, though we can't easily + * enforce it, one must not transition to the NORMAL state via the + * skipstate mechanism. +` */ + if ((softc->state != DA_STATE_NORMAL && priority != CAM_PRIORITY_DEV) || + (softc->state == DA_STATE_NORMAL && priority != CAM_PRIORITY_NORMAL)) { + xpt_print(periph->path, "Bad priority for state %d prio %d\n", + softc->state, priority); + xpt_release_ccb(start_ccb); + return; + } + skipstate: switch (softc->state) { case DA_STATE_NORMAL: diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h index c9de1fe4c391..d3ae3c32635d 100644 --- a/sys/cddl/boot/zfs/zfsimpl.h +++ b/sys/cddl/boot/zfs/zfsimpl.h @@ -94,6 +94,7 @@ typedef enum { B_FALSE, B_TRUE } boolean_t; #define P2END(x, align) (-(~(x) & -(align))) #define P2PHASEUP(x, align, phase) ((phase) - (((phase) - (x)) & -(align))) #define P2BOUNDARY(off, len, align) (((off) ^ ((off) + (len) - 1)) > (align) - 1) +#define IS_P2ALIGNED(v, a) ((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0) /* * General-purpose 32-bit and 64-bit bitfield encodings. @@ -498,19 +499,7 @@ typedef struct zio_eck { * Gang block headers are self-checksumming and contain an array * of block pointers. */ -#define SPA_GANGBLOCKSIZE SPA_MINBLOCKSIZE -#define SPA_GBH_NBLKPTRS ((SPA_GANGBLOCKSIZE - \ - sizeof (zio_eck_t)) / sizeof (blkptr_t)) -#define SPA_GBH_FILLER ((SPA_GANGBLOCKSIZE - \ - sizeof (zio_eck_t) - \ - (SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\ - sizeof (uint64_t)) - -typedef struct zio_gbh { - blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS]; - uint64_t zg_filler[SPA_GBH_FILLER]; - zio_eck_t zg_tail; -} zio_gbh_phys_t; +#define SPA_OLD_GANGBLOCKSIZE SPA_MINBLOCKSIZE #define VDEV_RAIDZ_MAXPARITY 3 diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h index c274a9f3357a..242a32e140f5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h @@ -70,6 +70,9 @@ typedef int processorid_t; #include <sys/linker.h> #include <sys/ioccom.h> #include <sys/cred.h> +#ifdef __FreeBSD__ +#include <sys/_mutex.h> +#endif #include <sys/proc.h> #include <sys/types.h> #include <sys/ucred.h> diff --git a/sys/cddl/dev/dtrace/x86/instr_size.c b/sys/cddl/dev/dtrace/x86/instr_size.c index 4397b3bd69d7..41faf0f3e5aa 100644 --- a/sys/cddl/dev/dtrace/x86/instr_size.c +++ b/sys/cddl/dev/dtrace/x86/instr_size.c @@ -29,6 +29,9 @@ #include <sys/types.h> #include <sys/param.h> +#ifdef __FreeBSD__ +#include <sys/_mutex.h> +#endif #include <sys/proc.h> #ifdef illumos #include <sys/cmn_err.h> diff --git a/sys/compat/linuxkpi/common/include/net/cfg80211.h b/sys/compat/linuxkpi/common/include/net/cfg80211.h index f769cfdd4075..305026b34451 100644 --- a/sys/compat/linuxkpi/common/include/net/cfg80211.h +++ b/sys/compat/linuxkpi/common/include/net/cfg80211.h @@ -1450,7 +1450,7 @@ cfg80211_chandef_create(struct cfg80211_chan_def *chandef, KASSERT(chandef != NULL, ("%s: chandef is NULL\n", __func__)); KASSERT(chan != NULL, ("%s: chan is NULL\n", __func__)); - /* memset(chandef, 0, sizeof(*chandef)); */ + memset(chandef, 0, sizeof(*chandef)); chandef->chan = chan; chandef->center_freq1 = chan->center_freq; /* chandef->width, center_freq2, punctured */ diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h index ee1ace3684de..0eda07a8235c 100644 --- a/sys/compat/linuxkpi/common/include/net/mac80211.h +++ b/sys/compat/linuxkpi/common/include/net/mac80211.h @@ -1315,7 +1315,7 @@ ieee80211_hw_restart_disconnect(struct ieee80211_vif *vif) for (_linkid = 0; _linkid < nitems((_sta)->link); _linkid++) \ if ( ((_vif)->active_links == 0 /* no MLO */ || \ ((_vif)->active_links & BIT(_linkid)) != 0) && \ - (_linksta = link_sta_dereference_protected((_sta), (_linkid))) ) + (_linksta = link_sta_dereference_check((_sta), (_linkid))) ) /* -------------------------------------------------------------------------- */ diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index 0dc3b2631804..8b1f5f0e0399 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -832,6 +832,7 @@ lkpi_lsta_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], sta->deflink.smps_mode = IEEE80211_SMPS_OFF; sta->deflink.bandwidth = IEEE80211_STA_RX_BW_20; sta->deflink.rx_nss = 1; + sta->deflink.sta = sta; lkpi_sta_sync_from_ni(hw, vif, sta, ni, false); @@ -2308,6 +2309,10 @@ lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int changed |= IEEE80211_CHANCTX_CHANGE_WIDTH; lkpi_80211_mo_change_chanctx(hw, chanctx_conf, changed); } else { + /* The device is no longer idle. */ + IMPROVE("Once we do multi-vif, only do for 1st chanctx"); + lkpi_hw_conf_idle(hw, false); + error = lkpi_80211_mo_add_chanctx(hw, chanctx_conf); if (error == 0 || error == EOPNOTSUPP) { vif->bss_conf.chanreq.oper.chan = chanctx_conf->def.chan; @@ -3081,8 +3086,6 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int lsta->in_mgd = false; } - lkpi_hw_conf_idle(hw, false); - /* * And then: * - (more packets)? @@ -6904,17 +6907,23 @@ linuxkpi_ieee80211_iterate_interfaces(struct ieee80211_hw *hw, if (flags & ~(IEEE80211_IFACE_ITER_NORMAL| IEEE80211_IFACE_ITER_RESUME_ALL| IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER| - IEEE80211_IFACE_ITER_ACTIVE|IEEE80211_IFACE_ITER__ATOMIC)) { + IEEE80211_IFACE_ITER_ACTIVE|IEEE80211_IFACE_ITER__ATOMIC| + IEEE80211_IFACE_ITER__MTX)) { ic_printf(lhw->ic, "XXX TODO %s flags(%#x) not yet supported.\n", __func__, flags); } + if ((flags & IEEE80211_IFACE_ITER__MTX) != 0) + lockdep_assert_wiphy(hw->wiphy); + active = (flags & IEEE80211_IFACE_ITER_ACTIVE) != 0; atomic = (flags & IEEE80211_IFACE_ITER__ATOMIC) != 0; nin_drv = (flags & IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER) != 0; - if (atomic) + if (atomic) { + IMPROVE("LKPI_80211_LHW_LVIF_LOCK atomic assume to be rcu?"); LKPI_80211_LHW_LVIF_LOCK(lhw); + } TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) { struct ieee80211vap *vap; diff --git a/sys/conf/NOTES b/sys/conf/NOTES index df71aa60099d..3d5f7dd8a71b 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2825,6 +2825,10 @@ options RANDOM_ENABLE_UMA # slab allocator # environment. options RANDOM_ENABLE_ETHER # ether_input +options RANDOM_ENABLE_KBD +options RANDOM_ENABLE_MOUSE +options RANDOM_ENABLE_TPM # implies TPM_HARVEST + # Module to enable execution of application via emulators like QEMU options IMGACT_BINMISC diff --git a/sys/conf/files b/sys/conf/files index 87c8830b192e..53fcb80f2b8d 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2278,6 +2278,10 @@ iwn6050.fw optional iwn6050fw | iwnfw \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6050.fw" +dev/iwx/if_iwx.c optional iwx \ + compile-with "${NORMAL_C} -DIWX_DEBUG=1" +dev/iwx/if_iwx_debug.c optional iwx \ + compile-with "${NORMAL_C} -DIWX_DEBUG=1" dev/ixgbe/if_ix.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe -DSMP" dev/ixgbe/if_ixv.c optional ixv inet \ diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 882aca705336..886980de754b 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -26,6 +26,10 @@ arm64/acpica/OsdEnvironment.c optional acpi arm64/acpica/acpi_wakeup.c optional acpi arm64/acpica/pci_cfgreg.c optional acpi pci arm64/arm64/autoconf.c standard +arm64/spe/arm_spe_backend.c optional hwt spe +arm64/spe/arm_spe_dev.c optional hwt spe +arm64/spe/arm_spe_acpi.c optional hwt spe acpi +arm64/spe/arm_spe_fdt.c optional hwt spe fdt arm64/arm64/bus_machdep.c standard arm64/arm64/bus_space_asm.S standard arm64/arm64/busdma_bounce.c standard @@ -590,23 +594,23 @@ arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt soc_brcm_bcm2837 | arm/broadcom/bcm2835/bcm2838_pci.c optional soc_brcm_bcm2838 fdt pci arm/broadcom/bcm2835/bcm2838_xhci.c optional soc_brcm_bcm2838 fdt pci xhci arm/broadcom/bcm2835/raspberrypi_gpio.c optional soc_brcm_bcm2837 gpio fdt | soc_brcm_bcm2838 gpio fdt -contrib/vchiq/interface/compat/vchi_bsd.c optional vchiq soc_brcm_bcm2837 \ +contrib/vchiq/interface/compat/vchi_bsd.c optional vchiq soc_brcm_bcm2837 fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" -contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c optional vchiq soc_brcm_bcm2837 \ +contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c optional vchiq soc_brcm_bcm2837 fdt \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" -contrib/vchiq/interface/vchiq_arm/vchiq_arm.c optional vchiq soc_brcm_bcm2837 \ +contrib/vchiq/interface/vchiq_arm/vchiq_arm.c optional vchiq soc_brcm_bcm2837 fdt \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" -contrib/vchiq/interface/vchiq_arm/vchiq_connected.c optional vchiq soc_brcm_bcm2837 \ +contrib/vchiq/interface/vchiq_arm/vchiq_connected.c optional vchiq soc_brcm_bcm2837 fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" -contrib/vchiq/interface/vchiq_arm/vchiq_core.c optional vchiq soc_brcm_bcm2837 \ +contrib/vchiq/interface/vchiq_arm/vchiq_core.c optional vchiq soc_brcm_bcm2837 fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" -contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c optional vchiq soc_brcm_bcm2837 \ +contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c optional vchiq soc_brcm_bcm2837 fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" -contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c optional vchiq soc_brcm_bcm2837 \ +contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c optional vchiq soc_brcm_bcm2837 fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" -contrib/vchiq/interface/vchiq_arm/vchiq_shim.c optional vchiq soc_brcm_bcm2837 \ +contrib/vchiq/interface/vchiq_arm/vchiq_shim.c optional vchiq soc_brcm_bcm2837 fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" -contrib/vchiq/interface/vchiq_arm/vchiq_util.c optional vchiq soc_brcm_bcm2837 \ +contrib/vchiq/interface/vchiq_arm/vchiq_util.c optional vchiq soc_brcm_bcm2837 fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" # Cavium diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index 0fd2d4050cf1..6e20dce0653f 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -472,7 +472,7 @@ CLEANFILES+= ${_i} .m.h: ${SYSDIR}/tools/makeobjops.awk ${AWK} -f ${SYSDIR}/tools/makeobjops.awk ${.IMPSRC} -h -.for _i in mii pccard +.for _i in mii .if !empty(SRCS:M${_i}devs.h) CLEANFILES+= ${_i}devs.h ${_i}devs.h: ${SYSDIR}/tools/${_i}devs2h.awk ${SYSDIR}/dev/${_i}/${_i}devs diff --git a/sys/conf/options b/sys/conf/options index b00b381d1da1..2437c2c6908a 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -956,6 +956,9 @@ RANDOM_LOADABLE opt_global.h # the uma slab allocator. RANDOM_ENABLE_UMA opt_global.h RANDOM_ENABLE_ETHER opt_global.h +RANDOM_ENABLE_KBD opt_global.h +RANDOM_ENABLE_MOUSE opt_global.h +RANDOM_ENABLE_TPM opt_global.h # This options turns TPM into entropy source. TPM_HARVEST opt_tpm.h diff --git a/sys/contrib/dev/iwlwifi/mld/agg.c b/sys/contrib/dev/iwlwifi/mld/agg.c index 3a346bcd6665..e3bc8767297a 100644 --- a/sys/contrib/dev/iwlwifi/mld/agg.c +++ b/sys/contrib/dev/iwlwifi/mld/agg.c @@ -201,7 +201,11 @@ iwl_mld_reorder(struct iwl_mld *mld, struct napi_struct *napi, struct iwl_mld_link_sta *mld_link_sta; u32 reorder = le32_to_cpu(desc->reorder_data); bool amsdu, last_subframe, is_old_sn, is_dup; +#if defined(__linux__) u8 tid = ieee80211_get_tid(hdr); +#elif defined(__FreeBSD__) + u8 tid; +#endif u8 baid; u16 nssn, sn; u32 sta_mask = 0; @@ -243,6 +247,10 @@ iwl_mld_reorder(struct iwl_mld *mld, struct napi_struct *napi, for_each_mld_link_sta(mld_sta, mld_link_sta, link_id) sta_mask |= BIT(mld_link_sta->fw_id); +#if defined(__FreeBSD__) + tid = ieee80211_get_tid(hdr); +#endif + /* verify the BAID is correctly mapped to the sta and tid */ if (IWL_FW_CHECK(mld, tid != baid_data->tid || diff --git a/sys/contrib/edk2/Include/Base.h b/sys/contrib/edk2/Include/Base.h index e3d03a9cc5ab..3ae798db8429 100644 --- a/sys/contrib/edk2/Include/Base.h +++ b/sys/contrib/edk2/Include/Base.h @@ -829,7 +829,7 @@ STATIC_ASSERT (sizeof (CHAR16) == 2, "sizeof (CHAR16) does not meet UEFI Specif * fail, but it also takes lengths to never use either of these constructs. The * boot loader, however, uses them and needs these assertionst o be correct. */ -#ifdef _STANDALONE +#if 0 STATIC_ASSERT (sizeof (L'A') == 2, "sizeof (L'A') does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (sizeof (L"A") == 4, "sizeof (L\"A\") does not meet UEFI Specification Data Type requirements"); #endif @@ -841,8 +841,10 @@ STATIC_ASSERT (ALIGNOF (INT16) == sizeof (INT16), "Alignment of INT16 does not STATIC_ASSERT (ALIGNOF (UINT16) == sizeof (UINT16), "Alignment of UINT16 does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (ALIGNOF (INT32) == sizeof (INT32), "Alignment of INT32 does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (ALIGNOF (UINT32) == sizeof (UINT32), "Alignment of UINT32 does not meet UEFI Specification Data Type requirements"); +#ifndef _STANDALONE STATIC_ASSERT (ALIGNOF (INT64) == sizeof (INT64), "Alignment of INT64 does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (ALIGNOF (UINT64) == sizeof (UINT64), "Alignment of UINT64 does not meet UEFI Specification Data Type requirements"); +#endif STATIC_ASSERT (ALIGNOF (CHAR8) == sizeof (CHAR8), "Alignment of CHAR8 does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (ALIGNOF (CHAR16) == sizeof (CHAR16), "Alignment of CHAR16 does not meet UEFI Specification Data Type requirements"); STATIC_ASSERT (ALIGNOF (INTN) == sizeof (INTN), "Alignment of INTN does not meet UEFI Specification Data Type requirements"); diff --git a/sys/contrib/edk2/Include/Guid/Acpi.h b/sys/contrib/edk2/Include/Guid/Acpi.h new file mode 100644 index 000000000000..9e9d6b5f05a7 --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/Acpi.h @@ -0,0 +1,40 @@ +/** @file + GUIDs used for ACPI entries in the EFI system table + + These GUIDs point the ACPI tables as defined in the ACPI specifications. + ACPI 2.0 specification defines the ACPI 2.0 GUID. UEFI 2.0 defines the + ACPI 2.0 Table GUID and ACPI Table GUID. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + GUIDs defined in UEFI 2.0 spec. + +**/ + +#ifndef __ACPI_GUID_H__ +#define __ACPI_GUID_H__ + +#define ACPI_TABLE_GUID \ + { \ + 0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define EFI_ACPI_TABLE_GUID \ + { \ + 0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \ + } + +#define ACPI_10_TABLE_GUID ACPI_TABLE_GUID + +// +// ACPI 2.0 or newer tables should use EFI_ACPI_TABLE_GUID. +// +#define EFI_ACPI_20_TABLE_GUID EFI_ACPI_TABLE_GUID + +extern EFI_GUID gEfiAcpiTableGuid; +extern EFI_GUID gEfiAcpi10TableGuid; +extern EFI_GUID gEfiAcpi20TableGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Guid/DebugImageInfoTable.h b/sys/contrib/edk2/Include/Guid/DebugImageInfoTable.h new file mode 100644 index 000000000000..c20cc626a07b --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/DebugImageInfoTable.h @@ -0,0 +1,74 @@ +/** @file + GUID and related data structures used with the Debug Image Info Table. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + GUID defined in UEFI 2.0 spec. + +**/ + +#ifndef __DEBUG_IMAGE_INFO_GUID_H__ +#define __DEBUG_IMAGE_INFO_GUID_H__ + +#include <Protocol/LoadedImage.h> + +/// +/// EFI_DEBUG_IMAGE_INFO_TABLE configuration table GUID declaration. +/// +#define EFI_DEBUG_IMAGE_INFO_TABLE_GUID \ + { \ + 0x49152e77, 0x1ada, 0x4764, {0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b } \ + } + +#define EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS 0x01 +#define EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED 0x02 + +#define EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL 0x01 + +typedef struct { + UINT64 Signature; ///< A constant UINT64 that has the value EFI_SYSTEM_TABLE_SIGNATURE + EFI_PHYSICAL_ADDRESS EfiSystemTableBase; ///< The physical address of the EFI system table. + UINT32 Crc32; ///< A 32-bit CRC value that is used to verify the EFI_SYSTEM_TABLE_POINTER structure is valid. +} EFI_SYSTEM_TABLE_POINTER; + +typedef struct { + /// + /// Indicates the type of image info structure. For PE32 EFI images, + /// this is set to EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL. + /// + UINT32 ImageInfoType; + /// + /// A pointer to an instance of the loaded image protocol for the associated image. + /// + EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocolInstance; + /// + /// Indicates the image handle of the associated image. + /// + EFI_HANDLE ImageHandle; +} EFI_DEBUG_IMAGE_INFO_NORMAL; + +typedef union { + UINT32 *ImageInfoType; + EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; +} EFI_DEBUG_IMAGE_INFO; + +typedef struct { + /// + /// UpdateStatus is used by the system to indicate the state of the debug image info table. + /// + volatile UINT32 UpdateStatus; + /// + /// The number of EFI_DEBUG_IMAGE_INFO elements in the array pointed to by EfiDebugImageInfoTable. + /// + UINT32 TableSize; + /// + /// A pointer to the first element of an array of EFI_DEBUG_IMAGE_INFO structures. + /// + EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable; +} EFI_DEBUG_IMAGE_INFO_TABLE_HEADER; + +extern EFI_GUID gEfiDebugImageInfoTableGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Guid/DxeServices.h b/sys/contrib/edk2/Include/Guid/DxeServices.h new file mode 100644 index 000000000000..128be13148b0 --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/DxeServices.h @@ -0,0 +1,26 @@ +/** @file + GUID used to identify the DXE Services Table + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + GUID introduced in PI Version 1.0. + +**/ + +#ifndef __DXE_SERVICES_GUID_H__ +#define __DXE_SERVICES_GUID_H__ + +// +// The DXE Services Table shall be stored in memory of type +// EfiBootServicesData +// +#define DXE_SERVICES_TABLE_GUID \ + { \ + 0x5ad34ba, 0x6f02, 0x4214, {0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9 } \ + } + +extern EFI_GUID gEfiDxeServicesTableGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Guid/Fdt.h b/sys/contrib/edk2/Include/Guid/Fdt.h new file mode 100644 index 000000000000..e0091468292a --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/Fdt.h @@ -0,0 +1,22 @@ +/** @file
+*
+* Copyright (c) 2013-2014, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef __FDT_H__
+#define __FDT_H__
+
+#define FDT_TABLE_GUID \
+ { 0xb1b621d5, 0xf19c, 0x41a5, { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } }
+
+extern EFI_GUID gFdtTableGuid;
+
+#define FDT_VARIABLE_GUID \
+ { 0x25a4fd4a, 0x9703, 0x4ba9, { 0xa1, 0x90, 0xb7, 0xc8, 0x4e, 0xfb, 0x3e, 0x57 } }
+
+extern EFI_GUID gFdtVariableGuid;
+
+#endif /* __FDT_H__ */
diff --git a/sys/contrib/edk2/Include/Guid/GlobalVariable.h b/sys/contrib/edk2/Include/Guid/GlobalVariable.h new file mode 100644 index 000000000000..26ba93b4b1c6 --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/GlobalVariable.h @@ -0,0 +1,192 @@ +/** @file + GUID for EFI (NVRAM) Variables. + + Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + GUID defined in UEFI 2.1 +**/ + +#ifndef __GLOBAL_VARIABLE_GUID_H__ +#define __GLOBAL_VARIABLE_GUID_H__ + +#define EFI_GLOBAL_VARIABLE \ + { \ + 0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } \ + } + +extern EFI_GUID gEfiGlobalVariableGuid; + +// +// Follow UEFI 2.4 spec: +// To prevent name collisions with possible future globally defined variables, +// other internal firmware data variables that are not defined here must be +// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or +// any other GUID defined by the UEFI Specification. Implementations must +// only permit the creation of variables with a UEFI Specification-defined +// VendorGuid when these variables are documented in the UEFI Specification. +// +// Note: except the globally defined variables defined below, the spec also defines +// L"Boot####" - A boot load option. +// L"Driver####" - A driver load option. +// L"SysPrep####" - A System Prep application load option. +// L"Key####" - Describes hot key relationship with a Boot#### load option. +// The attribute for them is NV+BS+RT, #### is a printed hex value, and no 0x or h +// is included in the hex value. They can not be expressed as a #define like other globally +// defined variables, it is because we can not list the Boot0000, Boot0001, etc one by one. +// + +/// +/// The language codes that the firmware supports. This value is deprecated. +/// Its attribute is BS+RT. +/// +#define EFI_LANG_CODES_VARIABLE_NAME L"LangCodes" +/// +/// The language code that the system is configured for. This value is deprecated. +/// Its attribute is NV+BS+RT. +/// +#define EFI_LANG_VARIABLE_NAME L"Lang" +/// +/// The firmware's boot managers timeout, in seconds, before initiating the default boot selection. +/// Its attribute is NV+BS+RT. +/// +#define EFI_TIME_OUT_VARIABLE_NAME L"Timeout" +/// +/// The language codes that the firmware supports. +/// Its attribute is BS+RT. +/// +#define EFI_PLATFORM_LANG_CODES_VARIABLE_NAME L"PlatformLangCodes" +/// +/// The language code that the system is configured for. +/// Its attribute is NV+BS+RT. +/// +#define EFI_PLATFORM_LANG_VARIABLE_NAME L"PlatformLang" +/// +/// The device path of the default input/output/error output console. +/// Its attribute is NV+BS+RT. +/// +#define EFI_CON_IN_VARIABLE_NAME L"ConIn" +#define EFI_CON_OUT_VARIABLE_NAME L"ConOut" +#define EFI_ERR_OUT_VARIABLE_NAME L"ErrOut" +/// +/// The device path of all possible input/output/error output devices. +/// Its attribute is BS+RT. +/// +#define EFI_CON_IN_DEV_VARIABLE_NAME L"ConInDev" +#define EFI_CON_OUT_DEV_VARIABLE_NAME L"ConOutDev" +#define EFI_ERR_OUT_DEV_VARIABLE_NAME L"ErrOutDev" +/// +/// The ordered boot option load list. +/// Its attribute is NV+BS+RT. +/// +#define EFI_BOOT_ORDER_VARIABLE_NAME L"BootOrder" +/// +/// The boot option for the next boot only. +/// Its attribute is NV+BS+RT. +/// +#define EFI_BOOT_NEXT_VARIABLE_NAME L"BootNext" +/// +/// The boot option that was selected for the current boot. +/// Its attribute is BS+RT. +/// +#define EFI_BOOT_CURRENT_VARIABLE_NAME L"BootCurrent" +/// +/// The types of boot options supported by the boot manager. Should be treated as read-only. +/// Its attribute is BS+RT. +/// +#define EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME L"BootOptionSupport" +/// +/// The ordered driver load option list. +/// Its attribute is NV+BS+RT. +/// +#define EFI_DRIVER_ORDER_VARIABLE_NAME L"DriverOrder" +/// +/// The ordered System Prep Application load option list. +/// Its attribute is NV+BS+RT. +/// +#define EFI_SYS_PREP_ORDER_VARIABLE_NAME L"SysPrepOrder" +/// +/// Identifies the level of hardware error record persistence +/// support implemented by the platform. This variable is +/// only modified by firmware and is read-only to the OS. +/// Its attribute is NV+BS+RT. +/// +#define EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME L"HwErrRecSupport" +/// +/// Whether the system is operating in setup mode (1) or not (0). +/// All other values are reserved. Should be treated as read-only. +/// Its attribute is BS+RT. +/// +#define EFI_SETUP_MODE_NAME L"SetupMode" +/// +/// The Key Exchange Key Signature Database. +/// Its attribute is NV+BS+RT+AT. +/// +#define EFI_KEY_EXCHANGE_KEY_NAME L"KEK" +/// +/// The public Platform Key. +/// Its attribute is NV+BS+RT+AT. +/// +#define EFI_PLATFORM_KEY_NAME L"PK" +/// +/// Array of GUIDs representing the type of signatures supported +/// by the platform firmware. Should be treated as read-only. +/// Its attribute is BS+RT. +/// +#define EFI_SIGNATURE_SUPPORT_NAME L"SignatureSupport" +/// +/// Whether the platform firmware is operating in Secure boot mode (1) or not (0). +/// All other values are reserved. Should be treated as read-only. +/// Its attribute is BS+RT. +/// +#define EFI_SECURE_BOOT_MODE_NAME L"SecureBoot" +/// +/// The OEM's default Key Exchange Key Signature Database. Should be treated as read-only. +/// Its attribute is BS+RT. +/// +#define EFI_KEK_DEFAULT_VARIABLE_NAME L"KEKDefault" +/// +/// The OEM's default public Platform Key. Should be treated as read-only. +/// Its attribute is BS+RT. +/// +#define EFI_PK_DEFAULT_VARIABLE_NAME L"PKDefault" +/// +/// The OEM's default secure boot signature store. Should be treated as read-only. +/// Its attribute is BS+RT. +/// +#define EFI_DB_DEFAULT_VARIABLE_NAME L"dbDefault" +/// +/// The OEM's default secure boot blacklist signature store. Should be treated as read-only. +/// Its attribute is BS+RT. +/// +#define EFI_DBX_DEFAULT_VARIABLE_NAME L"dbxDefault" +/// +/// The OEM's default secure boot timestamp signature store. Should be treated as read-only. +/// Its attribute is BS+RT. +/// +#define EFI_DBT_DEFAULT_VARIABLE_NAME L"dbtDefault" +/// +/// Allows the firmware to indicate supported features and actions to the OS. +/// Its attribute is BS+RT. +/// +#define EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME L"OsIndicationsSupported" +/// +/// Allows the OS to request the firmware to enable certain features and to take certain actions. +/// Its attribute is NV+BS+RT. +/// +#define EFI_OS_INDICATIONS_VARIABLE_NAME L"OsIndications" +/// +/// Whether the system is configured to use only vendor provided +/// keys or not. Should be treated as read-only. +/// Its attribute is BS+RT. +/// +#define EFI_VENDOR_KEYS_VARIABLE_NAME L"VendorKeys" + +/// +/// Whether the platform firmware is operating in device authentication boot mode (1) or not (0). +/// The content is UINT8. +/// +#define EFI_DEVICE_AUTH_BOOT_MODE_NAME L"devAuthBoot" + +#endif diff --git a/sys/contrib/edk2/Include/Guid/Gpt.h b/sys/contrib/edk2/Include/Guid/Gpt.h new file mode 100644 index 000000000000..8e6ec1f6bde0 --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/Gpt.h @@ -0,0 +1,37 @@ +/** @file + Guids used for the GPT (GUID Partition Table) + + GPT defines a new disk partitioning scheme and also describes + usage of the legacy Master Boot Record (MBR) partitioning scheme. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + GUIDs defined in UEFI 2.1 spec. + +**/ + +#ifndef __GPT_GUID_H__ +#define __GPT_GUID_H__ + +#define EFI_PART_TYPE_UNUSED_GUID \ + { \ + 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } \ + } + +#define EFI_PART_TYPE_EFI_SYSTEM_PART_GUID \ + { \ + 0xc12a7328, 0xf81f, 0x11d2, {0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } \ + } + +#define EFI_PART_TYPE_LEGACY_MBR_GUID \ + { \ + 0x024dee41, 0x33e7, 0x11d3, {0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f } \ + } + +extern EFI_GUID gEfiPartTypeUnusedGuid; +extern EFI_GUID gEfiPartTypeSystemPartGuid; +extern EFI_GUID gEfiPartTypeLegacyMbrGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Guid/HiiPlatformSetupFormset.h b/sys/contrib/edk2/Include/Guid/HiiPlatformSetupFormset.h new file mode 100644 index 000000000000..4ed0f55c05cf --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/HiiPlatformSetupFormset.h @@ -0,0 +1,33 @@ +/** @file + GUID indicates that the form set contains forms designed to be used + for platform configuration and this form set will be displayed. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + GUID defined in UEFI 2.1. + +**/ + +#ifndef __HII_PLATFORM_SETUP_FORMSET_GUID_H__ +#define __HII_PLATFORM_SETUP_FORMSET_GUID_H__ + +#define EFI_HII_PLATFORM_SETUP_FORMSET_GUID \ + { 0x93039971, 0x8545, 0x4b04, { 0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x4, 0xe } } + +#define EFI_HII_DRIVER_HEALTH_FORMSET_GUID \ + { 0xf22fc20c, 0x8cf4, 0x45eb, { 0x8e, 0x6, 0xad, 0x4e, 0x50, 0xb9, 0x5d, 0xd3 } } + +#define EFI_HII_USER_CREDENTIAL_FORMSET_GUID \ + { 0x337f4407, 0x5aee, 0x4b83, { 0xb2, 0xa7, 0x4e, 0xad, 0xca, 0x30, 0x88, 0xcd } } + +#define EFI_HII_REST_STYLE_FORMSET_GUID \ + { 0x790217bd, 0xbecf, 0x485b, { 0x91, 0x70, 0x5f, 0xf7, 0x11, 0x31, 0x8b, 0x27 } } + +extern EFI_GUID gEfiHiiPlatformSetupFormsetGuid; +extern EFI_GUID gEfiHiiDriverHealthFormsetGuid; +extern EFI_GUID gEfiHiiUserCredentialFormsetGuid; +extern EFI_GUID gEfiHiiRestStyleFormsetGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Guid/ImageAuthentication.h b/sys/contrib/edk2/Include/Guid/ImageAuthentication.h new file mode 100644 index 000000000000..9cf77466da09 --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/ImageAuthentication.h @@ -0,0 +1,385 @@ +/** @file
+ Image signature database are defined for the signed image validation.
+
+ Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ GUIDs defined in UEFI 2.5 spec.
+**/
+
+#ifndef __IMAGE_AUTHTICATION_H__
+#define __IMAGE_AUTHTICATION_H__
+
+#include <Guid/GlobalVariable.h>
+#include <Protocol/Hash.h>
+
+#define EFI_IMAGE_SECURITY_DATABASE_GUID \
+ { \
+ 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0xe, 0x67, 0x65, 0x6f } \
+ }
+
+///
+/// Varialbe name with guid EFI_IMAGE_SECURITY_DATABASE_GUID
+/// for the authorized signature database.
+///
+#define EFI_IMAGE_SECURITY_DATABASE L"db"
+///
+/// Varialbe name with guid EFI_IMAGE_SECURITY_DATABASE_GUID
+/// for the forbidden signature database.
+///
+#define EFI_IMAGE_SECURITY_DATABASE1 L"dbx"
+///
+/// Variable name with guid EFI_IMAGE_SECURITY_DATABASE_GUID
+/// for the timestamp signature database.
+///
+#define EFI_IMAGE_SECURITY_DATABASE2 L"dbt"
+
+#define SECURE_BOOT_MODE_ENABLE 1
+#define SECURE_BOOT_MODE_DISABLE 0
+
+#define SETUP_MODE 1
+#define USER_MODE 0
+
+#define DEVICE_AUTH_BOOT_MODE_ENABLE 1
+#define DEVICE_AUTH_BOOT_MODE_DISABLE 0
+
+// ***********************************************************************
+// Signature Database
+// ***********************************************************************
+///
+/// The format of a signature database.
+///
+#pragma pack(1)
+
+typedef struct {
+ ///
+ /// An identifier which identifies the agent which added the signature to the list.
+ ///
+ EFI_GUID SignatureOwner;
+ ///
+ /// The format of the signature is defined by the SignatureType.
+ ///
+ UINT8 SignatureData[1];
+} EFI_SIGNATURE_DATA;
+
+typedef struct {
+ ///
+ /// Type of the signature. GUID signature types are defined in below.
+ ///
+ EFI_GUID SignatureType;
+ ///
+ /// Total size of the signature list, including this header.
+ ///
+ UINT32 SignatureListSize;
+ ///
+ /// Size of the signature header which precedes the array of signatures.
+ ///
+ UINT32 SignatureHeaderSize;
+ ///
+ /// Size of each signature.
+ ///
+ UINT32 SignatureSize;
+ ///
+ /// Header before the array of signatures. The format of this header is specified
+ /// by the SignatureType.
+ /// UINT8 SignatureHeader[SignatureHeaderSize];
+ ///
+ /// An array of signatures. Each signature is SignatureSize bytes in length.
+ /// EFI_SIGNATURE_DATA Signatures[][SignatureSize];
+ ///
+} EFI_SIGNATURE_LIST;
+
+typedef struct {
+ ///
+ /// The SHA256 hash of an X.509 certificate's To-Be-Signed contents.
+ ///
+ EFI_SHA256_HASH ToBeSignedHash;
+ ///
+ /// The time that the certificate shall be considered to be revoked.
+ ///
+ EFI_TIME TimeOfRevocation;
+} EFI_CERT_X509_SHA256;
+
+typedef struct {
+ ///
+ /// The SHA384 hash of an X.509 certificate's To-Be-Signed contents.
+ ///
+ EFI_SHA384_HASH ToBeSignedHash;
+ ///
+ /// The time that the certificate shall be considered to be revoked.
+ ///
+ EFI_TIME TimeOfRevocation;
+} EFI_CERT_X509_SHA384;
+
+typedef struct {
+ ///
+ /// The SHA512 hash of an X.509 certificate's To-Be-Signed contents.
+ ///
+ EFI_SHA512_HASH ToBeSignedHash;
+ ///
+ /// The time that the certificate shall be considered to be revoked.
+ ///
+ EFI_TIME TimeOfRevocation;
+} EFI_CERT_X509_SHA512;
+
+typedef UINT8 EFI_SM3_HASH[32];
+
+typedef struct {
+ ///
+ /// The SM3 hash of an X.509 certificate's To-Be-Signed contents.
+ ///
+ EFI_SM3_HASH ToBeSignedHash;
+ ///
+ /// The time that the certificate shall be considered to be revoked.
+ ///
+ EFI_TIME TimeOfRevocation;
+} EFI_CERT_X509_SM3;
+
+#pragma pack()
+
+///
+/// This identifies a signature containing a SHA-256 hash. The SignatureHeader size shall
+/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
+/// 32 bytes.
+///
+#define EFI_CERT_SHA256_GUID \
+ { \
+ 0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28} \
+ }
+
+///
+/// This identifies a signature containing an RSA-2048 key. The key (only the modulus
+/// since the public key exponent is known to be 0x10001) shall be stored in big-endian
+/// order.
+/// The SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size
+/// of SignatureOwner component) + 256 bytes.
+///
+#define EFI_CERT_RSA2048_GUID \
+ { \
+ 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6} \
+ }
+
+///
+/// This identifies a signature containing a RSA-2048 signature of a SHA-256 hash. The
+/// SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size of
+/// SignatureOwner component) + 256 bytes.
+///
+#define EFI_CERT_RSA2048_SHA256_GUID \
+ { \
+ 0xe2b36190, 0x879b, 0x4a3d, {0xad, 0x8d, 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84} \
+ }
+
+///
+/// This identifies a signature containing a SHA-1 hash. The SignatureSize shall always
+/// be 16 (size of SignatureOwner component) + 20 bytes.
+///
+#define EFI_CERT_SHA1_GUID \
+ { \
+ 0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87, 0xbe, 0x1, 0x49, 0x66, 0x31, 0xbd} \
+ }
+
+///
+/// This identifies a signature containing a SM3 hash. The SignatureSize shall always
+/// be 16 (size of SignatureOwner component) + 32 bytes.
+///
+#define EFI_CERT_SM3_GUID \
+ { \
+ 0x57347f87, 0x7a9b, 0x403a, { 0xb9, 0x3c, 0xdc, 0x4a, 0xfb, 0x7a, 0xe, 0xbc } \
+ }
+
+///
+/// TThis identifies a signature containing a RSA-2048 signature of a SHA-1 hash. The
+/// SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size of
+/// SignatureOwner component) + 256 bytes.
+///
+#define EFI_CERT_RSA2048_SHA1_GUID \
+ { \
+ 0x67f8444f, 0x8743, 0x48f1, {0xa3, 0x28, 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80} \
+ }
+
+///
+/// This identifies a signature based on an X.509 certificate. If the signature is an X.509
+/// certificate then verification of the signature of an image should validate the public
+/// key certificate in the image using certificate path verification, up to this X.509
+/// certificate as a trusted root. The SignatureHeader size shall always be 0. The
+/// SignatureSize may vary but shall always be 16 (size of the SignatureOwner component) +
+/// the size of the certificate itself.
+/// Note: This means that each certificate will normally be in a separate EFI_SIGNATURE_LIST.
+///
+#define EFI_CERT_X509_GUID \
+ { \
+ 0xa5c059a1, 0x94e4, 0x4aa7, {0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72} \
+ }
+
+///
+/// This identifies a signature containing the SM3 hash of an X.509 certificate's To-Be-Signed
+/// contents, and a time of revocation. The SignatureHeader size shall always be 0. The
+/// SignatureSize shall always be 16 (size of the SignatureOwner component) + 32 bytes for
+/// an EFI_CERT_X509_SM3 structure. If the TimeOfRevocation is non-zero, the certificate should
+/// be considered to be revoked from that time and onwards, and otherwise the certificate shall
+/// be considered to always be revoked.
+///
+#define EFI_CERT_X509_SM3_GUID \
+ { \
+ 0x60d807e5, 0x10b4, 0x49a9, {0x93, 0x31, 0xe4, 0x4, 0x37, 0x88, 0x8d, 0x37 } \
+ }
+
+///
+/// This identifies a signature containing a SHA-224 hash. The SignatureHeader size shall
+/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
+/// 28 bytes.
+///
+#define EFI_CERT_SHA224_GUID \
+ { \
+ 0xb6e5233, 0xa65c, 0x44c9, {0x94, 0x7, 0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd} \
+ }
+
+///
+/// This identifies a signature containing a SHA-384 hash. The SignatureHeader size shall
+/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
+/// 48 bytes.
+///
+#define EFI_CERT_SHA384_GUID \
+ { \
+ 0xff3e5307, 0x9fd0, 0x48c9, {0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x1} \
+ }
+
+///
+/// This identifies a signature containing a SHA-512 hash. The SignatureHeader size shall
+/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
+/// 64 bytes.
+///
+#define EFI_CERT_SHA512_GUID \
+ { \
+ 0x93e0fae, 0xa6c4, 0x4f50, {0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a} \
+ }
+
+///
+/// This identifies a signature containing the SHA256 hash of an X.509 certificate's
+/// To-Be-Signed contents, and a time of revocation. The SignatureHeader size shall
+/// always be 0. The SignatureSize shall always be 16 (size of the SignatureOwner component)
+/// + 48 bytes for an EFI_CERT_X509_SHA256 structure. If the TimeOfRevocation is non-zero,
+/// the certificate should be considered to be revoked from that time and onwards, and
+/// otherwise the certificate shall be considered to always be revoked.
+///
+#define EFI_CERT_X509_SHA256_GUID \
+ { \
+ 0x3bd2a492, 0x96c0, 0x4079, {0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed } \
+ }
+
+///
+/// This identifies a signature containing the SHA384 hash of an X.509 certificate's
+/// To-Be-Signed contents, and a time of revocation. The SignatureHeader size shall
+/// always be 0. The SignatureSize shall always be 16 (size of the SignatureOwner component)
+/// + 64 bytes for an EFI_CERT_X509_SHA384 structure. If the TimeOfRevocation is non-zero,
+/// the certificate should be considered to be revoked from that time and onwards, and
+/// otherwise the certificate shall be considered to always be revoked.
+///
+#define EFI_CERT_X509_SHA384_GUID \
+ { \
+ 0x7076876e, 0x80c2, 0x4ee6, {0xaa, 0xd2, 0x28, 0xb3, 0x49, 0xa6, 0x86, 0x5b } \
+ }
+
+///
+/// This identifies a signature containing the SHA512 hash of an X.509 certificate's
+/// To-Be-Signed contents, and a time of revocation. The SignatureHeader size shall
+/// always be 0. The SignatureSize shall always be 16 (size of the SignatureOwner component)
+/// + 80 bytes for an EFI_CERT_X509_SHA512 structure. If the TimeOfRevocation is non-zero,
+/// the certificate should be considered to be revoked from that time and onwards, and
+/// otherwise the certificate shall be considered to always be revoked.
+///
+#define EFI_CERT_X509_SHA512_GUID \
+ { \
+ 0x446dbf63, 0x2502, 0x4cda, {0xbc, 0xfa, 0x24, 0x65, 0xd2, 0xb0, 0xfe, 0x9d } \
+ }
+
+///
+/// This identifies a signature containing a DER-encoded PKCS #7 version 1.5 [RFC2315]
+/// SignedData value.
+///
+#define EFI_CERT_TYPE_PKCS7_GUID \
+ { \
+ 0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} \
+ }
+
+// ***********************************************************************
+// Image Execution Information Table Definition
+// ***********************************************************************
+typedef UINT32 EFI_IMAGE_EXECUTION_ACTION;
+
+#define EFI_IMAGE_EXECUTION_AUTHENTICATION 0x00000007
+#define EFI_IMAGE_EXECUTION_AUTH_UNTESTED 0x00000000
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED 0x00000001
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_PASSED 0x00000002
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND 0x00000003
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND 0x00000004
+#define EFI_IMAGE_EXECUTION_POLICY_FAILED 0x00000005
+#define EFI_IMAGE_EXECUTION_INITIALIZED 0x00000008
+
+//
+// EFI_IMAGE_EXECUTION_INFO is added to EFI System Configuration Table
+// and assigned the GUID EFI_IMAGE_SECURITY_DATABASE_GUID.
+//
+typedef struct {
+ ///
+ /// Describes the action taken by the firmware regarding this image.
+ ///
+ EFI_IMAGE_EXECUTION_ACTION Action;
+ ///
+ /// Size of all of the entire structure.
+ ///
+ UINT32 InfoSize;
+ ///
+ /// If this image was a UEFI device driver (for option ROM, for example) this is the
+ /// null-terminated, user-friendly name for the device. If the image was for an application,
+ /// then this is the name of the application. If this cannot be determined, then a simple
+ /// NULL character should be put in this position.
+ /// CHAR16 Name[];
+ ///
+
+ ///
+ /// For device drivers, this is the device path of the device for which this device driver
+ /// was intended. In some cases, the driver itself may be stored as part of the system
+ /// firmware, but this field should record the device's path, not the firmware path. For
+ /// applications, this is the device path of the application. If this cannot be determined,
+ /// a simple end-of-path device node should be put in this position.
+ /// EFI_DEVICE_PATH_PROTOCOL DevicePath;
+ ///
+
+ ///
+ /// Zero or more image signatures. If the image contained no signatures,
+ /// then this field is empty.
+ /// EFI_SIGNATURE_LIST Signature;
+ ///
+} EFI_IMAGE_EXECUTION_INFO;
+
+typedef struct {
+ ///
+ /// Number of EFI_IMAGE_EXECUTION_INFO structures.
+ ///
+ UINTN NumberOfImages;
+ ///
+ /// Number of image instances of EFI_IMAGE_EXECUTION_INFO structures.
+ ///
+ // EFI_IMAGE_EXECUTION_INFO InformationInfo[]
+} EFI_IMAGE_EXECUTION_INFO_TABLE;
+
+extern EFI_GUID gEfiImageSecurityDatabaseGuid;
+extern EFI_GUID gEfiCertSha256Guid;
+extern EFI_GUID gEfiCertRsa2048Guid;
+extern EFI_GUID gEfiCertRsa2048Sha256Guid;
+extern EFI_GUID gEfiCertSha1Guid;
+extern EFI_GUID gEfiCertRsa2048Sha1Guid;
+extern EFI_GUID gEfiCertX509Guid;
+extern EFI_GUID gEfiCertSha224Guid;
+extern EFI_GUID gEfiCertSha384Guid;
+extern EFI_GUID gEfiCertSha512Guid;
+extern EFI_GUID gEfiCertX509Sha256Guid;
+extern EFI_GUID gEfiCertX509Sha384Guid;
+extern EFI_GUID gEfiCertX509Sha512Guid;
+extern EFI_GUID gEfiCertPkcs7Guid;
+extern EFI_GUID gEfiCertSm3Guid;
+extern EFI_GUID gEfiCertX509Sm3Guid;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Guid/MemoryAllocationHob.h b/sys/contrib/edk2/Include/Guid/MemoryAllocationHob.h new file mode 100644 index 000000000000..6054a2c097a4 --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/MemoryAllocationHob.h @@ -0,0 +1,28 @@ +/** @file + GUIDs for HOBs used in memory allcation + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + GUIDs introduced in PI Version 1.0. + +**/ + +#ifndef __MEMORY_ALLOCATION_GUID_H__ +#define __MEMORY_ALLOCATION_GUID_H__ + +#define EFI_HOB_MEMORY_ALLOC_BSP_STORE_GUID \ + {0x564b33cd, 0xc92a, 0x4593, {0x90, 0xbf, 0x24, 0x73, 0xe4, 0x3c, 0x63, 0x22} }; + +#define EFI_HOB_MEMORY_ALLOC_STACK_GUID \ + {0x4ed4bf27, 0x4092, 0x42e9, {0x80, 0x7d, 0x52, 0x7b, 0x1d, 0x0, 0xc9, 0xbd} } + +#define EFI_HOB_MEMORY_ALLOC_MODULE_GUID \ + {0xf8e21975, 0x899, 0x4f58, {0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a} } + +extern EFI_GUID gEfiHobMemoryAllocBspStoreGuid; +extern EFI_GUID gEfiHobMemoryAllocStackGuid; +extern EFI_GUID gEfiHobMemoryAllocModuleGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Guid/MemoryAttributesTable.h b/sys/contrib/edk2/Include/Guid/MemoryAttributesTable.h new file mode 100644 index 000000000000..e741935856da --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/MemoryAttributesTable.h @@ -0,0 +1,32 @@ +/** @file + GUIDs used for UEFI Memory Attributes Table in the UEFI 2.6 specification. + + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __UEFI_MEMORY_ATTRIBUTES_TABLE_H__ +#define __UEFI_MEMORY_ATTRIBUTES_TABLE_H__ + +#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID {\ + 0xdcfa911d, 0x26eb, 0x469f, {0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20} \ +} + +typedef struct { + UINT32 Version; + UINT32 NumberOfEntries; + UINT32 DescriptorSize; + UINT32 Flags; + // EFI_MEMORY_DESCRIPTOR Entry[1]; +} EFI_MEMORY_ATTRIBUTES_TABLE; + +#define EFI_MEMORY_ATTRIBUTES_TABLE_VERSION 0x00000002 + +#define EFI_MEMORY_ATTRIBUTES_FLAGS_RT_FORWARD_CONTROL_FLOW_GUARD 0x1 +// BIT0 implies that Runtime code includes the forward control flow guard +// instruction, such as X86 CET-IBT or ARM BTI. + +extern EFI_GUID gEfiMemoryAttributesTableGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Guid/MemoryOverwriteControl.h b/sys/contrib/edk2/Include/Guid/MemoryOverwriteControl.h new file mode 100644 index 000000000000..8ee9bbe51563 --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/MemoryOverwriteControl.h @@ -0,0 +1,70 @@ +/** @file + GUID used for MemoryOverwriteRequestControl UEFI variable defined in + TCG Platform Reset Attack Mitigation Specification 1.00. + See http://trustedcomputinggroup.org for the latest specification + + The purpose of the MemoryOverwriteRequestControl UEFI variable is to give users (e.g., OS, loader) the ability to + indicate to the platform that secrets are present in memory and that the platform firmware must clear memory upon + a restart. The OS loader should not create the variable. Rather, the firmware is required to create it. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _MEMORY_OVERWRITE_CONTROL_DATA_GUID_H_ +#define _MEMORY_OVERWRITE_CONTROL_DATA_GUID_H_ + +#define MEMORY_ONLY_RESET_CONTROL_GUID \ + { \ + 0xe20939be, 0x32d4, 0x41be, {0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29} \ + } + +/// +/// Variable name is "MemoryOverwriteRequestControl" and it is a 1 byte unsigned value. +/// The attributes should be: +/// EFI_VARIABLE_NON_VOLATILE | +/// EFI_VARIABLE_BOOTSERVICE_ACCESS | +/// EFI_VARIABLE_RUNTIME_ACCESS +/// +#define MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME L"MemoryOverwriteRequestControl" + +/// +/// 0 = Firmware MUST clear the MOR bit +/// 1 = Firmware MUST set the MOR bit +/// +#define MOR_CLEAR_MEMORY_BIT_MASK 0x01 + +/// +/// 0 = Firmware MAY autodetect a clean shutdown of the Static RTM OS. +/// 1 = Firmware MUST NOT autodetect a clean shutdown of the Static RTM OS. +/// +#define MOR_DISABLEAUTODETECT_BIT_MASK 0x10 + +/// +/// MOR field bit offset +/// +#define MOR_CLEAR_MEMORY_BIT_OFFSET 0 +#define MOR_DISABLEAUTODETECT_BIT_OFFSET 4 + +/** + Return the ClearMemory bit value 0 or 1. + + @param mor 1 byte value that contains ClearMemory and DisableAutoDetect bit. + + @return ClearMemory bit value +**/ +#define MOR_CLEAR_MEMORY_VALUE(mor) (((UINT8)(mor) & MOR_CLEAR_MEMORY_BIT_MASK) >> MOR_CLEAR_MEMORY_BIT_OFFSET) + +/** + Return the DisableAutoDetect bit value 0 or 1. + + @param mor 1 byte value that contains ClearMemory and DisableAutoDetect bit. + + @return DisableAutoDetect bit value +**/ +#define MOR_DISABLE_AUTO_DETECT_VALUE(mor) (((UINT8)(mor) & MOR_DISABLEAUTODETECT_BIT_MASK) >> MOR_DISABLEAUTODETECT_BIT_OFFSET) + +extern EFI_GUID gEfiMemoryOverwriteControlDataGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Guid/Mps.h b/sys/contrib/edk2/Include/Guid/Mps.h new file mode 100644 index 000000000000..5911f4efa9fa --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/Mps.h @@ -0,0 +1,29 @@ +/** @file + GUIDs used for MPS entries in the UEFI 2.0 system table + ACPI is the primary means of exporting MPS information to the OS. MPS only was + included to support Itanium-based platform power on. So don't use it if you don't have too. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + GUIDs defined in UEFI 2.0 spec. + +**/ + +#ifndef __MPS_GUID_H__ +#define __MPS_GUID_H__ + +#define EFI_MPS_TABLE_GUID \ + { \ + 0xeb9d2d2f, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +// +// GUID name defined in spec. +// +#define MPS_TABLE_GUID EFI_MPS_TABLE_GUID + +extern EFI_GUID gEfiMpsTableGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Guid/Rng.h b/sys/contrib/edk2/Include/Guid/Rng.h new file mode 100644 index 000000000000..acf0895b2b0d --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/Rng.h @@ -0,0 +1,155 @@ +/** @file + Random Number Generator (RNG) GUIDs and structures shared across RNG interfaces. + + Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef RNG_GUID_H_ +#define RNG_GUID_H_ + +typedef struct _EFI_RNG_INTERFACE EFI_RNG_INTERFACE; + +/// +/// 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 } \ + } + +/// +/// The Arm Architecture states the RNDR that the DRBG algorithm should be compliant +/// with NIST SP800-90A, while not mandating a particular algorithm, so as to be +/// inclusive of different geographies. +/// +#define EFI_RNG_ALGORITHM_ARM_RNDR \ + { \ + 0x43d2fde3, 0x9d4e, 0x4d79, {0x02, 0x96, 0xa8, 0x9b, 0xca, 0x78, 0x08, 0x41} \ + } + +/** + Returns information about the random number generation implementation. + + @param[in] This A pointer to this interface 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_INTERFACE *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 this interface 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_INTERFACE *This, + IN EFI_RNG_ALGORITHM *RNGAlgorithm OPTIONAL, + IN UINTN RNGValueLength, + OUT UINT8 *RNGValue + ); + +/// +/// The Random Number Generator (RNG) interface provides random bits for use in +/// applications, or entropy for seeding other random number generators. +/// +/// This interface is shared between the RNG Protocol defined in the UEFI 2.4 Specification +/// and the RNG PPI defined in the PI 1.9 Specification. +/// +struct _EFI_RNG_INTERFACE { + EFI_RNG_GET_INFO GetInfo; + EFI_RNG_GET_RNG GetRNG; +}; + +extern EFI_GUID gEfiRngAlgorithmSp80090Hash256Guid; +extern EFI_GUID gEfiRngAlgorithmSp80090Hmac256Guid; +extern EFI_GUID gEfiRngAlgorithmSp80090Ctr256Guid; +extern EFI_GUID gEfiRngAlgorithmX9313DesGuid; +extern EFI_GUID gEfiRngAlgorithmX931AesGuid; +extern EFI_GUID gEfiRngAlgorithmRaw; +extern EFI_GUID gEfiRngAlgorithmArmRndr; + +#endif // #ifndef RNG_GUID_H_ diff --git a/sys/contrib/edk2/Include/Guid/SmBios.h b/sys/contrib/edk2/Include/Guid/SmBios.h new file mode 100644 index 000000000000..c01617a1a4cb --- /dev/null +++ b/sys/contrib/edk2/Include/Guid/SmBios.h @@ -0,0 +1,32 @@ +/** @file + GUIDs used to locate the SMBIOS tables in the UEFI 2.5 system table. + + These GUIDs in the system table are the only legal ways to search for and + locate the SMBIOS tables. Do not search the 0xF0000 segment to find SMBIOS + tables. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + GUIDs defined in UEFI 2.5 spec. + +**/ + +#ifndef __SMBIOS_GUID_H__ +#define __SMBIOS_GUID_H__ + +#define SMBIOS_TABLE_GUID \ + { \ + 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define SMBIOS3_TABLE_GUID \ + { \ + 0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 } \ + } + +extern EFI_GUID gEfiSmbiosTableGuid; +extern EFI_GUID gEfiSmbios3TableGuid; + +#endif diff --git a/sys/contrib/edk2/Include/IndustryStandard/Atapi.h b/sys/contrib/edk2/Include/IndustryStandard/Atapi.h new file mode 100644 index 000000000000..7f11302bfa6e --- /dev/null +++ b/sys/contrib/edk2/Include/IndustryStandard/Atapi.h @@ -0,0 +1,849 @@ +/** @file + This file contains just some basic definitions that are needed by drivers + that dealing with ATA/ATAPI interface. + +Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _ATAPI_H_ +#define _ATAPI_H_ + +#pragma pack(1) + +/// +/// ATA5_IDENTIFY_DATA is defined in ATA-5. +/// (This structure is provided mainly for backward-compatibility support. +/// Old drivers may reference fields that are marked "obsolete" in +/// ATA_IDENTIFY_DATA, which currently conforms to ATA-8.) +/// +typedef struct { + UINT16 config; ///< General Configuration. + UINT16 cylinders; ///< Number of Cylinders. + UINT16 reserved_2; + UINT16 heads; ///< Number of logical heads. + UINT16 vendor_data1; + UINT16 vendor_data2; + UINT16 sectors_per_track; + UINT16 vendor_specific_7_9[3]; + CHAR8 SerialNo[20]; ///< ASCII + UINT16 vendor_specific_20_21[2]; + UINT16 ecc_bytes_available; + CHAR8 FirmwareVer[8]; ///< ASCII + CHAR8 ModelName[40]; ///< ASCII + UINT16 multi_sector_cmd_max_sct_cnt; + UINT16 reserved_48; + UINT16 capabilities; + UINT16 reserved_50; + UINT16 pio_cycle_timing; + UINT16 reserved_52; + UINT16 field_validity; + UINT16 current_cylinders; + UINT16 current_heads; + UINT16 current_sectors; + UINT16 CurrentCapacityLsb; + UINT16 CurrentCapacityMsb; + UINT16 reserved_59; + UINT16 user_addressable_sectors_lo; + UINT16 user_addressable_sectors_hi; + UINT16 reserved_62; + UINT16 multi_word_dma_mode; + UINT16 advanced_pio_modes; + UINT16 min_multi_word_dma_cycle_time; + UINT16 rec_multi_word_dma_cycle_time; + UINT16 min_pio_cycle_time_without_flow_control; + UINT16 min_pio_cycle_time_with_flow_control; + UINT16 reserved_69_79[11]; + UINT16 major_version_no; + UINT16 minor_version_no; + UINT16 command_set_supported_82; ///< word 82 + UINT16 command_set_supported_83; ///< word 83 + UINT16 command_set_feature_extn; ///< word 84 + UINT16 command_set_feature_enb_85; ///< word 85 + UINT16 command_set_feature_enb_86; ///< word 86 + UINT16 command_set_feature_default; ///< word 87 + UINT16 ultra_dma_mode; ///< word 88 + UINT16 reserved_89_127[39]; + UINT16 security_status; + UINT16 vendor_data_129_159[31]; + UINT16 reserved_160_255[96]; +} ATA5_IDENTIFY_DATA; + +/// +/// ATA_IDENTIFY_DATA strictly complies with ATA/ATAPI-8 Spec +/// to define the data returned by an ATA device upon successful +/// completion of the ATA IDENTIFY_DEVICE command. +/// +typedef struct { + UINT16 config; ///< General Configuration. + UINT16 obsolete_1; + UINT16 specific_config; ///< Specific Configuration. + UINT16 obsolete_3; + UINT16 retired_4_5[2]; + UINT16 obsolete_6; + UINT16 cfa_reserved_7_8[2]; + UINT16 retired_9; + CHAR8 SerialNo[20]; ///< word 10~19 + UINT16 retired_20_21[2]; + UINT16 obsolete_22; + CHAR8 FirmwareVer[8]; ///< word 23~26 + CHAR8 ModelName[40]; ///< word 27~46 + UINT16 multi_sector_cmd_max_sct_cnt; + UINT16 trusted_computing_support; + UINT16 capabilities_49; + UINT16 capabilities_50; + UINT16 obsolete_51_52[2]; + UINT16 field_validity; + UINT16 obsolete_54_58[5]; + UINT16 multi_sector_setting; + UINT16 user_addressable_sectors_lo; + UINT16 user_addressable_sectors_hi; + UINT16 obsolete_62; + UINT16 multi_word_dma_mode; + UINT16 advanced_pio_modes; + UINT16 min_multi_word_dma_cycle_time; + UINT16 rec_multi_word_dma_cycle_time; + UINT16 min_pio_cycle_time_without_flow_control; + UINT16 min_pio_cycle_time_with_flow_control; + UINT16 additional_supported; ///< word 69 + UINT16 reserved_70; + UINT16 reserved_71_74[4]; ///< Reserved for IDENTIFY PACKET DEVICE cmd. + UINT16 queue_depth; + UINT16 serial_ata_capabilities; + UINT16 reserved_77; ///< Reserved for Serial ATA + UINT16 serial_ata_features_supported; + UINT16 serial_ata_features_enabled; + UINT16 major_version_no; + UINT16 minor_version_no; + UINT16 command_set_supported_82; ///< word 82 + UINT16 command_set_supported_83; ///< word 83 + UINT16 command_set_feature_extn; ///< word 84 + UINT16 command_set_feature_enb_85; ///< word 85 + UINT16 command_set_feature_enb_86; ///< word 86 + UINT16 command_set_feature_default; ///< word 87 + UINT16 ultra_dma_mode; ///< word 88 + UINT16 time_for_security_erase_unit; + UINT16 time_for_enhanced_security_erase_unit; + UINT16 advanced_power_management_level; + UINT16 master_password_identifier; + UINT16 hardware_configuration_test_result; + UINT16 obsolete_94; + UINT16 stream_minimum_request_size; + UINT16 streaming_transfer_time_for_dma; + UINT16 streaming_access_latency_for_dma_and_pio; + UINT16 streaming_performance_granularity[2]; ///< word 98~99 + UINT16 maximum_lba_for_48bit_addressing[4]; ///< word 100~103 + UINT16 streaming_transfer_time_for_pio; + UINT16 max_no_of_512byte_blocks_per_data_set_cmd; + UINT16 phy_logic_sector_support; ///< word 106 + UINT16 interseek_delay_for_iso7779; + UINT16 world_wide_name[4]; ///< word 108~111 + UINT16 reserved_for_128bit_wwn_112_115[4]; + UINT16 reserved_for_technical_report; + UINT16 logic_sector_size_lo; ///< word 117 + UINT16 logic_sector_size_hi; ///< word 118 + UINT16 features_and_command_sets_supported_ext; ///< word 119 + UINT16 features_and_command_sets_enabled_ext; ///< word 120 + UINT16 reserved_121_126[6]; + UINT16 obsolete_127; + UINT16 security_status; ///< word 128 + UINT16 vendor_specific_129_159[31]; + UINT16 cfa_power_mode; ///< word 160 + UINT16 reserved_for_compactflash_161_167[7]; + UINT16 device_nominal_form_factor; + UINT16 is_data_set_cmd_supported; + CHAR8 additional_product_identifier[8]; + UINT16 reserved_174_175[2]; + CHAR8 media_serial_number[60]; ///< word 176~205 + UINT16 sct_command_transport; ///< word 206 + UINT16 reserved_207_208[2]; + UINT16 alignment_logic_in_phy_blocks; ///< word 209 + UINT16 write_read_verify_sector_count_mode3[2]; ///< word 210~211 + UINT16 verify_sector_count_mode2[2]; + UINT16 nv_cache_capabilities; + UINT16 nv_cache_size_in_logical_block_lsw; ///< word 215 + UINT16 nv_cache_size_in_logical_block_msw; ///< word 216 + UINT16 nominal_media_rotation_rate; + UINT16 reserved_218; + UINT16 nv_cache_options; ///< word 219 + UINT16 write_read_verify_mode; ///< word 220 + UINT16 reserved_221; + UINT16 transport_major_revision_number; + UINT16 transport_minor_revision_number; + UINT16 reserved_224_229[6]; + UINT64 extended_no_of_addressable_sectors; + UINT16 min_number_per_download_microcode_mode3; ///< word 234 + UINT16 max_number_per_download_microcode_mode3; ///< word 235 + UINT16 reserved_236_254[19]; + UINT16 integrity_word; +} ATA_IDENTIFY_DATA; + +/// +/// ATAPI_IDENTIFY_DATA strictly complies with ATA/ATAPI-8 Spec +/// to define the data returned by an ATAPI device upon successful +/// completion of the ATA IDENTIFY_PACKET_DEVICE command. +/// +typedef struct { + UINT16 config; ///< General Configuration. + UINT16 reserved_1; + UINT16 specific_config; ///< Specific Configuration. + UINT16 reserved_3_9[7]; + CHAR8 SerialNo[20]; ///< word 10~19 + UINT16 reserved_20_22[3]; + CHAR8 FirmwareVer[8]; ///< word 23~26 + CHAR8 ModelName[40]; ///< word 27~46 + UINT16 reserved_47_48[2]; + UINT16 capabilities_49; + UINT16 capabilities_50; + UINT16 obsolete_51; + UINT16 reserved_52; + UINT16 field_validity; ///< word 53 + UINT16 reserved_54_61[8]; + UINT16 dma_dir; + UINT16 multi_word_dma_mode; ///< word 63 + UINT16 advanced_pio_modes; ///< word 64 + UINT16 min_multi_word_dma_cycle_time; + UINT16 rec_multi_word_dma_cycle_time; + UINT16 min_pio_cycle_time_without_flow_control; + UINT16 min_pio_cycle_time_with_flow_control; + UINT16 reserved_69_70[2]; + UINT16 obsolete_71_72[2]; + UINT16 reserved_73_74[2]; + UINT16 obsolete_75; + UINT16 serial_ata_capabilities; + UINT16 reserved_77; ///< Reserved for Serial ATA + UINT16 serial_ata_features_supported; + UINT16 serial_ata_features_enabled; + UINT16 major_version_no; ///< word 80 + UINT16 minor_version_no; ///< word 81 + UINT16 cmd_set_support_82; + UINT16 cmd_set_support_83; + UINT16 cmd_feature_support; + UINT16 cmd_feature_enable_85; + UINT16 cmd_feature_enable_86; + UINT16 cmd_feature_default; + UINT16 ultra_dma_select; + UINT16 time_required_for_sec_erase; ///< word 89 + UINT16 time_required_for_enhanced_sec_erase; ///< word 90 + UINT16 advanced_power_management_level; + UINT16 master_pwd_revison_code; + UINT16 hardware_reset_result; ///< word 93 + UINT16 obsolete_94; + UINT16 reserved_95_107[13]; + UINT16 world_wide_name[4]; ///< word 108~111 + UINT16 reserved_for_128bit_wwn_112_115[4]; + UINT16 reserved_116_118[3]; + UINT16 command_and_feature_sets_supported; ///< word 119 + UINT16 command_and_feature_sets_supported_enabled; + UINT16 reserved_121_124[4]; + UINT16 atapi_byte_count_0_behavior; ///< word 125 + UINT16 obsolete_126_127[2]; + UINT16 security_status; + UINT16 reserved_129_159[31]; + UINT16 cfa_reserved_160_175[16]; + UINT16 reserved_176_221[46]; + UINT16 transport_major_version; + UINT16 transport_minor_version; + UINT16 reserved_224_254[31]; + UINT16 integrity_word; +} ATAPI_IDENTIFY_DATA; + +/// +/// Standard Quiry Data format, defined in SFF-8070i(ATAPI Removable Rewritable Specification). +/// +typedef struct { + UINT8 peripheral_type; + UINT8 RMB; + UINT8 version; + UINT8 response_data_format; + UINT8 addnl_length; ///< n - 4, Numbers of bytes following this one. + UINT8 reserved_5; + UINT8 reserved_6; + UINT8 reserved_7; + UINT8 vendor_info[8]; + UINT8 product_id[16]; + UINT8 product_revision_level[4]; + UINT8 vendor_specific_36_55[55 - 36 + 1]; + UINT8 reserved_56_95[95 - 56 + 1]; + /// + /// Vendor-specific parameters fields. The sizeof (ATAPI_INQUIRY_DATA) is 254 + /// since allocation_length is one byte in ATAPI_INQUIRY_CMD. + /// + UINT8 vendor_specific_96_253[253 - 96 + 1]; +} ATAPI_INQUIRY_DATA; + +/// +/// Request Sense Standard Data, defined in SFF-8070i(ATAPI Removable Rewritable Specification). +/// +typedef struct { + UINT8 error_code : 7; + UINT8 valid : 1; + UINT8 reserved_1; + UINT8 sense_key : 4; + UINT8 reserved_2 : 1; + UINT8 Vendor_specifc_1 : 3; + UINT8 vendor_specific_3; + UINT8 vendor_specific_4; + UINT8 vendor_specific_5; + UINT8 vendor_specific_6; + UINT8 addnl_sense_length; ///< n - 7 + UINT8 vendor_specific_8; + UINT8 vendor_specific_9; + UINT8 vendor_specific_10; + UINT8 vendor_specific_11; + UINT8 addnl_sense_code; ///< mandatory + UINT8 addnl_sense_code_qualifier; ///< mandatory + UINT8 field_replaceable_unit_code; ///< optional + UINT8 sense_key_specific_15 : 7; + UINT8 SKSV : 1; + UINT8 sense_key_specific_16; + UINT8 sense_key_specific_17; +} ATAPI_REQUEST_SENSE_DATA; + +/// +/// READ CAPACITY Data, defined in SFF-8070i(ATAPI Removable Rewritable Specification). +/// +typedef struct { + UINT8 LastLba3; + UINT8 LastLba2; + UINT8 LastLba1; + UINT8 LastLba0; + UINT8 BlockSize3; + UINT8 BlockSize2; + UINT8 BlockSize1; + UINT8 BlockSize0; +} ATAPI_READ_CAPACITY_DATA; + +/// +/// Capacity List Header + Current/Maximum Capacity Descriptor, +/// defined in SFF-8070i(ATAPI Removable Rewritable Specification). +/// +typedef struct { + UINT8 reserved_0; + UINT8 reserved_1; + UINT8 reserved_2; + UINT8 Capacity_Length; + UINT8 LastLba3; + UINT8 LastLba2; + UINT8 LastLba1; + UINT8 LastLba0; + UINT8 DesCode : 2; + UINT8 reserved_9 : 6; + UINT8 BlockSize2; + UINT8 BlockSize1; + UINT8 BlockSize0; +} ATAPI_READ_FORMAT_CAPACITY_DATA; + +/// +/// Test Unit Ready Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). +/// +typedef struct { + UINT8 opcode; + UINT8 reserved_1; + UINT8 reserved_2; + UINT8 reserved_3; + UINT8 reserved_4; + UINT8 reserved_5; + UINT8 reserved_6; + UINT8 reserved_7; + UINT8 reserved_8; + UINT8 reserved_9; + UINT8 reserved_10; + UINT8 reserved_11; +} ATAPI_TEST_UNIT_READY_CMD; + +/// +/// INQUIRY Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). +/// +typedef struct { + UINT8 opcode; + UINT8 reserved_1 : 5; + UINT8 lun : 3; + UINT8 page_code; ///< defined in SFF8090i, V6 + UINT8 reserved_3; + UINT8 allocation_length; + UINT8 reserved_5; + UINT8 reserved_6; + UINT8 reserved_7; + UINT8 reserved_8; + UINT8 reserved_9; + UINT8 reserved_10; + UINT8 reserved_11; +} ATAPI_INQUIRY_CMD; + +/// +/// REQUEST SENSE Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). +/// +typedef struct { + UINT8 opcode; + UINT8 reserved_1 : 5; + UINT8 lun : 3; + UINT8 reserved_2; + UINT8 reserved_3; + UINT8 allocation_length; + UINT8 reserved_5; + UINT8 reserved_6; + UINT8 reserved_7; + UINT8 reserved_8; + UINT8 reserved_9; + UINT8 reserved_10; + UINT8 reserved_11; +} ATAPI_REQUEST_SENSE_CMD; + +/// +/// READ (10) Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). +/// +typedef struct { + UINT8 opcode; + UINT8 reserved_1 : 5; + UINT8 lun : 3; + UINT8 Lba0; + UINT8 Lba1; + UINT8 Lba2; + UINT8 Lba3; + UINT8 reserved_6; + UINT8 TranLen0; + UINT8 TranLen1; + UINT8 reserved_9; + UINT8 reserved_10; + UINT8 reserved_11; +} ATAPI_READ10_CMD; + +/// +/// READ Format Capacity Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). +/// +typedef struct { + UINT8 opcode; + UINT8 reserved_1 : 5; + UINT8 lun : 3; + UINT8 reserved_2; + UINT8 reserved_3; + UINT8 reserved_4; + UINT8 reserved_5; + UINT8 reserved_6; + UINT8 allocation_length_hi; + UINT8 allocation_length_lo; + UINT8 reserved_9; + UINT8 reserved_10; + UINT8 reserved_11; +} ATAPI_READ_FORMAT_CAP_CMD; + +/// +/// MODE SENSE Command, defined in SFF-8070i(ATAPI Removable Rewritable Specification). +/// +typedef struct { + UINT8 opcode; + UINT8 reserved_1 : 5; + UINT8 lun : 3; + UINT8 page_code : 6; + UINT8 page_control : 2; + UINT8 reserved_3; + UINT8 reserved_4; + UINT8 reserved_5; + UINT8 reserved_6; + UINT8 parameter_list_length_hi; + UINT8 parameter_list_length_lo; + UINT8 reserved_9; + UINT8 reserved_10; + UINT8 reserved_11; +} ATAPI_MODE_SENSE_CMD; + +/// +/// ATAPI_PACKET_COMMAND is not defined in the ATA specification. +/// We add it here for the convenience of ATA/ATAPI module writers. +/// +typedef union { + UINT16 Data16[6]; + ATAPI_TEST_UNIT_READY_CMD TestUnitReady; + ATAPI_READ10_CMD Read10; + ATAPI_REQUEST_SENSE_CMD RequestSence; + ATAPI_INQUIRY_CMD Inquiry; + ATAPI_MODE_SENSE_CMD ModeSense; + ATAPI_READ_FORMAT_CAP_CMD ReadFormatCapacity; +} ATAPI_PACKET_COMMAND; + +#pragma pack() + +#define ATAPI_MAX_DMA_EXT_CMD_SECTORS 0x10000 +#define ATAPI_MAX_DMA_CMD_SECTORS 0x100 + +// ATA/ATAPI Signature equates +#define ATA_SIGNATURE 0x0101 ///< defined in ACS-3 +#define ATAPI_SIGNATURE 0xeb14 ///< defined in ACS-3 +#define ATAPI_SIGNATURE_32 0xeb140101 ///< defined in ACS-3 + +// Spin Up Configuration definitions +#define ATA_SPINUP_CFG_REQUIRED_IDD_INCOMPLETE 0x37c8 ///< defined in ACS-3 +#define ATA_SPINUP_CFG_REQUIRED_IDD_COMPLETE 0x738c ///< defined in ACS-3 +#define ATA_SPINUP_CFG_NOT_REQUIRED_IDD_INCOMPLETE 0x8c73 ///< defined in ACS-3 +#define ATA_SPINUP_CFG_NOT_REQUIRED_IDD_COMPLETE 0xc837 ///< defined in ACS-3 + +// +// ATA Packet Command Code +// +#define ATA_CMD_FORMAT_UNIT 0x04 ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_SOFT_RESET 0x08 ///< defined from ATA-3 +#define ATA_CMD_PACKET 0xA0 ///< defined from ATA-3 +#define ATA_CMD_IDENTIFY_DEVICE 0xA1 ///< defined from ATA-3 +#define ATA_CMD_SERVICE 0xA2 ///< defined from ATA-3 +#define ATA_CMD_TEST_UNIT_READY 0x00 ///< defined from ATA-1 +#define ATA_CMD_REQUEST_SENSE 0x03 ///< defined from ATA-4 +#define ATA_CMD_INQUIRY 0x12 ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_READ_FORMAT_CAPACITY 0x23 ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_READ_CAPACITY 0x25 ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_READ_10 0x28 ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_WRITE_10 0x2A ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_ATAPI_SEEK 0x2B ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_WRITE_AND_VERIFY 0x2E ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_VERIFY 0x2F ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_READ_12 0xA8 ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_WRITE_12 0xAA ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_START_STOP_UNIT 0x1B ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_PREVENT_ALLOW_MEDIA_REMOVAL 0x1E ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_CMD_MODE_SELECT 0x55 ///< defined in ATAPI Removable Rewritable Media Devices + +#define ATA_CMD_MODE_SENSE 0x5A ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_PAGE_CODE_READ_WRITE_ERROR 0x01 ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_PAGE_CODE_CACHING_PAGE 0x08 ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_PAGE_CODE_REMOVABLE_BLOCK_CAPABILITIES 0x1B ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_PAGE_CODE_TIMER_PROTECT_PAGE 0x1C ///< defined in ATAPI Removable Rewritable Media Devices +#define ATA_PAGE_CODE_RETURN_ALL_PAGES 0x3F ///< defined in ATAPI Removable Rewritable Media Devices + +#define ATA_CMD_GET_CONFIGURATION 0x46 ///< defined in ATAPI Multimedia Devices +#define ATA_GCCD_RT_FIELD_VALUE_ALL 0x00 ///< defined in ATAPI Multimedia Devices +#define ATA_GCCD_RT_FIELD_VALUE_CURRENT 0x01 ///< defined in ATAPI Multimedia Devices +#define ATA_GCCD_RT_FIELD_VALUE_SINGLE 0x02 ///< defined in ATAPI Multimedia Devices +#define ATA_GCCD_RT_FIELD_VALUE_RESERVED 0x03 ///< defined in ATAPI Multimedia Devices + +#define ATA_FEATURE_LIST_PROFILE_LIST 0x0000 ///< defined in ATAPI Multimedia Devices +#define ATA_FEATURE_LIST_CORE 0x0001 ///< defined in ATAPI Multimedia Devices +#define ATA_FEATURE_LIST_MORPHING 0x0002 ///< defined in ATAPI Multimedia Devices +#define ATA_FEATURE_LIST_REMOVEABLE_MEDIUM 0x0003 ///< defined in ATAPI Multimedia Devices +#define ATA_FEATURE_LIST_WRITE_PROTECT 0x0004 ///< defined in ATAPI Multimedia Devices + +/// +/// Start/Stop and Eject Operations +/// +///@{ +#define ATA_CMD_SUBOP_STOP_DISC 0x00 ///< Stop the Disc +#define ATA_CMD_SUBOP_START_DISC 0x01 ///< Start the Disc and acquire the format type +#define ATA_CMD_SUBOP_EJECT_DISC 0x02 ///< Eject the Disc if possible +#define ATA_CMD_SUBOP_CLOSE_TRAY 0x03 ///< Load the Disc (Close Tray) +///@} + +// +// ATA Commands Code +// + +// +// Class 1: PIO Data-In Commands +// +#define ATA_CMD_IDENTIFY_DRIVE 0xec ///< defined from ATA-3 +#define ATA_CMD_READ_BUFFER 0xe4 ///< defined from ATA-1 +#define ATA_CMD_READ_SECTORS 0x20 ///< defined from ATA-1 +#define ATA_CMD_READ_SECTORS_WITH_RETRY 0x21 ///< defined from ATA-1, obsoleted from ATA-5 +#define ATA_CMD_READ_LONG 0x22 ///< defined from ATA-1, obsoleted from ATA-5 +#define ATA_CMD_READ_LONG_WITH_RETRY 0x23 ///< defined from ATA-1, obsoleted from ATA-5 +#define ATA_CMD_READ_SECTORS_EXT 0x24 ///< defined from ATA-6 +#define ATA_CMD_READ_MULTIPLE 0xc4 ///< defined in ACS-3 +#define ATA_CMD_READ_MULTIPLE_EXT 0x29 ///< defined in ACS-3 +#define ATA_CMD_READ_LOG_EXT 0x2f ///< defined in ACS-3 + +// +// Class 2: PIO Data-Out Commands +// +#define ATA_CMD_FORMAT_TRACK 0x50 ///< defined from ATA-1, obsoleted from ATA-4 +#define ATA_CMD_WRITE_BUFFER 0xe8 ///< defined from ATA-1 +#define ATA_CMD_WRITE_SECTORS 0x30 ///< defined from ATA-1 +#define ATA_CMD_WRITE_SECTORS_WITH_RETRY 0x31 ///< defined from ATA-1, obsoleted from ATA-5 +#define ATA_CMD_WRITE_LONG 0x32 ///< defined from ATA-1, obsoleted from ATA-5 +#define ATA_CMD_WRITE_LONG_WITH_RETRY 0x33 ///< defined from ATA-1, obsoleted from ATA-5 +#define ATA_CMD_WRITE_VERIFY 0x3c ///< defined from ATA-1, obsoleted from ATA-5 +#define ATA_CMD_WRITE_SECTORS_EXT 0x34 ///< defined from ATA-6 +#define ATA_CMD_WRITE_MULTIPLE 0xc5 ///< defined in ACS-3 +#define ATA_CMD_WRITE_MULTIPLE_EXT 0x39 ///< defined in ACS-3 + +// +// Class 3 No Data Command +// +#define ATA_CMD_ACK_MEDIA_CHANGE 0xdb ///< defined from ATA-1, obsoleted from ATA-5 +#define ATA_CMD_BOOT_POST_BOOT 0xdc ///< defined from ATA-1, obsoleted from ATA-3 +#define ATA_CMD_BOOT_PRE_BOOT 0xdd ///< defined from ATA-1, obsoleted from ATA-3 +#define ATA_CMD_CHECK_POWER_MODE 0x98 ///< defined from ATA-1, obsoleted from ATA-4 +#define ATA_CMD_CHECK_POWER_MODE_ALIAS 0xe5 ///< defined from ATA-1 +#define ATA_CMD_DOOR_LOCK 0xde ///< defined from ATA-1 +#define ATA_CMD_DOOR_UNLOCK 0xdf ///< defined from ATA-1 +#define ATA_CMD_EXEC_DRIVE_DIAG 0x90 ///< defined from ATA-1 +#define ATA_CMD_IDLE_ALIAS 0x97 ///< defined from ATA-1, obsoleted from ATA-4 +#define ATA_CMD_IDLE 0xe3 ///< defined from ATA-1 +#define ATA_CMD_IDLE_IMMEDIATE 0x95 ///< defined from ATA-1, obsoleted from ATA-4 +#define ATA_CMD_IDLE_IMMEDIATE_ALIAS 0xe1 ///< defined from ATA-1 +#define ATA_CMD_INIT_DRIVE_PARAM 0x91 ///< defined from ATA-1, obsoleted from ATA-6 +#define ATA_CMD_RECALIBRATE 0x10 ///< defined from ATA-1, obsoleted from ATA-4 +#define ATA_CMD_READ_DRIVE_STATE 0xe9 ///< defined from ATA-1, obsoleted from ATA-3 +#define ATA_CMD_SET_MULTIPLE_MODE 0xC6 ///< defined from ATA-2 +#define ATA_CMD_READ_VERIFY 0x40 ///< defined from ATA-1 +#define ATA_CMD_READ_VERIFY_WITH_RETRY 0x41 ///< defined from ATA-1, obsoleted from ATA-5 +#define ATA_CMD_SEEK 0x70 ///< defined from ATA-1 +#define ATA_CMD_SET_FEATURES 0xef ///< defined from ATA-1 +#define ATA_CMD_STANDBY 0x96 ///< defined from ATA-1, obsoleted from ATA-4 +#define ATA_CMD_STANDBY_ALIAS 0xe2 ///< defined from ATA-1 +#define ATA_CMD_STANDBY_IMMEDIATE 0x94 ///< defined from ATA-1, obsoleted from ATA-4 +#define ATA_CMD_STANDBY_IMMEDIATE_ALIAS 0xe0 ///< defined from ATA-1 +#define ATA_CMD_SLEEP 0xe6 ///< defined in ACS-3 +#define ATA_CMD_READ_NATIVE_MAX_ADDRESS 0xf8 ///< defined in ATA-6 +#define ATA_CMD_READ_NATIVE_MAX_ADDRESS_EXT 0x27 ///< defined in ATA-6 + +// +// Set Features Sub Command +// +#define ATA_SUB_CMD_ENABLE_VOLATILE_WRITE_CACHE 0x02 ///< defined in ACS-3 +#define ATA_SUB_CMD_SET_TRANSFER_MODE 0x03 ///< defined in ACS-3 +#define ATA_SUB_CMD_ENABLE_APM 0x05 ///< defined in ACS-3 +#define ATA_SUB_CMD_ENABLE_PUIS 0x06 ///< defined in ACS-3 +#define ATA_SUB_CMD_PUIS_SET_DEVICE_SPINUP 0x07 ///< defined in ACS-3 +#define ATA_SUB_CMD_ENABLE_WRITE_READ_VERIFY 0x0b ///< defined in ACS-3 +#define ATA_SUB_CMD_ENABLE_SATA_FEATURE 0x10 ///< defined in ACS-3 +#define ATA_SUB_CMD_DISABLE_MEDIA_STATUS_NOTIFICATION 0x31 ///< defined in ACS-3 +#define ATA_SUB_CMD_ENABLE_FREE_FALL_CONTROL 0x41 ///< defined in ACS-3 +#define ATA_SUB_CMD_ACOUSTIC_MANAGEMENT_ENABLE 0x42 ///< defined in ACS-3 +#define ATA_SUB_CMD_SET_MAX_HOST_INTERFACE_SECTOR_TIMES 0x43 ///< defined in ACS-3 +#define ATA_SUB_CMD_EXTENDED_POWER_CONDITIONS 0x4a ///< defined in ACS-3 +#define ATA_SUB_CMD_DISABLE_READ_LOOK_AHEAD 0x55 ///< defined in ACS-3 +#define ATA_SUB_CMD_EN_DIS_DSN_FEATURE 0x63 ///< defined in ACS-3 +#define ATA_SUB_CMD_DISABLE_REVERT_TO_POWER_ON_DEFAULTS 0x66 ///< defined in ACS-3 +#define ATA_SUB_CMD_DISABLE_VOLATILE_WRITE_CACHE 0x82 ///< defined in ACS-3 +#define ATA_SUB_CMD_DISABLE_APM 0x85 ///< defined in ACS-3 +#define ATA_SUB_CMD_DISABLE_PUIS 0x86 ///< defined in ACS-3 +#define ATA_SUB_CMD_DISABLE_WRITE_READ_VERIFY 0x8b ///< defined in ACS-3 +#define ATA_SUB_CMD_DISABLE_SATA_FEATURE 0x90 ///< defined in ACS-3 +#define ATA_SUB_CMD_ENABLE_MEDIA_STATUS_NOTIFICATION 0x95 ///< defined in ACS-3 +#define ATA_SUB_CMD_ENABLE_READ_LOOK_AHEAD 0xaa ///< defined in ACS-3 +#define ATA_SUB_CMD_DISABLE_FREE_FALL_CONTROL 0xc1 ///< defined in ACS-3 +#define ATA_SUB_CMD_ACOUSTIC_MANAGEMENT_DISABLE 0xc2 ///< defined in ACS-3 +#define ATA_SUB_CMD_EN_DIS_SENSE_DATA_REPORTING 0xc3 ///< defined in ACS-3 +#define ATA_SUB_CMD_ENABLE_REVERT_TO_POWER_ON_DEFAULTS 0xcc ///< defined in ACS-3 + +// +// S.M.A.R.T +// +#define ATA_CMD_SMART 0xb0 ///< defined from ATA-3 +#define ATA_CONSTANT_C2 0xc2 ///< reserved +#define ATA_CONSTANT_4F 0x4f ///< reserved + +#define ATA_SMART_READ_DATA 0xd0 ///< defined in ACS-3 + +#define ATA_SMART_AUTOSAVE 0xd2 ///< defined in ACS-3 +#define ATA_AUTOSAVE_DISABLE_ATTR 0x00 +#define ATA_AUTOSAVE_ENABLE_ATTR 0xf1 + +#define ATA_SMART_EXECUTE_OFFLINE_IMMEDIATE 0xd4 ///< defined in ACS-3 +#define ATA_EXECUTE_SMART_OFFLINE_ROUTINE 0x00 ///< defined in ACS-3 +#define ATA_EXECUTE_SMART_OFFLINE_SHORT_SELFTEST 0x01 ///< defined in ACS-3 +#define ATA_EXECUTE_SMART_OFFLINE_EXTENDED_SELFTEST 0x02 ///< defined in ACS-3 +#define ATA_EXECUTE_SMART_OFFLINE_CONVEYANCE_SELFTEST 0x03 ///< defined in ACS-3 +#define ATA_EXECUTE_SMART_OFFLINE_SELECTIVE_SELFTEST 0x04 ///< defined in ACS-3 +#define ATA_SMART_ABORT_SELF_TEST_SUBROUTINE 0x7f ///< defined in ACS-3 +#define ATA_EXECUTE_SMART_CAPTIVE_SHORT_SELFTEST 0x81 ///< defined in ACS-3 +#define ATA_EXECUTE_SMART_CAPTIVE_EXTENDED_SELFTEST 0x82 ///< defined in ACS-3 +#define ATA_EXECUTE_SMART_CAPTIVE_CONVEYANCE_SELFTEST 0x83 ///< defined in ACS-3 +#define ATA_EXECUTE_SMART_CAPTIVE_SELECTIVE_SELFTEST 0x84 ///< defined in ACS-3 + +#define ATA_SMART_READLOG 0xd5 ///< defined in ACS-3 +#define ATA_SMART_WRITELOG 0xd6 ///< defined in ACS-3 +#define ATA_SMART_ENABLE_OPERATION 0xd8 ///< reserved +#define ATA_SMART_DISABLE_OPERATION 0xd9 ///< defined in ACS-3 +#define ATA_SMART_RETURN_STATUS 0xda ///< defined from ATA-3 + +#define ATA_SMART_THRESHOLD_NOT_EXCEEDED_VALUE 0xc24f ///< defined in ACS-3 +#define ATA_SMART_THRESHOLD_EXCEEDED_VALUE 0x2cf4 ///< defined in ACS-3 + +// SMART Log Definitions +#define ATA_SMART_LOG_DIRECTORY 0x00 ///< defined in ACS-3 +#define ATA_SMART_SUM_SMART_ERROR_LOG 0x01 ///< defined in ACS-3 +#define ATA_SMART_COMP_SMART_ERROR_LOG 0x02 ///< defined in ACS-3 +#define ATA_SMART_EXT_COMP_SMART_ERROR_LOG 0x03 ///< defined in ACS-3 +#define ATA_SMART_SMART_SELFTEST_LOG 0x06 ///< defined in ACS-3 +#define ATA_SMART_EXT_SMART_SELFTEST_LOG 0x07 ///< defined in ACS-3 +#define ATA_SMART_SELECTIVE_SELFTEST_LOG 0x09 ///< defined in ACS-3 +#define ATA_SMART_HOST_VENDOR_SPECIFIC 0x80 ///< defined in ACS-3 +#define ATA_SMART_DEVICE_VENDOR_SPECIFIC 0xa0 ///< defined in ACS-3 + +// +// Class 4: DMA Command +// +#define ATA_CMD_READ_DMA 0xc8 ///< defined from ATA-1 +#define ATA_CMD_READ_DMA_WITH_RETRY 0xc9 ///< defined from ATA-1, obsoleted from ATA-5 +#define ATA_CMD_READ_DMA_EXT 0x25 ///< defined from ATA-6 +#define ATA_CMD_WRITE_DMA 0xca ///< defined from ATA-1 +#define ATA_CMD_WRITE_DMA_WITH_RETRY 0xcb ///< defined from ATA-1, obsoleted from ATA- +#define ATA_CMD_WRITE_DMA_EXT 0x35 ///< defined from ATA-6 + +// +// ATA Security commands +// +#define ATA_CMD_SECURITY_SET_PASSWORD 0xf1 ///< defined in ACS-3 +#define ATA_CMD_SECURITY_UNLOCK 0xf2 ///< defined in ACS-3 +#define ATA_CMD_SECURITY_ERASE_PREPARE 0xf3 ///< defined in ACS-3 +#define ATA_CMD_SECURITY_ERASE_UNIT 0xf4 ///< defined in ACS-3 +#define ATA_CMD_SECURITY_FREEZE_LOCK 0xf5 ///< defined in ACS-3 +#define ATA_CMD_SECURITY_DISABLE_PASSWORD 0xf6 ///< defined in ACS-3 + +#define ATA_SECURITY_BUFFER_LENGTH 512 ///< defined in ACS-3 + +// +// ATA Device Config Overlay +// +#define ATA_CMD_DEV_CONFIG_OVERLAY 0xb1 ///< defined from ATA-6 +#define ATA_CMD_DEV_CONFIG_RESTORE_FEATURE 0xc0 ///< defined from ATA-6 +#define ATA_CMD_DEV_CONFIG_FREEZELOCK_FEATURE 0xc1 ///< defined from ATA-6 +#define ATA_CMD_DEV_CONFIG_IDENTIFY_FEATURE 0xc2 ///< defined from ATA-6 +#define ATA_CMD_DEV_CONFIG_SET_FEATURE 0xc3 ///< defined from ATA-6 + +// +// ATA Trusted Computing Feature Set Commands +// +#define ATA_CMD_TRUSTED_NON_DATA 0x5b ///< defined in ACS-3 +#define ATA_CMD_TRUSTED_RECEIVE 0x5c ///< defined in ACS-3 +#define ATA_CMD_TRUSTED_RECEIVE_DMA 0x5d ///< defined in ACS-3 +#define ATA_CMD_TRUSTED_SEND 0x5e ///< defined in ACS-3 +#define ATA_CMD_TRUSTED_SEND_DMA 0x5f ///< defined in ACS-3 + +// +// ATA Trusted Receive Fields +// +#define ATA_TR_RETURN_SECURITY_PROTOCOL_INFORMATION 0x00 ///< defined in ACS-3 +#define ATA_TR_SECURITY_PROTOCOL_JEDEC_RESERVED 0xec ///< defined in ACS-3 +#define ATA_TR_SECURITY_PROTOCOL_SDCARD_RESERVED 0xed ///< defined in ACS-3 +#define ATA_TR_SECURITY_PROTOCOL_IEEE1667_RESERVED 0xee ///< defined in ACS-3 + +// +// Equates used for Acoustic Flags +// +#define ATA_ACOUSTIC_LEVEL_BYPASS 0xff ///< defined from ATA-6 +#define ATA_ACOUSTIC_LEVEL_MAXIMUM_PERFORMANCE 0xfe ///< defined from ATA-6 +#define ATA_ACOUSTIC_LEVEL_QUIET 0x80 ///< defined from ATA-6 + +// +// Equates used for DiPM Support +// +#define ATA_CMD_DIPM_SUB 0x03 // defined in ACS-3 : Count value in SetFeature identification : 03h Device-initiated interface power state transitions +#define ATA_DIPM_ENABLE 0x10 // defined in ACS-3 +#define ATA_DIPM_DISABLE 0x90 // defined in ACS-3 + +// +// Equates used for DevSleep Support +// +#define ATA_CMD_DEVSLEEP_SUB 0x09 // defined in SATA 3.2 Gold Spec : Count value in SetFeature identification : 09h Device Sleep +#define ATA_DEVSLEEP_ENABLE 0x10 // defined in SATA 3.2 Gold Spec +#define ATA_DEVSLEEP_DISABLE 0x90 // defined in SATA 3.2 Gold Spec + +#define ATA_DEVSLP_EXIT_TIMEOUT 20 // MDAT - 20 ms +#define ATA_DEVSLP_MINIMUM_DETECTION_TIME 10 // DMDT - 10 us +#define ATA_DEVSLP_MINIMUM_ASSERTION_TIME 10 // DETO - 10 ms + +// +// Set MAX Commands +// +#define ATA_CMD_SET_MAX_ADDRESS_EXT 0x37 ///< defined from ATA-6 +#define ATA_CMD_SET_MAX_ADDRESS 0xf9 ///< defined from ATA-6 +#define ATA_SET_MAX_SET_PASSWORD 0x01 ///< defined from ATA-6 +#define ATA_SET_MAX_LOCK 0x02 ///< defined from ATA-6 +#define ATA_SET_MAX_UNLOCK 0x03 ///< defined from ATA-6 +#define ATA_SET_MAX_FREEZE_LOCK 0x04 ///< defined from ATA-6 + +/// +/// Default content of device control register, disable INT, +/// Bit3 is set to 1 according ATA-1 +/// +#define ATA_DEFAULT_CTL (0x0a) +/// +/// Default context of Device/Head Register, +/// Bit7 and Bit5 are set to 1 for back-compatibilities. +/// +#define ATA_DEFAULT_CMD (0xa0) + +#define ATAPI_MAX_BYTE_COUNT (0xfffe) + +#define ATA_REQUEST_SENSE_ERROR (0x70) ///< defined in SFF-8070i + +// +// Sense Key, Additional Sense Codes and Additional Sense Code Qualifier +// defined in MultiMedia Commands (MMC, MMC-2) +// +// Sense Key +// +#define ATA_SK_NO_SENSE (0x0) +#define ATA_SK_RECOVERY_ERROR (0x1) +#define ATA_SK_NOT_READY (0x2) +#define ATA_SK_MEDIUM_ERROR (0x3) +#define ATA_SK_HARDWARE_ERROR (0x4) +#define ATA_SK_ILLEGAL_REQUEST (0x5) +#define ATA_SK_UNIT_ATTENTION (0x6) +#define ATA_SK_DATA_PROTECT (0x7) +#define ATA_SK_BLANK_CHECK (0x8) +#define ATA_SK_VENDOR_SPECIFIC (0x9) +#define ATA_SK_RESERVED_A (0xA) +#define ATA_SK_ABORT (0xB) +#define ATA_SK_RESERVED_C (0xC) +#define ATA_SK_OVERFLOW (0xD) +#define ATA_SK_MISCOMPARE (0xE) +#define ATA_SK_RESERVED_F (0xF) + +// +// Additional Sense Codes +// +#define ATA_ASC_NOT_READY (0x04) +#define ATA_ASC_MEDIA_ERR1 (0x10) +#define ATA_ASC_MEDIA_ERR2 (0x11) +#define ATA_ASC_MEDIA_ERR3 (0x14) +#define ATA_ASC_MEDIA_ERR4 (0x30) +#define ATA_ASC_MEDIA_UPSIDE_DOWN (0x06) +#define ATA_ASC_INVALID_CMD (0x20) +#define ATA_ASC_LBA_OUT_OF_RANGE (0x21) +#define ATA_ASC_INVALID_FIELD (0x24) +#define ATA_ASC_WRITE_PROTECTED (0x27) +#define ATA_ASC_MEDIA_CHANGE (0x28) +#define ATA_ASC_RESET (0x29) ///< Power On Reset or Bus Reset occurred. +#define ATA_ASC_ILLEGAL_FIELD (0x26) +#define ATA_ASC_NO_MEDIA (0x3A) +#define ATA_ASC_ILLEGAL_MODE_FOR_THIS_TRACK (0x64) + +// +// Additional Sense Code Qualifier +// +#define ATA_ASCQ_IN_PROGRESS (0x01) + +// +// Error Register +// +#define ATA_ERRREG_BBK BIT7 ///< Bad block detected defined from ATA-1, obsoleted from ATA-2 +#define ATA_ERRREG_UNC BIT6 ///< Uncorrectable Data defined from ATA-1, obsoleted from ATA-4 +#define ATA_ERRREG_MC BIT5 ///< Media Change defined from ATA-1, obsoleted from ATA-4 +#define ATA_ERRREG_IDNF BIT4 ///< ID Not Found defined from ATA-1, obsoleted from ATA-4 +#define ATA_ERRREG_MCR BIT3 ///< Media Change Requested defined from ATA-1, obsoleted from ATA-4 +#define ATA_ERRREG_ABRT BIT2 ///< Aborted Command defined from ATA-1 +#define ATA_ERRREG_TK0NF BIT1 ///< Track 0 Not Found defined from ATA-1, obsoleted from ATA-4 +#define ATA_ERRREG_AMNF BIT0 ///< Address Mark Not Found defined from ATA-1, obsoleted from ATA-4 + +// +// Status Register +// +#define ATA_STSREG_BSY BIT7 ///< Controller Busy defined from ATA-1 +#define ATA_STSREG_DRDY BIT6 ///< Drive Ready defined from ATA-1 +#define ATA_STSREG_DWF BIT5 ///< Drive Write Fault defined from ATA-1, obsoleted from ATA-4 +#define ATA_STSREG_DF BIT5 ///< Drive Fault defined from ATA-6 +#define ATA_STSREG_DSC BIT4 ///< Disk Seek Complete defined from ATA-1, obsoleted from ATA-4 +#define ATA_STSREG_DRQ BIT3 ///< Data Request defined from ATA-1 +#define ATA_STSREG_CORR BIT2 ///< Corrected Data defined from ATA-1, obsoleted from ATA-4 +#define ATA_STSREG_IDX BIT1 ///< Index defined from ATA-1, obsoleted from ATA-4 +#define ATA_STSREG_ERR BIT0 ///< Error defined from ATA-1 + +// +// Device Control Register +// +#define ATA_CTLREG_SRST BIT2 ///< Software Reset. +#define ATA_CTLREG_IEN_L BIT1 ///< Interrupt Enable #. + +#endif diff --git a/sys/contrib/edk2/Include/IndustryStandard/PeImage.h b/sys/contrib/edk2/Include/IndustryStandard/PeImage.h new file mode 100644 index 000000000000..455928e6b8bc --- /dev/null +++ b/sys/contrib/edk2/Include/IndustryStandard/PeImage.h @@ -0,0 +1,816 @@ +/** @file + EFI image format for PE32, PE32+ and TE. Please note some data structures are + different for PE32 and PE32+. EFI_IMAGE_NT_HEADERS32 is for PE32 and + EFI_IMAGE_NT_HEADERS64 is for PE32+. + + This file is coded to the Visual Studio, Microsoft Portable Executable and + Common Object File Format Specification, Revision 9.3 - December 29, 2015. + This file also includes some definitions in PI Specification, Revision 1.0. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> +Portions Copyright (c) 2016 - 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> +Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PE_IMAGE_H__ +#define __PE_IMAGE_H__ + +// +// PE32+ Subsystem type for EFI images +// +#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13///< defined PI Specification, 1.0 + +// +// PE32+ Machine type for EFI images +// +#define IMAGE_FILE_MACHINE_I386 0x014c +#define IMAGE_FILE_MACHINE_IA64 0x0200 +#define IMAGE_FILE_MACHINE_EBC 0x0EBC +#define IMAGE_FILE_MACHINE_X64 0x8664 +#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x01c2 +#define IMAGE_FILE_MACHINE_ARM64 0xAA64 +#define IMAGE_FILE_MACHINE_RISCV32 0x5032 +#define IMAGE_FILE_MACHINE_RISCV64 0x5064 +#define IMAGE_FILE_MACHINE_RISCV128 0x5128 +#define IMAGE_FILE_MACHINE_LOONGARCH32 0x6232 +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 + +// +// EXE file formats +// +#define EFI_IMAGE_DOS_SIGNATURE SIGNATURE_16('M', 'Z') +#define EFI_IMAGE_OS2_SIGNATURE SIGNATURE_16('N', 'E') +#define EFI_IMAGE_OS2_SIGNATURE_LE SIGNATURE_16('L', 'E') +#define EFI_IMAGE_NT_SIGNATURE SIGNATURE_32('P', 'E', '\0', '\0') + +/// +/// PE images can start with an optional DOS header, so if an image is run +/// under DOS it can print an error message. +/// +typedef struct { + UINT16 e_magic; ///< Magic number. + UINT16 e_cblp; ///< Bytes on last page of file. + UINT16 e_cp; ///< Pages in file. + UINT16 e_crlc; ///< Relocations. + UINT16 e_cparhdr; ///< Size of header in paragraphs. + UINT16 e_minalloc; ///< Minimum extra paragraphs needed. + UINT16 e_maxalloc; ///< Maximum extra paragraphs needed. + UINT16 e_ss; ///< Initial (relative) SS value. + UINT16 e_sp; ///< Initial SP value. + UINT16 e_csum; ///< Checksum. + UINT16 e_ip; ///< Initial IP value. + UINT16 e_cs; ///< Initial (relative) CS value. + UINT16 e_lfarlc; ///< File address of relocation table. + UINT16 e_ovno; ///< Overlay number. + UINT16 e_res[4]; ///< Reserved words. + UINT16 e_oemid; ///< OEM identifier (for e_oeminfo). + UINT16 e_oeminfo; ///< OEM information; e_oemid specific. + UINT16 e_res2[10]; ///< Reserved words. + UINT32 e_lfanew; ///< File address of new exe header. +} EFI_IMAGE_DOS_HEADER; + +/// +/// COFF File Header (Object and Image). +/// +typedef struct { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} EFI_IMAGE_FILE_HEADER; + +/// +/// Size of EFI_IMAGE_FILE_HEADER. +/// +#define EFI_IMAGE_SIZEOF_FILE_HEADER 20 + +// +// Characteristics +// +#define EFI_IMAGE_FILE_RELOCS_STRIPPED BIT0 ///< 0x0001 Relocation info stripped from file. +#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE BIT1 ///< 0x0002 File is executable (i.e. no unresolved externel references). +#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED BIT2 ///< 0x0004 Line numbers stripped from file. +#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED BIT3 ///< 0x0008 Local symbols stripped from file. +#define EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE BIT5 ///< 0x0020 Supports addresses > 2-GB +#define EFI_IMAGE_FILE_BYTES_REVERSED_LO BIT7 ///< 0x0080 Bytes of machine word are reversed. +#define EFI_IMAGE_FILE_32BIT_MACHINE BIT8 ///< 0x0100 32 bit word machine. +#define EFI_IMAGE_FILE_DEBUG_STRIPPED BIT9 ///< 0x0200 Debugging info stripped from file in .DBG file. +#define EFI_IMAGE_FILE_SYSTEM BIT12 ///< 0x1000 System File. +#define EFI_IMAGE_FILE_DLL BIT13 ///< 0x2000 File is a DLL. +#define EFI_IMAGE_FILE_BYTES_REVERSED_HI BIT15 ///< 0x8000 Bytes of machine word are reversed. + +/// +/// Header Data Directories. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 Size; +} EFI_IMAGE_DATA_DIRECTORY; + +// +// Directory Entries +// +#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0 +#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1 +#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2 +#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 +#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4 +#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5 +#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6 +#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 +#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 +#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9 +#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 + +#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16 + +/// +/// @attention +/// EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC means PE32 and +/// EFI_IMAGE_OPTIONAL_HEADER32 must be used. The data structures only vary +/// after NT additional fields. +/// +#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b + +/// +/// Optional Header Standard Fields for PE32. +/// +typedef struct { + /// + /// Standard fields. + /// + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; ///< PE32 contains this additional field, which is absent in PE32+. + /// + /// Optional Header Windows-Specific Fields. + /// + UINT32 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT32 SizeOfStackReserve; + UINT32 SizeOfStackCommit; + UINT32 SizeOfHeapReserve; + UINT32 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; +} EFI_IMAGE_OPTIONAL_HEADER32; + +/// +/// @attention +/// EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC means PE32+ and +/// EFI_IMAGE_OPTIONAL_HEADER64 must be used. The data structures only vary +/// after NT additional fields. +/// +#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + +/// +/// Optional Header Standard Fields for PE32+. +/// +typedef struct { + /// + /// Standard fields. + /// + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + /// + /// Optional Header Windows-Specific Fields. + /// + UINT64 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT64 SizeOfStackReserve; + UINT64 SizeOfStackCommit; + UINT64 SizeOfHeapReserve; + UINT64 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; +} EFI_IMAGE_OPTIONAL_HEADER64; + +/// +/// @attention +/// EFI_IMAGE_NT_HEADERS32 is for use ONLY by tools. +/// +typedef struct { + UINT32 Signature; + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader; +} EFI_IMAGE_NT_HEADERS32; + +#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32) + +/// +/// @attention +/// EFI_IMAGE_HEADERS64 is for use ONLY by tools. +/// +typedef struct { + UINT32 Signature; + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader; +} EFI_IMAGE_NT_HEADERS64; + +#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64) + +// +// Other Windows Subsystem Values +// +#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0 +#define EFI_IMAGE_SUBSYSTEM_NATIVE 1 +#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2 +#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3 +#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5 +#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7 + +// +// DLL Characteristics +// +#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020 +#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040 +#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 0x0080 +#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 +#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200 +#define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 +#define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 +#define IMAGE_DLLCHARACTERISTICS_APPCONTAINER 0x1000 +#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 +#define IMAGE_DLLCHARACTERISTICS_GUARD_CF 0x4000 +#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 + +/// +/// Length of ShortName. +/// +#define EFI_IMAGE_SIZEOF_SHORT_NAME 8 + +/// +/// Section Table. This table immediately follows the optional header. +/// +typedef struct { + UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME]; + union { + UINT32 PhysicalAddress; + UINT32 VirtualSize; + } Misc; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} EFI_IMAGE_SECTION_HEADER; + +/// +/// Size of EFI_IMAGE_SECTION_HEADER. +/// +#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40 + +// +// Section Flags Values +// +#define EFI_IMAGE_SCN_TYPE_NO_PAD BIT3 ///< 0x00000008 ///< Reserved. +#define EFI_IMAGE_SCN_CNT_CODE BIT5 ///< 0x00000020 +#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA BIT6 ///< 0x00000040 +#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA BIT7 ///< 0x00000080 + +#define EFI_IMAGE_SCN_LNK_OTHER BIT8 ///< 0x00000100 ///< Reserved. +#define EFI_IMAGE_SCN_LNK_INFO BIT9 ///< 0x00000200 ///< Section contains comments or some other type of information. +#define EFI_IMAGE_SCN_LNK_REMOVE BIT11 ///< 0x00000800 ///< Section contents will not become part of image. +#define EFI_IMAGE_SCN_LNK_COMDAT BIT12 ///< 0x00001000 + +#define EFI_IMAGE_SCN_ALIGN_1BYTES BIT20 ///< 0x00100000 +#define EFI_IMAGE_SCN_ALIGN_2BYTES BIT21 ///< 0x00200000 +#define EFI_IMAGE_SCN_ALIGN_4BYTES (BIT20|BIT21) ///< 0x00300000 +#define EFI_IMAGE_SCN_ALIGN_8BYTES BIT22 ///< 0x00400000 +#define EFI_IMAGE_SCN_ALIGN_16BYTES (BIT20|BIT22) ///< 0x00500000 +#define EFI_IMAGE_SCN_ALIGN_32BYTES (BIT21|BIT22) ///< 0x00600000 +#define EFI_IMAGE_SCN_ALIGN_64BYTES (BIT20|BIT21|BIT22) ///< 0x00700000 + +#define EFI_IMAGE_SCN_MEM_DISCARDABLE BIT25 ///< 0x02000000 +#define EFI_IMAGE_SCN_MEM_NOT_CACHED BIT26 ///< 0x04000000 +#define EFI_IMAGE_SCN_MEM_NOT_PAGED BIT27 ///< 0x08000000 +#define EFI_IMAGE_SCN_MEM_SHARED BIT28 ///< 0x10000000 +#define EFI_IMAGE_SCN_MEM_EXECUTE BIT29 ///< 0x20000000 +#define EFI_IMAGE_SCN_MEM_READ BIT30 ///< 0x40000000 +#define EFI_IMAGE_SCN_MEM_WRITE BIT31 ///< 0x80000000 + +/// +/// Size of a Symbol Table Record. +/// +#define EFI_IMAGE_SIZEOF_SYMBOL 18 + +// +// Symbols have a section number of the section in which they are +// defined. Otherwise, section numbers have the following meanings: +// +#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 ///< Symbol is undefined or is common. +#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 ///< Symbol is an absolute value. +#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 ///< Symbol is a special debug item. + +// +// Symbol Type (fundamental) values. +// +#define EFI_IMAGE_SYM_TYPE_NULL 0 ///< no type. +#define EFI_IMAGE_SYM_TYPE_VOID 1 ///< no valid type. +#define EFI_IMAGE_SYM_TYPE_CHAR 2 ///< type character. +#define EFI_IMAGE_SYM_TYPE_SHORT 3 ///< type short integer. +#define EFI_IMAGE_SYM_TYPE_INT 4 +#define EFI_IMAGE_SYM_TYPE_LONG 5 +#define EFI_IMAGE_SYM_TYPE_FLOAT 6 +#define EFI_IMAGE_SYM_TYPE_DOUBLE 7 +#define EFI_IMAGE_SYM_TYPE_STRUCT 8 +#define EFI_IMAGE_SYM_TYPE_UNION 9 +#define EFI_IMAGE_SYM_TYPE_ENUM 10 ///< enumeration. +#define EFI_IMAGE_SYM_TYPE_MOE 11 ///< member of enumeration. +#define EFI_IMAGE_SYM_TYPE_BYTE 12 +#define EFI_IMAGE_SYM_TYPE_WORD 13 +#define EFI_IMAGE_SYM_TYPE_UINT 14 +#define EFI_IMAGE_SYM_TYPE_DWORD 15 + +// +// Symbol Type (derived) values. +// +#define EFI_IMAGE_SYM_DTYPE_NULL 0 ///< no derived type. +#define EFI_IMAGE_SYM_DTYPE_POINTER 1 +#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2 +#define EFI_IMAGE_SYM_DTYPE_ARRAY 3 + +// +// Storage classes. +// +#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION ((UINT8) -1) +#define EFI_IMAGE_SYM_CLASS_NULL 0 +#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1 +#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2 +#define EFI_IMAGE_SYM_CLASS_STATIC 3 +#define EFI_IMAGE_SYM_CLASS_REGISTER 4 +#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define EFI_IMAGE_SYM_CLASS_LABEL 6 +#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9 +#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12 +#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18 +#define EFI_IMAGE_SYM_CLASS_BLOCK 100 +#define EFI_IMAGE_SYM_CLASS_FUNCTION 101 +#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define EFI_IMAGE_SYM_CLASS_FILE 103 +#define EFI_IMAGE_SYM_CLASS_SECTION 104 +#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +// +// type packing constants +// +#define EFI_IMAGE_N_BTMASK 017 +#define EFI_IMAGE_N_TMASK 060 +#define EFI_IMAGE_N_TMASK1 0300 +#define EFI_IMAGE_N_TMASK2 0360 +#define EFI_IMAGE_N_BTSHFT 4 +#define EFI_IMAGE_N_TSHIFT 2 + +// +// Communal selection types. +// +#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define EFI_IMAGE_COMDAT_SELECT_ANY 2 +#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +// +// the following values only be referred in PeCoff, not defined in PECOFF. +// +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + +/// +/// Relocation format. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} EFI_IMAGE_RELOCATION; + +/// +/// Size of EFI_IMAGE_RELOCATION +/// +#define EFI_IMAGE_SIZEOF_RELOCATION 10 + +// +// I386 relocation types. +// +#define EFI_IMAGE_REL_I386_ABSOLUTE 0x0000 ///< Reference is absolute, no relocation is necessary. +#define EFI_IMAGE_REL_I386_DIR16 0x0001 ///< Direct 16-bit reference to the symbols virtual address. +#define EFI_IMAGE_REL_I386_REL16 0x0002 ///< PC-relative 16-bit reference to the symbols virtual address. +#define EFI_IMAGE_REL_I386_DIR32 0x0006 ///< Direct 32-bit reference to the symbols virtual address. +#define EFI_IMAGE_REL_I386_DIR32NB 0x0007 ///< Direct 32-bit reference to the symbols virtual address, base not included. +#define EFI_IMAGE_REL_I386_SEG12 0x0009 ///< Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address. +#define EFI_IMAGE_REL_I386_SECTION 0x000A +#define EFI_IMAGE_REL_I386_SECREL 0x000B +#define EFI_IMAGE_REL_I386_REL32 0x0014 ///< PC-relative 32-bit reference to the symbols virtual address. + +// +// x64 processor relocation types. +// +#define IMAGE_REL_AMD64_ABSOLUTE 0x0000 +#define IMAGE_REL_AMD64_ADDR64 0x0001 +#define IMAGE_REL_AMD64_ADDR32 0x0002 +#define IMAGE_REL_AMD64_ADDR32NB 0x0003 +#define IMAGE_REL_AMD64_REL32 0x0004 +#define IMAGE_REL_AMD64_REL32_1 0x0005 +#define IMAGE_REL_AMD64_REL32_2 0x0006 +#define IMAGE_REL_AMD64_REL32_3 0x0007 +#define IMAGE_REL_AMD64_REL32_4 0x0008 +#define IMAGE_REL_AMD64_REL32_5 0x0009 +#define IMAGE_REL_AMD64_SECTION 0x000A +#define IMAGE_REL_AMD64_SECREL 0x000B +#define IMAGE_REL_AMD64_SECREL7 0x000C +#define IMAGE_REL_AMD64_TOKEN 0x000D +#define IMAGE_REL_AMD64_SREL32 0x000E +#define IMAGE_REL_AMD64_PAIR 0x000F +#define IMAGE_REL_AMD64_SSPAN32 0x0010 + +/// +/// Based relocation format. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 SizeOfBlock; +} EFI_IMAGE_BASE_RELOCATION; + +/// +/// Size of EFI_IMAGE_BASE_RELOCATION. +/// +#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8 + +// +// Based relocation types. +// +#define EFI_IMAGE_REL_BASED_ABSOLUTE 0 +#define EFI_IMAGE_REL_BASED_HIGH 1 +#define EFI_IMAGE_REL_BASED_LOW 2 +#define EFI_IMAGE_REL_BASED_HIGHLOW 3 +#define EFI_IMAGE_REL_BASED_HIGHADJ 4 +#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5 +#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7 +#define EFI_IMAGE_REL_BASED_IA64_IMM64 9 +#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 9 +#define EFI_IMAGE_REL_BASED_DIR64 10 + +/// +/// Relocation types of RISC-V processor. +/// +#define EFI_IMAGE_REL_BASED_RISCV_HI20 5 +#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7 +#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8 + +// +// Relocation types of LoongArch processor. +// +#define EFI_IMAGE_REL_BASED_LOONGARCH32_MARK_LA 8 +#define EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA 8 + +/// +/// Line number format. +/// +typedef struct { + union { + UINT32 SymbolTableIndex; ///< Symbol table index of function name if Linenumber is 0. + UINT32 VirtualAddress; ///< Virtual address of line number. + } Type; + UINT16 Linenumber; ///< Line number. +} EFI_IMAGE_LINENUMBER; + +/// +/// Size of EFI_IMAGE_LINENUMBER. +/// +#define EFI_IMAGE_SIZEOF_LINENUMBER 6 + +// +// Archive format. +// +#define EFI_IMAGE_ARCHIVE_START_SIZE 8 +#define EFI_IMAGE_ARCHIVE_START "!<arch>\n" +#define EFI_IMAGE_ARCHIVE_END "`\n" +#define EFI_IMAGE_ARCHIVE_PAD "\n" +#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +/// +/// Archive Member Headers +/// +typedef struct { + UINT8 Name[16]; ///< File member name - `/' terminated. + UINT8 Date[12]; ///< File member date - decimal. + UINT8 UserID[6]; ///< File member user id - decimal. + UINT8 GroupID[6]; ///< File member group id - decimal. + UINT8 Mode[8]; ///< File member mode - octal. + UINT8 Size[10]; ///< File member size - decimal. + UINT8 EndHeader[2]; ///< String to end header. (0x60 0x0A). +} EFI_IMAGE_ARCHIVE_MEMBER_HEADER; + +/// +/// Size of EFI_IMAGE_ARCHIVE_MEMBER_HEADER. +/// +#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +// +// DLL Support +// + +/// +/// Export Directory Table. +/// +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Name; + UINT32 Base; + UINT32 NumberOfFunctions; + UINT32 NumberOfNames; + UINT32 AddressOfFunctions; + UINT32 AddressOfNames; + UINT32 AddressOfNameOrdinals; +} EFI_IMAGE_EXPORT_DIRECTORY; + +// +// Based export types. +// +#define EFI_IMAGE_EXPORT_ORDINAL_BASE 1 +#define EFI_IMAGE_EXPORT_ADDR_SIZE 4 +#define EFI_IMAGE_EXPORT_ORDINAL_SIZE 2 + +/// +/// Hint/Name Table. +/// +typedef struct { + UINT16 Hint; + UINT8 Name[1]; +} EFI_IMAGE_IMPORT_BY_NAME; + +/// +/// Import Address Table RVA (Thunk Table). +/// +typedef struct { + union { + UINT32 Function; + UINT32 Ordinal; + EFI_IMAGE_IMPORT_BY_NAME *AddressOfData; + } u1; +} EFI_IMAGE_THUNK_DATA; + +#define EFI_IMAGE_ORDINAL_FLAG BIT31 ///< Flag for PE32. +#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0) +#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +/// +/// Import Directory Table +/// +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT32 ForwarderChain; + UINT32 Name; + EFI_IMAGE_THUNK_DATA *FirstThunk; +} EFI_IMAGE_IMPORT_DESCRIPTOR; + +/// +/// Debug Directory Format. +/// +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Type; + UINT32 SizeOfData; + UINT32 RVA; ///< The address of the debug data when loaded, relative to the image base. + UINT32 FileOffset; ///< The file pointer to the debug data. +} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY; + +#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2 ///< The Visual C++ debug information. +#define EFI_IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS 20 + +/// +/// Debug Data Structure defined in Microsoft C++. +/// +#define CODEVIEW_SIGNATURE_NB10 SIGNATURE_32('N', 'B', '1', '0') +typedef struct { + UINT32 Signature; ///< "NB10" + UINT32 Unknown; + UINT32 Unknown2; + UINT32 Unknown3; + // + // Filename of .PDB goes here + // +} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY; + +/// +/// Debug Data Structure defined in Microsoft C++. +/// +#define CODEVIEW_SIGNATURE_RSDS SIGNATURE_32('R', 'S', 'D', 'S') +typedef struct { + UINT32 Signature; ///< "RSDS". + UINT32 Unknown; + UINT32 Unknown2; + UINT32 Unknown3; + UINT32 Unknown4; + UINT32 Unknown5; + // + // Filename of .PDB goes here + // +} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY; + +/// +/// Debug Data Structure defined by Apple Mach-O to Coff utility. +/// +#define CODEVIEW_SIGNATURE_MTOC SIGNATURE_32('M', 'T', 'O', 'C') +typedef struct { + UINT32 Signature; ///< "MTOC". + GUID MachOUuid; + // + // Filename of .DLL (Mach-O with debug info) goes here + // +} EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY; + +// +// .pdata entries for X64 +// +typedef struct { + UINT32 FunctionStartAddress; + UINT32 FunctionEndAddress; + UINT32 UnwindInfoAddress; +} RUNTIME_FUNCTION; + +typedef struct { + UINT8 Version : 3; + UINT8 Flags : 5; + UINT8 SizeOfProlog; + UINT8 CountOfUnwindCodes; + UINT8 FrameRegister : 4; + UINT8 FrameRegisterOffset : 4; +} UNWIND_INFO; + +/// +/// Extended DLL Characteristics +/// +#define EFI_IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT 0x0001 +#define EFI_IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT 0x0040 + +typedef struct { + UINT32 DllCharacteristicsEx; +} EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY; + +/// +/// Resource format. +/// +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT16 NumberOfNamedEntries; + UINT16 NumberOfIdEntries; + // + // Array of EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY entries goes here. + // +} EFI_IMAGE_RESOURCE_DIRECTORY; + +/// +/// Resource directory entry format. +/// +typedef struct { + union { + struct { + UINT32 NameOffset : 31; + UINT32 NameIsString : 1; + } s; + UINT32 Id; + } u1; + union { + UINT32 OffsetToData; + struct { + UINT32 OffsetToDirectory : 31; + UINT32 DataIsDirectory : 1; + } s; + } u2; +} EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY; + +/// +/// Resource directory entry for string. +/// +typedef struct { + UINT16 Length; + CHAR16 String[1]; +} EFI_IMAGE_RESOURCE_DIRECTORY_STRING; + +/// +/// Resource directory entry for data array. +/// +typedef struct { + UINT32 OffsetToData; + UINT32 Size; + UINT32 CodePage; + UINT32 Reserved; +} EFI_IMAGE_RESOURCE_DATA_ENTRY; + +/// +/// Header format for TE images, defined in the PI Specification, 1.0. +/// +typedef struct { + UINT16 Signature; ///< The signature for TE format = "VZ". + UINT16 Machine; ///< From the original file header. + UINT8 NumberOfSections; ///< From the original file header. + UINT8 Subsystem; ///< From original optional header. + UINT16 StrippedSize; ///< Number of bytes we removed from the header. + UINT32 AddressOfEntryPoint; ///< Offset to entry point -- from original optional header. + UINT32 BaseOfCode; ///< From original image -- required for ITP debug. + UINT64 ImageBase; ///< From original file header. + EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; ///< Only base relocation and debug directory. +} EFI_TE_IMAGE_HEADER; + +#define EFI_TE_IMAGE_HEADER_SIGNATURE SIGNATURE_16('V', 'Z') + +// +// Data directory indexes in our TE image header +// +#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0 +#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1 + +/// +/// Union of PE32, PE32+, and TE headers. +/// +typedef union { + EFI_IMAGE_NT_HEADERS32 Pe32; + EFI_IMAGE_NT_HEADERS64 Pe32Plus; + EFI_TE_IMAGE_HEADER Te; +} EFI_IMAGE_OPTIONAL_HEADER_UNION; + +typedef union { + EFI_IMAGE_NT_HEADERS32 *Pe32; + EFI_IMAGE_NT_HEADERS64 *Pe32Plus; + EFI_TE_IMAGE_HEADER *Te; + EFI_IMAGE_OPTIONAL_HEADER_UNION *Union; +} EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION; + +#endif diff --git a/sys/contrib/edk2/Include/IndustryStandard/Tpm12.h b/sys/contrib/edk2/Include/IndustryStandard/Tpm12.h new file mode 100644 index 000000000000..0435bebe8e18 --- /dev/null +++ b/sys/contrib/edk2/Include/IndustryStandard/Tpm12.h @@ -0,0 +1,2165 @@ +/** @file
+ TPM Specification data structures (TCG TPM Specification Version 1.2 Revision 103)
+ See http://trustedcomputinggroup.org for latest specification updates
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TPM12_H_
+#define _TPM12_H_
+
+///
+/// The start of TPM return codes
+///
+#define TPM_BASE 0
+
+//
+// All structures MUST be packed on a byte boundary.
+//
+
+#pragma pack (1)
+
+//
+// Part 2, section 2.2.3: Helper redefinitions
+//
+///
+/// Indicates the conditions where it is required that authorization be presented
+///
+typedef UINT8 TPM_AUTH_DATA_USAGE;
+///
+/// The information as to what the payload is in an encrypted structure
+///
+typedef UINT8 TPM_PAYLOAD_TYPE;
+///
+/// The version info breakdown
+///
+typedef UINT8 TPM_VERSION_BYTE;
+///
+/// The state of the dictionary attack mitigation logic
+///
+typedef UINT8 TPM_DA_STATE;
+///
+/// The request or response authorization type
+///
+typedef UINT16 TPM_TAG;
+///
+/// The protocol in use
+///
+typedef UINT16 TPM_PROTOCOL_ID;
+///
+/// Indicates the start state
+///
+typedef UINT16 TPM_STARTUP_TYPE;
+///
+/// The definition of the encryption scheme
+///
+typedef UINT16 TPM_ENC_SCHEME;
+///
+/// The definition of the signature scheme
+///
+typedef UINT16 TPM_SIG_SCHEME;
+///
+/// The definition of the migration scheme
+///
+typedef UINT16 TPM_MIGRATE_SCHEME;
+///
+/// Sets the state of the physical presence mechanism
+///
+typedef UINT16 TPM_PHYSICAL_PRESENCE;
+///
+/// Indicates the types of entity that are supported by the TPM
+///
+typedef UINT16 TPM_ENTITY_TYPE;
+///
+/// Indicates the permitted usage of the key
+///
+typedef UINT16 TPM_KEY_USAGE;
+///
+/// The type of asymmetric encrypted structure in use by the endorsement key
+///
+typedef UINT16 TPM_EK_TYPE;
+///
+/// The tag for the structure
+///
+typedef UINT16 TPM_STRUCTURE_TAG;
+///
+/// The platform specific spec to which the information relates to
+///
+typedef UINT16 TPM_PLATFORM_SPECIFIC;
+///
+/// The command ordinal
+///
+typedef UINT32 TPM_COMMAND_CODE;
+///
+/// Identifies a TPM capability area
+///
+typedef UINT32 TPM_CAPABILITY_AREA;
+///
+/// Indicates information regarding a key
+///
+typedef UINT32 TPM_KEY_FLAGS;
+///
+/// Indicates the type of algorithm
+///
+typedef UINT32 TPM_ALGORITHM_ID;
+///
+/// The locality modifier
+///
+typedef UINT32 TPM_MODIFIER_INDICATOR;
+///
+/// The actual number of a counter
+///
+typedef UINT32 TPM_ACTUAL_COUNT;
+///
+/// Attributes that define what options are in use for a transport session
+///
+typedef UINT32 TPM_TRANSPORT_ATTRIBUTES;
+///
+/// Handle to an authorization session
+///
+typedef UINT32 TPM_AUTHHANDLE;
+///
+/// Index to a DIR register
+///
+typedef UINT32 TPM_DIRINDEX;
+///
+/// The area where a key is held assigned by the TPM
+///
+typedef UINT32 TPM_KEY_HANDLE;
+///
+/// Index to a PCR register
+///
+typedef UINT32 TPM_PCRINDEX;
+///
+/// The return code from a function
+///
+typedef UINT32 TPM_RESULT;
+///
+/// The types of resources that a TPM may have using internal resources
+///
+typedef UINT32 TPM_RESOURCE_TYPE;
+///
+/// Allows for controlling of the key when loaded and how to handle TPM_Startup issues
+///
+typedef UINT32 TPM_KEY_CONTROL;
+///
+/// The index into the NV storage area
+///
+typedef UINT32 TPM_NV_INDEX;
+///
+/// The family ID. Family IDs are automatically assigned a sequence number by the TPM.
+/// A trusted process can set the FamilyID value in an individual row to NULL, which
+/// invalidates that row. The family ID resets to NULL on each change of TPM Owner.
+///
+typedef UINT32 TPM_FAMILY_ID;
+///
+/// IA value used as a label for the most recent verification of this family. Set to zero when not in use.
+///
+typedef UINT32 TPM_FAMILY_VERIFICATION;
+///
+/// How the TPM handles var
+///
+typedef UINT32 TPM_STARTUP_EFFECTS;
+///
+/// The mode of a symmetric encryption
+///
+typedef UINT32 TPM_SYM_MODE;
+///
+/// The family flags
+///
+typedef UINT32 TPM_FAMILY_FLAGS;
+///
+/// The index value for the delegate NV table
+///
+typedef UINT32 TPM_DELEGATE_INDEX;
+///
+/// The restrictions placed on delegation of CMK commands
+///
+typedef UINT32 TPM_CMK_DELEGATE;
+///
+/// The ID value of a monotonic counter
+///
+typedef UINT32 TPM_COUNT_ID;
+///
+/// A command to execute
+///
+typedef UINT32 TPM_REDIT_COMMAND;
+///
+/// A transport session handle
+///
+typedef UINT32 TPM_TRANSHANDLE;
+///
+/// A generic handle could be key, transport etc
+///
+typedef UINT32 TPM_HANDLE;
+///
+/// What operation is happening
+///
+typedef UINT32 TPM_FAMILY_OPERATION;
+
+//
+// Part 2, section 2.2.4: Vendor specific
+// The following defines allow for the quick specification of a
+// vendor specific item.
+//
+#define TPM_Vendor_Specific32 ((UINT32) 0x00000400)
+#define TPM_Vendor_Specific8 ((UINT8) 0x80)
+
+//
+// Part 2, section 3.1: TPM_STRUCTURE_TAG
+//
+#define TPM_TAG_CONTEXTBLOB ((TPM_STRUCTURE_TAG) 0x0001)
+#define TPM_TAG_CONTEXT_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0002)
+#define TPM_TAG_CONTEXTPOINTER ((TPM_STRUCTURE_TAG) 0x0003)
+#define TPM_TAG_CONTEXTLIST ((TPM_STRUCTURE_TAG) 0x0004)
+#define TPM_TAG_SIGNINFO ((TPM_STRUCTURE_TAG) 0x0005)
+#define TPM_TAG_PCR_INFO_LONG ((TPM_STRUCTURE_TAG) 0x0006)
+#define TPM_TAG_PERSISTENT_FLAGS ((TPM_STRUCTURE_TAG) 0x0007)
+#define TPM_TAG_VOLATILE_FLAGS ((TPM_STRUCTURE_TAG) 0x0008)
+#define TPM_TAG_PERSISTENT_DATA ((TPM_STRUCTURE_TAG) 0x0009)
+#define TPM_TAG_VOLATILE_DATA ((TPM_STRUCTURE_TAG) 0x000A)
+#define TPM_TAG_SV_DATA ((TPM_STRUCTURE_TAG) 0x000B)
+#define TPM_TAG_EK_BLOB ((TPM_STRUCTURE_TAG) 0x000C)
+#define TPM_TAG_EK_BLOB_AUTH ((TPM_STRUCTURE_TAG) 0x000D)
+#define TPM_TAG_COUNTER_VALUE ((TPM_STRUCTURE_TAG) 0x000E)
+#define TPM_TAG_TRANSPORT_INTERNAL ((TPM_STRUCTURE_TAG) 0x000F)
+#define TPM_TAG_TRANSPORT_LOG_IN ((TPM_STRUCTURE_TAG) 0x0010)
+#define TPM_TAG_TRANSPORT_LOG_OUT ((TPM_STRUCTURE_TAG) 0x0011)
+#define TPM_TAG_AUDIT_EVENT_IN ((TPM_STRUCTURE_TAG) 0x0012)
+#define TPM_TAG_AUDIT_EVENT_OUT ((TPM_STRUCTURE_TAG) 0x0013)
+#define TPM_TAG_CURRENT_TICKS ((TPM_STRUCTURE_TAG) 0x0014)
+#define TPM_TAG_KEY ((TPM_STRUCTURE_TAG) 0x0015)
+#define TPM_TAG_STORED_DATA12 ((TPM_STRUCTURE_TAG) 0x0016)
+#define TPM_TAG_NV_ATTRIBUTES ((TPM_STRUCTURE_TAG) 0x0017)
+#define TPM_TAG_NV_DATA_PUBLIC ((TPM_STRUCTURE_TAG) 0x0018)
+#define TPM_TAG_NV_DATA_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0019)
+#define TPM_TAG_DELEGATIONS ((TPM_STRUCTURE_TAG) 0x001A)
+#define TPM_TAG_DELEGATE_PUBLIC ((TPM_STRUCTURE_TAG) 0x001B)
+#define TPM_TAG_DELEGATE_TABLE_ROW ((TPM_STRUCTURE_TAG) 0x001C)
+#define TPM_TAG_TRANSPORT_AUTH ((TPM_STRUCTURE_TAG) 0x001D)
+#define TPM_TAG_TRANSPORT_PUBLIC ((TPM_STRUCTURE_TAG) 0x001E)
+#define TPM_TAG_PERMANENT_FLAGS ((TPM_STRUCTURE_TAG) 0x001F)
+#define TPM_TAG_STCLEAR_FLAGS ((TPM_STRUCTURE_TAG) 0x0020)
+#define TPM_TAG_STANY_FLAGS ((TPM_STRUCTURE_TAG) 0x0021)
+#define TPM_TAG_PERMANENT_DATA ((TPM_STRUCTURE_TAG) 0x0022)
+#define TPM_TAG_STCLEAR_DATA ((TPM_STRUCTURE_TAG) 0x0023)
+#define TPM_TAG_STANY_DATA ((TPM_STRUCTURE_TAG) 0x0024)
+#define TPM_TAG_FAMILY_TABLE_ENTRY ((TPM_STRUCTURE_TAG) 0x0025)
+#define TPM_TAG_DELEGATE_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0026)
+#define TPM_TAG_DELG_KEY_BLOB ((TPM_STRUCTURE_TAG) 0x0027)
+#define TPM_TAG_KEY12 ((TPM_STRUCTURE_TAG) 0x0028)
+#define TPM_TAG_CERTIFY_INFO2 ((TPM_STRUCTURE_TAG) 0x0029)
+#define TPM_TAG_DELEGATE_OWNER_BLOB ((TPM_STRUCTURE_TAG) 0x002A)
+#define TPM_TAG_EK_BLOB_ACTIVATE ((TPM_STRUCTURE_TAG) 0x002B)
+#define TPM_TAG_DAA_BLOB ((TPM_STRUCTURE_TAG) 0x002C)
+#define TPM_TAG_DAA_CONTEXT ((TPM_STRUCTURE_TAG) 0x002D)
+#define TPM_TAG_DAA_ENFORCE ((TPM_STRUCTURE_TAG) 0x002E)
+#define TPM_TAG_DAA_ISSUER ((TPM_STRUCTURE_TAG) 0x002F)
+#define TPM_TAG_CAP_VERSION_INFO ((TPM_STRUCTURE_TAG) 0x0030)
+#define TPM_TAG_DAA_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0031)
+#define TPM_TAG_DAA_TPM ((TPM_STRUCTURE_TAG) 0x0032)
+#define TPM_TAG_CMK_MIGAUTH ((TPM_STRUCTURE_TAG) 0x0033)
+#define TPM_TAG_CMK_SIGTICKET ((TPM_STRUCTURE_TAG) 0x0034)
+#define TPM_TAG_CMK_MA_APPROVAL ((TPM_STRUCTURE_TAG) 0x0035)
+#define TPM_TAG_QUOTE_INFO2 ((TPM_STRUCTURE_TAG) 0x0036)
+#define TPM_TAG_DA_INFO ((TPM_STRUCTURE_TAG) 0x0037)
+#define TPM_TAG_DA_LIMITED ((TPM_STRUCTURE_TAG) 0x0038)
+#define TPM_TAG_DA_ACTION_TYPE ((TPM_STRUCTURE_TAG) 0x0039)
+
+//
+// Part 2, section 4: TPM Types
+//
+
+//
+// Part 2, section 4.1: TPM_RESOURCE_TYPE
+//
+#define TPM_RT_KEY ((TPM_RESOURCE_TYPE) 0x00000001) ///< The handle is a key handle and is the result of a LoadKey type operation
+#define TPM_RT_AUTH ((TPM_RESOURCE_TYPE) 0x00000002) ///< The handle is an authorization handle. Auth handles come from TPM_OIAP, TPM_OSAP and TPM_DSAP
+#define TPM_RT_HASH ((TPM_RESOURCE_TYPE) 0x00000003) ///< Reserved for hashes
+#define TPM_RT_TRANS ((TPM_RESOURCE_TYPE) 0x00000004) ///< The handle is for a transport session. Transport handles come from TPM_EstablishTransport
+#define TPM_RT_CONTEXT ((TPM_RESOURCE_TYPE) 0x00000005) ///< Resource wrapped and held outside the TPM using the context save/restore commands
+#define TPM_RT_COUNTER ((TPM_RESOURCE_TYPE) 0x00000006) ///< Reserved for counters
+#define TPM_RT_DELEGATE ((TPM_RESOURCE_TYPE) 0x00000007) ///< The handle is for a delegate row. These are the internal rows held in NV storage by the TPM
+#define TPM_RT_DAA_TPM ((TPM_RESOURCE_TYPE) 0x00000008) ///< The value is a DAA TPM specific blob
+#define TPM_RT_DAA_V0 ((TPM_RESOURCE_TYPE) 0x00000009) ///< The value is a DAA V0 parameter
+#define TPM_RT_DAA_V1 ((TPM_RESOURCE_TYPE) 0x0000000A) ///< The value is a DAA V1 parameter
+
+//
+// Part 2, section 4.2: TPM_PAYLOAD_TYPE
+//
+#define TPM_PT_ASYM ((TPM_PAYLOAD_TYPE) 0x01) ///< The entity is an asymmetric key
+#define TPM_PT_BIND ((TPM_PAYLOAD_TYPE) 0x02) ///< The entity is bound data
+#define TPM_PT_MIGRATE ((TPM_PAYLOAD_TYPE) 0x03) ///< The entity is a migration blob
+#define TPM_PT_MAINT ((TPM_PAYLOAD_TYPE) 0x04) ///< The entity is a maintenance blob
+#define TPM_PT_SEAL ((TPM_PAYLOAD_TYPE) 0x05) ///< The entity is sealed data
+#define TPM_PT_MIGRATE_RESTRICTED ((TPM_PAYLOAD_TYPE) 0x06) ///< The entity is a restricted-migration asymmetric key
+#define TPM_PT_MIGRATE_EXTERNAL ((TPM_PAYLOAD_TYPE) 0x07) ///< The entity is a external migratable key
+#define TPM_PT_CMK_MIGRATE ((TPM_PAYLOAD_TYPE) 0x08) ///< The entity is a CMK migratable blob
+#define TPM_PT_VENDOR_SPECIFIC ((TPM_PAYLOAD_TYPE) 0x80) ///< 0x80 - 0xFF Vendor specific payloads
+
+//
+// Part 2, section 4.3: TPM_ENTITY_TYPE
+//
+#define TPM_ET_KEYHANDLE ((UINT16) 0x0001) ///< The entity is a keyHandle or key
+#define TPM_ET_OWNER ((UINT16) 0x0002) ///< The entity is the TPM Owner
+#define TPM_ET_DATA ((UINT16) 0x0003) ///< The entity is some data
+#define TPM_ET_SRK ((UINT16) 0x0004) ///< The entity is the SRK
+#define TPM_ET_KEY ((UINT16) 0x0005) ///< The entity is a key or keyHandle
+#define TPM_ET_REVOKE ((UINT16) 0x0006) ///< The entity is the RevokeTrust value
+#define TPM_ET_DEL_OWNER_BLOB ((UINT16) 0x0007) ///< The entity is a delegate owner blob
+#define TPM_ET_DEL_ROW ((UINT16) 0x0008) ///< The entity is a delegate row
+#define TPM_ET_DEL_KEY_BLOB ((UINT16) 0x0009) ///< The entity is a delegate key blob
+#define TPM_ET_COUNTER ((UINT16) 0x000A) ///< The entity is a counter
+#define TPM_ET_NV ((UINT16) 0x000B) ///< The entity is a NV index
+#define TPM_ET_OPERATOR ((UINT16) 0x000C) ///< The entity is the operator
+#define TPM_ET_RESERVED_HANDLE ((UINT16) 0x0040) ///< Reserved. This value avoids collisions with the handle MSB setting.
+//
+// TPM_ENTITY_TYPE MSB Values: The MSB is used to indicate the ADIP encryption sheme when applicable
+//
+#define TPM_ET_XOR ((UINT16) 0x0000) ///< ADIP encryption scheme: XOR
+#define TPM_ET_AES128 ((UINT16) 0x0006) ///< ADIP encryption scheme: AES 128 bits
+
+//
+// Part 2, section 4.4.1: Reserved Key Handles
+//
+#define TPM_KH_SRK ((TPM_KEY_HANDLE) 0x40000000) ///< The handle points to the SRK
+#define TPM_KH_OWNER ((TPM_KEY_HANDLE) 0x40000001) ///< The handle points to the TPM Owner
+#define TPM_KH_REVOKE ((TPM_KEY_HANDLE) 0x40000002) ///< The handle points to the RevokeTrust value
+#define TPM_KH_TRANSPORT ((TPM_KEY_HANDLE) 0x40000003) ///< The handle points to the EstablishTransport static authorization
+#define TPM_KH_OPERATOR ((TPM_KEY_HANDLE) 0x40000004) ///< The handle points to the Operator auth
+#define TPM_KH_ADMIN ((TPM_KEY_HANDLE) 0x40000005) ///< The handle points to the delegation administration auth
+#define TPM_KH_EK ((TPM_KEY_HANDLE) 0x40000006) ///< The handle points to the PUBEK, only usable with TPM_OwnerReadInternalPub
+
+//
+// Part 2, section 4.5: TPM_STARTUP_TYPE
+//
+#define TPM_ST_CLEAR ((TPM_STARTUP_TYPE) 0x0001) ///< The TPM is starting up from a clean state
+#define TPM_ST_STATE ((TPM_STARTUP_TYPE) 0x0002) ///< The TPM is starting up from a saved state
+#define TPM_ST_DEACTIVATED ((TPM_STARTUP_TYPE) 0x0003) ///< The TPM is to startup and set the deactivated flag to TRUE
+
+//
+// Part 2, section 4.6: TPM_STATUP_EFFECTS
+// The table makeup is still an open issue.
+//
+
+//
+// Part 2, section 4.7: TPM_PROTOCOL_ID
+//
+#define TPM_PID_OIAP ((TPM_PROTOCOL_ID) 0x0001) ///< The OIAP protocol.
+#define TPM_PID_OSAP ((TPM_PROTOCOL_ID) 0x0002) ///< The OSAP protocol.
+#define TPM_PID_ADIP ((TPM_PROTOCOL_ID) 0x0003) ///< The ADIP protocol.
+#define TPM_PID_ADCP ((TPM_PROTOCOL_ID) 0x0004) ///< The ADCP protocol.
+#define TPM_PID_OWNER ((TPM_PROTOCOL_ID) 0x0005) ///< The protocol for taking ownership of a TPM.
+#define TPM_PID_DSAP ((TPM_PROTOCOL_ID) 0x0006) ///< The DSAP protocol
+#define TPM_PID_TRANSPORT ((TPM_PROTOCOL_ID) 0x0007) ///< The transport protocol
+
+//
+// Part 2, section 4.8: TPM_ALGORITHM_ID
+// The TPM MUST support the algorithms TPM_ALG_RSA, TPM_ALG_SHA, TPM_ALG_HMAC,
+// TPM_ALG_MGF1
+//
+#define TPM_ALG_RSA ((TPM_ALGORITHM_ID) 0x00000001) ///< The RSA algorithm.
+#define TPM_ALG_DES ((TPM_ALGORITHM_ID) 0x00000002) ///< The DES algorithm
+#define TPM_ALG_3DES ((TPM_ALGORITHM_ID) 0x00000003) ///< The 3DES algorithm in EDE mode
+#define TPM_ALG_SHA ((TPM_ALGORITHM_ID) 0x00000004) ///< The SHA1 algorithm
+#define TPM_ALG_HMAC ((TPM_ALGORITHM_ID) 0x00000005) ///< The RFC 2104 HMAC algorithm
+#define TPM_ALG_AES128 ((TPM_ALGORITHM_ID) 0x00000006) ///< The AES algorithm, key size 128
+#define TPM_ALG_MGF1 ((TPM_ALGORITHM_ID) 0x00000007) ///< The XOR algorithm using MGF1 to create a string the size of the encrypted block
+#define TPM_ALG_AES192 ((TPM_ALGORITHM_ID) 0x00000008) ///< AES, key size 192
+#define TPM_ALG_AES256 ((TPM_ALGORITHM_ID) 0x00000009) ///< AES, key size 256
+#define TPM_ALG_XOR ((TPM_ALGORITHM_ID) 0x0000000A) ///< XOR using the rolling nonces
+
+//
+// Part 2, section 4.9: TPM_PHYSICAL_PRESENCE
+//
+#define TPM_PHYSICAL_PRESENCE_HW_DISABLE ((TPM_PHYSICAL_PRESENCE) 0x0200) ///< Sets the physicalPresenceHWEnable to FALSE
+#define TPM_PHYSICAL_PRESENCE_CMD_DISABLE ((TPM_PHYSICAL_PRESENCE) 0x0100) ///< Sets the physicalPresenceCMDEnable to FALSE
+#define TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK ((TPM_PHYSICAL_PRESENCE) 0x0080) ///< Sets the physicalPresenceLifetimeLock to TRUE
+#define TPM_PHYSICAL_PRESENCE_HW_ENABLE ((TPM_PHYSICAL_PRESENCE) 0x0040) ///< Sets the physicalPresenceHWEnable to TRUE
+#define TPM_PHYSICAL_PRESENCE_CMD_ENABLE ((TPM_PHYSICAL_PRESENCE) 0x0020) ///< Sets the physicalPresenceCMDEnable to TRUE
+#define TPM_PHYSICAL_PRESENCE_NOTPRESENT ((TPM_PHYSICAL_PRESENCE) 0x0010) ///< Sets PhysicalPresence = FALSE
+#define TPM_PHYSICAL_PRESENCE_PRESENT ((TPM_PHYSICAL_PRESENCE) 0x0008) ///< Sets PhysicalPresence = TRUE
+#define TPM_PHYSICAL_PRESENCE_LOCK ((TPM_PHYSICAL_PRESENCE) 0x0004) ///< Sets PhysicalPresenceLock = TRUE
+
+//
+// Part 2, section 4.10: TPM_MIGRATE_SCHEME
+//
+#define TPM_MS_MIGRATE ((TPM_MIGRATE_SCHEME) 0x0001) ///< A public key that can be used with all TPM migration commands other than 'ReWrap' mode.
+#define TPM_MS_REWRAP ((TPM_MIGRATE_SCHEME) 0x0002) ///< A public key that can be used for the ReWrap mode of TPM_CreateMigrationBlob.
+#define TPM_MS_MAINT ((TPM_MIGRATE_SCHEME) 0x0003) ///< A public key that can be used for the Maintenance commands
+#define TPM_MS_RESTRICT_MIGRATE ((TPM_MIGRATE_SCHEME) 0x0004) ///< The key is to be migrated to a Migration Authority.
+#define TPM_MS_RESTRICT_APPROVE_DOUBLE ((TPM_MIGRATE_SCHEME) 0x0005) ///< The key is to be migrated to an entity approved by a Migration Authority using double wrapping
+
+//
+// Part 2, section 4.11: TPM_EK_TYPE
+//
+#define TPM_EK_TYPE_ACTIVATE ((TPM_EK_TYPE) 0x0001) ///< The blob MUST be TPM_EK_BLOB_ACTIVATE
+#define TPM_EK_TYPE_AUTH ((TPM_EK_TYPE) 0x0002) ///< The blob MUST be TPM_EK_BLOB_AUTH
+
+//
+// Part 2, section 4.12: TPM_PLATFORM_SPECIFIC
+//
+#define TPM_PS_PC_11 ((TPM_PLATFORM_SPECIFIC) 0x0001) ///< PC Specific version 1.1
+#define TPM_PS_PC_12 ((TPM_PLATFORM_SPECIFIC) 0x0002) ///< PC Specific version 1.2
+#define TPM_PS_PDA_12 ((TPM_PLATFORM_SPECIFIC) 0x0003) ///< PDA Specific version 1.2
+#define TPM_PS_Server_12 ((TPM_PLATFORM_SPECIFIC) 0x0004) ///< Server Specific version 1.2
+#define TPM_PS_Mobile_12 ((TPM_PLATFORM_SPECIFIC) 0x0005) ///< Mobil Specific version 1.2
+
+//
+// Part 2, section 5: Basic Structures
+//
+
+///
+/// Part 2, section 5.1: TPM_STRUCT_VER
+///
+typedef struct tdTPM_STRUCT_VER {
+ UINT8 major;
+ UINT8 minor;
+ UINT8 revMajor;
+ UINT8 revMinor;
+} TPM_STRUCT_VER;
+
+///
+/// Part 2, section 5.3: TPM_VERSION
+///
+typedef struct tdTPM_VERSION {
+ TPM_VERSION_BYTE major;
+ TPM_VERSION_BYTE minor;
+ UINT8 revMajor;
+ UINT8 revMinor;
+} TPM_VERSION;
+
+#define TPM_SHA1_160_HASH_LEN 0x14
+#define TPM_SHA1BASED_NONCE_LEN TPM_SHA1_160_HASH_LEN
+
+///
+/// Part 2, section 5.4: TPM_DIGEST
+///
+typedef struct tdTPM_DIGEST {
+ UINT8 digest[TPM_SHA1_160_HASH_LEN];
+} TPM_DIGEST;
+
+///
+/// This SHALL be the digest of the chosen identityLabel and privacyCA for a new TPM identity
+///
+typedef TPM_DIGEST TPM_CHOSENID_HASH;
+///
+/// This SHALL be the hash of a list of PCR indexes and PCR values that a key or data is bound to
+///
+typedef TPM_DIGEST TPM_COMPOSITE_HASH;
+///
+/// This SHALL be the value of a DIR register
+///
+typedef TPM_DIGEST TPM_DIRVALUE;
+
+typedef TPM_DIGEST TPM_HMAC;
+///
+/// The value inside of the PCR
+///
+typedef TPM_DIGEST TPM_PCRVALUE;
+///
+/// This SHALL be the value of the current internal audit state
+///
+typedef TPM_DIGEST TPM_AUDITDIGEST;
+
+///
+/// Part 2, section 5.5: TPM_NONCE
+///
+typedef struct tdTPM_NONCE {
+ UINT8 nonce[20];
+} TPM_NONCE;
+
+///
+/// This SHALL be a random value generated by a TPM immediately after the EK is installed
+/// in that TPM, whenever an EK is installed in that TPM
+///
+typedef TPM_NONCE TPM_DAA_TPM_SEED;
+///
+/// This SHALL be a random value
+///
+typedef TPM_NONCE TPM_DAA_CONTEXT_SEED;
+
+//
+// Part 2, section 5.6: TPM_AUTHDATA
+//
+///
+/// The AuthData data is the information that is saved or passed to provide proof of ownership
+/// 296 of an entity
+///
+typedef UINT8 tdTPM_AUTHDATA[20];
+
+typedef tdTPM_AUTHDATA TPM_AUTHDATA;
+///
+/// A secret plaintext value used in the authorization process
+///
+typedef TPM_AUTHDATA TPM_SECRET;
+///
+/// A ciphertext (encrypted) version of AuthData data. The encryption mechanism depends on the context
+///
+typedef TPM_AUTHDATA TPM_ENCAUTH;
+
+///
+/// Part 2, section 5.7: TPM_KEY_HANDLE_LIST
+/// Size of handle is loaded * sizeof(TPM_KEY_HANDLE)
+///
+typedef struct tdTPM_KEY_HANDLE_LIST {
+ UINT16 loaded;
+ TPM_KEY_HANDLE handle[1];
+} TPM_KEY_HANDLE_LIST;
+
+//
+// Part 2, section 5.8: TPM_KEY_USAGE values
+//
+///
+/// TPM_KEY_SIGNING SHALL indicate a signing key. The [private] key SHALL be
+/// used for signing operations, only. This means that it MUST be a leaf of the
+/// Protected Storage key hierarchy.
+///
+#define TPM_KEY_SIGNING ((UINT16) 0x0010)
+///
+/// TPM_KEY_STORAGE SHALL indicate a storage key. The key SHALL be used to wrap
+/// and unwrap other keys in the Protected Storage hierarchy
+///
+#define TPM_KEY_STORAGE ((UINT16) 0x0011)
+///
+/// TPM_KEY_IDENTITY SHALL indicate an identity key. The key SHALL be used for
+/// operations that require a TPM identity, only.
+///
+#define TPM_KEY_IDENTITY ((UINT16) 0x0012)
+///
+/// TPM_KEY_AUTHCHANGE SHALL indicate an ephemeral key that is in use during
+/// the ChangeAuthAsym process, only.
+///
+#define TPM_KEY_AUTHCHANGE ((UINT16) 0x0013)
+///
+/// TPM_KEY_BIND SHALL indicate a key that can be used for TPM_Bind and
+/// TPM_Unbind operations only.
+///
+#define TPM_KEY_BIND ((UINT16) 0x0014)
+///
+/// TPM_KEY_LEGACY SHALL indicate a key that can perform signing and binding
+/// operations. The key MAY be used for both signing and binding operations.
+/// The TPM_KEY_LEGACY key type is to allow for use by applications where both
+/// signing and encryption operations occur with the same key. The use of this
+/// key type is not recommended TPM_KEY_MIGRATE 0x0016 This SHALL indicate a
+/// key in use for TPM_MigrateKey
+///
+#define TPM_KEY_LEGACY ((UINT16) 0x0015)
+///
+/// TPM_KEY_MIGRAGE SHALL indicate a key in use for TPM_MigrateKey
+///
+#define TPM_KEY_MIGRATE ((UINT16) 0x0016)
+
+//
+// Part 2, section 5.8.1: Mandatory Key Usage Schemes
+//
+
+#define TPM_ES_NONE ((TPM_ENC_SCHEME) 0x0001)
+#define TPM_ES_RSAESPKCSv15 ((TPM_ENC_SCHEME) 0x0002)
+#define TPM_ES_RSAESOAEP_SHA1_MGF1 ((TPM_ENC_SCHEME) 0x0003)
+#define TPM_ES_SYM_CNT ((TPM_ENC_SCHEME) 0x0004) ///< rev94 defined
+#define TPM_ES_SYM_CTR ((TPM_ENC_SCHEME) 0x0004)
+#define TPM_ES_SYM_OFB ((TPM_ENC_SCHEME) 0x0005)
+
+#define TPM_SS_NONE ((TPM_SIG_SCHEME) 0x0001)
+#define TPM_SS_RSASSAPKCS1v15_SHA1 ((TPM_SIG_SCHEME) 0x0002)
+#define TPM_SS_RSASSAPKCS1v15_DER ((TPM_SIG_SCHEME) 0x0003)
+#define TPM_SS_RSASSAPKCS1v15_INFO ((TPM_SIG_SCHEME) 0x0004)
+
+//
+// Part 2, section 5.9: TPM_AUTH_DATA_USAGE values
+//
+#define TPM_AUTH_NEVER ((TPM_AUTH_DATA_USAGE) 0x00)
+#define TPM_AUTH_ALWAYS ((TPM_AUTH_DATA_USAGE) 0x01)
+#define TPM_AUTH_PRIV_USE_ONLY ((TPM_AUTH_DATA_USAGE) 0x03)
+
+///
+/// Part 2, section 5.10: TPM_KEY_FLAGS
+///
+typedef enum tdTPM_KEY_FLAGS {
+ redirection = 0x00000001,
+ migratable = 0x00000002,
+ isVolatile = 0x00000004,
+ pcrIgnoredOnRead = 0x00000008,
+ migrateAuthority = 0x00000010
+} TPM_KEY_FLAGS_BITS;
+
+///
+/// Part 2, section 5.11: TPM_CHANGEAUTH_VALIDATE
+///
+typedef struct tdTPM_CHANGEAUTH_VALIDATE {
+ TPM_SECRET newAuthSecret;
+ TPM_NONCE n1;
+} TPM_CHANGEAUTH_VALIDATE;
+
+///
+/// Part 2, section 5.12: TPM_MIGRATIONKEYAUTH
+/// declared after section 10 to catch declaration of TPM_PUBKEY
+///
+/// Part 2 section 10.1: TPM_KEY_PARMS
+/// [size_is(parmSize)] BYTE* parms;
+///
+typedef struct tdTPM_KEY_PARMS {
+ TPM_ALGORITHM_ID algorithmID;
+ TPM_ENC_SCHEME encScheme;
+ TPM_SIG_SCHEME sigScheme;
+ UINT32 parmSize;
+ UINT8 *parms;
+} TPM_KEY_PARMS;
+
+///
+/// Part 2, section 10.4: TPM_STORE_PUBKEY
+///
+typedef struct tdTPM_STORE_PUBKEY {
+ UINT32 keyLength;
+ UINT8 key[1];
+} TPM_STORE_PUBKEY;
+
+///
+/// Part 2, section 10.5: TPM_PUBKEY
+///
+typedef struct tdTPM_PUBKEY {
+ TPM_KEY_PARMS algorithmParms;
+ TPM_STORE_PUBKEY pubKey;
+} TPM_PUBKEY;
+
+///
+/// Part 2, section 5.12: TPM_MIGRATIONKEYAUTH
+///
+typedef struct tdTPM_MIGRATIONKEYAUTH {
+ TPM_PUBKEY migrationKey;
+ TPM_MIGRATE_SCHEME migrationScheme;
+ TPM_DIGEST digest;
+} TPM_MIGRATIONKEYAUTH;
+
+///
+/// Part 2, section 5.13: TPM_COUNTER_VALUE
+///
+typedef struct tdTPM_COUNTER_VALUE {
+ TPM_STRUCTURE_TAG tag;
+ UINT8 label[4];
+ TPM_ACTUAL_COUNT counter;
+} TPM_COUNTER_VALUE;
+
+///
+/// Part 2, section 5.14: TPM_SIGN_INFO
+/// Size of data indicated by dataLen
+///
+typedef struct tdTPM_SIGN_INFO {
+ TPM_STRUCTURE_TAG tag;
+ UINT8 fixed[4];
+ TPM_NONCE replay;
+ UINT32 dataLen;
+ UINT8 *data;
+} TPM_SIGN_INFO;
+
+///
+/// Part 2, section 5.15: TPM_MSA_COMPOSITE
+/// Number of migAuthDigest indicated by MSAlist
+///
+typedef struct tdTPM_MSA_COMPOSITE {
+ UINT32 MSAlist;
+ TPM_DIGEST migAuthDigest[1];
+} TPM_MSA_COMPOSITE;
+
+///
+/// Part 2, section 5.16: TPM_CMK_AUTH
+///
+typedef struct tdTPM_CMK_AUTH {
+ TPM_DIGEST migrationAuthorityDigest;
+ TPM_DIGEST destinationKeyDigest;
+ TPM_DIGEST sourceKeyDigest;
+} TPM_CMK_AUTH;
+
+//
+// Part 2, section 5.17: TPM_CMK_DELEGATE
+//
+#define TPM_CMK_DELEGATE_SIGNING ((TPM_CMK_DELEGATE) BIT31)
+#define TPM_CMK_DELEGATE_STORAGE ((TPM_CMK_DELEGATE) BIT30)
+#define TPM_CMK_DELEGATE_BIND ((TPM_CMK_DELEGATE) BIT29)
+#define TPM_CMK_DELEGATE_LEGACY ((TPM_CMK_DELEGATE) BIT28)
+#define TPM_CMK_DELEGATE_MIGRATE ((TPM_CMK_DELEGATE) BIT27)
+
+///
+/// Part 2, section 5.18: TPM_SELECT_SIZE
+///
+typedef struct tdTPM_SELECT_SIZE {
+ UINT8 major;
+ UINT8 minor;
+ UINT16 reqSize;
+} TPM_SELECT_SIZE;
+
+///
+/// Part 2, section 5,19: TPM_CMK_MIGAUTH
+///
+typedef struct tdTPM_CMK_MIGAUTH {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST msaDigest;
+ TPM_DIGEST pubKeyDigest;
+} TPM_CMK_MIGAUTH;
+
+///
+/// Part 2, section 5.20: TPM_CMK_SIGTICKET
+///
+typedef struct tdTPM_CMK_SIGTICKET {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST verKeyDigest;
+ TPM_DIGEST signedData;
+} TPM_CMK_SIGTICKET;
+
+///
+/// Part 2, section 5.21: TPM_CMK_MA_APPROVAL
+///
+typedef struct tdTPM_CMK_MA_APPROVAL {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST migrationAuthorityDigest;
+} TPM_CMK_MA_APPROVAL;
+
+//
+// Part 2, section 6: Command Tags
+//
+#define TPM_TAG_RQU_COMMAND ((TPM_STRUCTURE_TAG) 0x00C1)
+#define TPM_TAG_RQU_AUTH1_COMMAND ((TPM_STRUCTURE_TAG) 0x00C2)
+#define TPM_TAG_RQU_AUTH2_COMMAND ((TPM_STRUCTURE_TAG) 0x00C3)
+#define TPM_TAG_RSP_COMMAND ((TPM_STRUCTURE_TAG) 0x00C4)
+#define TPM_TAG_RSP_AUTH1_COMMAND ((TPM_STRUCTURE_TAG) 0x00C5)
+#define TPM_TAG_RSP_AUTH2_COMMAND ((TPM_STRUCTURE_TAG) 0x00C6)
+
+///
+/// Part 2, section 7.1: TPM_PERMANENT_FLAGS
+///
+typedef struct tdTPM_PERMANENT_FLAGS {
+ TPM_STRUCTURE_TAG tag;
+ BOOLEAN disable;
+ BOOLEAN ownership;
+ BOOLEAN deactivated;
+ BOOLEAN readPubek;
+ BOOLEAN disableOwnerClear;
+ BOOLEAN allowMaintenance;
+ BOOLEAN physicalPresenceLifetimeLock;
+ BOOLEAN physicalPresenceHWEnable;
+ BOOLEAN physicalPresenceCMDEnable;
+ BOOLEAN CEKPUsed;
+ BOOLEAN TPMpost;
+ BOOLEAN TPMpostLock;
+ BOOLEAN FIPS;
+ BOOLEAN operator_;
+ BOOLEAN enableRevokeEK;
+ BOOLEAN nvLocked;
+ BOOLEAN readSRKPub;
+ BOOLEAN tpmEstablished;
+ BOOLEAN maintenanceDone;
+ BOOLEAN disableFullDALogicInfo;
+} TPM_PERMANENT_FLAGS;
+
+//
+// Part 2, section 7.1.1: Flag Restrictions (of TPM_PERMANENT_FLAGS)
+//
+#define TPM_PF_DISABLE ((TPM_CAPABILITY_AREA) 1)
+#define TPM_PF_OWNERSHIP ((TPM_CAPABILITY_AREA) 2)
+#define TPM_PF_DEACTIVATED ((TPM_CAPABILITY_AREA) 3)
+#define TPM_PF_READPUBEK ((TPM_CAPABILITY_AREA) 4)
+#define TPM_PF_DISABLEOWNERCLEAR ((TPM_CAPABILITY_AREA) 5)
+#define TPM_PF_ALLOWMAINTENANCE ((TPM_CAPABILITY_AREA) 6)
+#define TPM_PF_PHYSICALPRESENCELIFETIMELOCK ((TPM_CAPABILITY_AREA) 7)
+#define TPM_PF_PHYSICALPRESENCEHWENABLE ((TPM_CAPABILITY_AREA) 8)
+#define TPM_PF_PHYSICALPRESENCECMDENABLE ((TPM_CAPABILITY_AREA) 9)
+#define TPM_PF_CEKPUSED ((TPM_CAPABILITY_AREA) 10)
+#define TPM_PF_TPMPOST ((TPM_CAPABILITY_AREA) 11)
+#define TPM_PF_TPMPOSTLOCK ((TPM_CAPABILITY_AREA) 12)
+#define TPM_PF_FIPS ((TPM_CAPABILITY_AREA) 13)
+#define TPM_PF_OPERATOR ((TPM_CAPABILITY_AREA) 14)
+#define TPM_PF_ENABLEREVOKEEK ((TPM_CAPABILITY_AREA) 15)
+#define TPM_PF_NV_LOCKED ((TPM_CAPABILITY_AREA) 16)
+#define TPM_PF_READSRKPUB ((TPM_CAPABILITY_AREA) 17)
+#define TPM_PF_TPMESTABLISHED ((TPM_CAPABILITY_AREA) 18)
+#define TPM_PF_MAINTENANCEDONE ((TPM_CAPABILITY_AREA) 19)
+#define TPM_PF_DISABLEFULLDALOGICINFO ((TPM_CAPABILITY_AREA) 20)
+
+///
+/// Part 2, section 7.2: TPM_STCLEAR_FLAGS
+///
+typedef struct tdTPM_STCLEAR_FLAGS {
+ TPM_STRUCTURE_TAG tag;
+ BOOLEAN deactivated;
+ BOOLEAN disableForceClear;
+ BOOLEAN physicalPresence;
+ BOOLEAN physicalPresenceLock;
+ BOOLEAN bGlobalLock;
+} TPM_STCLEAR_FLAGS;
+
+//
+// Part 2, section 7.2.1: Flag Restrictions (of TPM_STCLEAR_FLAGS)
+//
+#define TPM_SF_DEACTIVATED ((TPM_CAPABILITY_AREA) 1)
+#define TPM_SF_DISABLEFORCECLEAR ((TPM_CAPABILITY_AREA) 2)
+#define TPM_SF_PHYSICALPRESENCE ((TPM_CAPABILITY_AREA) 3)
+#define TPM_SF_PHYSICALPRESENCELOCK ((TPM_CAPABILITY_AREA) 4)
+#define TPM_SF_BGLOBALLOCK ((TPM_CAPABILITY_AREA) 5)
+
+///
+/// Part 2, section 7.3: TPM_STANY_FLAGS
+///
+typedef struct tdTPM_STANY_FLAGS {
+ TPM_STRUCTURE_TAG tag;
+ BOOLEAN postInitialise;
+ TPM_MODIFIER_INDICATOR localityModifier;
+ BOOLEAN transportExclusive;
+ BOOLEAN TOSPresent;
+} TPM_STANY_FLAGS;
+
+//
+// Part 2, section 7.3.1: Flag Restrictions (of TPM_STANY_FLAGS)
+//
+#define TPM_AF_POSTINITIALISE ((TPM_CAPABILITY_AREA) 1)
+#define TPM_AF_LOCALITYMODIFIER ((TPM_CAPABILITY_AREA) 2)
+#define TPM_AF_TRANSPORTEXCLUSIVE ((TPM_CAPABILITY_AREA) 3)
+#define TPM_AF_TOSPRESENT ((TPM_CAPABILITY_AREA) 4)
+
+//
+// All those structures defined in section 7.4, 7.5, 7.6 are not normative and
+// thus no definitions here
+//
+// Part 2, section 7.4: TPM_PERMANENT_DATA
+//
+#define TPM_MIN_COUNTERS 4 ///< the minimum number of counters is 4
+#define TPM_DELEGATE_KEY TPM_KEY
+#define TPM_NUM_PCR 16
+#define TPM_MAX_NV_WRITE_NOOWNER 64
+
+//
+// Part 2, section 7.4.1: PERMANENT_DATA Subcap for SetCapability
+//
+#define TPM_PD_REVMAJOR ((TPM_CAPABILITY_AREA) 1)
+#define TPM_PD_REVMINOR ((TPM_CAPABILITY_AREA) 2)
+#define TPM_PD_TPMPROOF ((TPM_CAPABILITY_AREA) 3)
+#define TPM_PD_OWNERAUTH ((TPM_CAPABILITY_AREA) 4)
+#define TPM_PD_OPERATORAUTH ((TPM_CAPABILITY_AREA) 5)
+#define TPM_PD_MANUMAINTPUB ((TPM_CAPABILITY_AREA) 6)
+#define TPM_PD_ENDORSEMENTKEY ((TPM_CAPABILITY_AREA) 7)
+#define TPM_PD_SRK ((TPM_CAPABILITY_AREA) 8)
+#define TPM_PD_DELEGATEKEY ((TPM_CAPABILITY_AREA) 9)
+#define TPM_PD_CONTEXTKEY ((TPM_CAPABILITY_AREA) 10)
+#define TPM_PD_AUDITMONOTONICCOUNTER ((TPM_CAPABILITY_AREA) 11)
+#define TPM_PD_MONOTONICCOUNTER ((TPM_CAPABILITY_AREA) 12)
+#define TPM_PD_PCRATTRIB ((TPM_CAPABILITY_AREA) 13)
+#define TPM_PD_ORDINALAUDITSTATUS ((TPM_CAPABILITY_AREA) 14)
+#define TPM_PD_AUTHDIR ((TPM_CAPABILITY_AREA) 15)
+#define TPM_PD_RNGSTATE ((TPM_CAPABILITY_AREA) 16)
+#define TPM_PD_FAMILYTABLE ((TPM_CAPABILITY_AREA) 17)
+#define TPM_DELEGATETABLE ((TPM_CAPABILITY_AREA) 18)
+#define TPM_PD_EKRESET ((TPM_CAPABILITY_AREA) 19)
+#define TPM_PD_MAXNVBUFSIZE ((TPM_CAPABILITY_AREA) 20)
+#define TPM_PD_LASTFAMILYID ((TPM_CAPABILITY_AREA) 21)
+#define TPM_PD_NOOWNERNVWRITE ((TPM_CAPABILITY_AREA) 22)
+#define TPM_PD_RESTRICTDELEGATE ((TPM_CAPABILITY_AREA) 23)
+#define TPM_PD_TPMDAASEED ((TPM_CAPABILITY_AREA) 24)
+#define TPM_PD_DAAPROOF ((TPM_CAPABILITY_AREA) 25)
+
+///
+/// Part 2, section 7.5: TPM_STCLEAR_DATA
+/// available inside TPM only
+///
+typedef struct tdTPM_STCLEAR_DATA {
+ TPM_STRUCTURE_TAG tag;
+ TPM_NONCE contextNonceKey;
+ TPM_COUNT_ID countID;
+ UINT32 ownerReference;
+ BOOLEAN disableResetLock;
+ TPM_PCRVALUE PCR[TPM_NUM_PCR];
+ UINT32 deferredPhysicalPresence;
+} TPM_STCLEAR_DATA;
+
+//
+// Part 2, section 7.5.1: STCLEAR_DATA Subcap for SetCapability
+//
+#define TPM_SD_CONTEXTNONCEKEY ((TPM_CAPABILITY_AREA)0x00000001)
+#define TPM_SD_COUNTID ((TPM_CAPABILITY_AREA)0x00000002)
+#define TPM_SD_OWNERREFERENCE ((TPM_CAPABILITY_AREA)0x00000003)
+#define TPM_SD_DISABLERESETLOCK ((TPM_CAPABILITY_AREA)0x00000004)
+#define TPM_SD_PCR ((TPM_CAPABILITY_AREA)0x00000005)
+#define TPM_SD_DEFERREDPHYSICALPRESENCE ((TPM_CAPABILITY_AREA)0x00000006)
+
+//
+// Part 2, section 7.6.1: STANY_DATA Subcap for SetCapability
+//
+#define TPM_AD_CONTEXTNONCESESSION ((TPM_CAPABILITY_AREA) 1)
+#define TPM_AD_AUDITDIGEST ((TPM_CAPABILITY_AREA) 2)
+#define TPM_AD_CURRENTTICKS ((TPM_CAPABILITY_AREA) 3)
+#define TPM_AD_CONTEXTCOUNT ((TPM_CAPABILITY_AREA) 4)
+#define TPM_AD_CONTEXTLIST ((TPM_CAPABILITY_AREA) 5)
+#define TPM_AD_SESSIONS ((TPM_CAPABILITY_AREA) 6)
+
+//
+// Part 2, section 8: PCR Structures
+//
+
+///
+/// Part 2, section 8.1: TPM_PCR_SELECTION
+/// Size of pcrSelect[] indicated by sizeOfSelect
+///
+typedef struct tdTPM_PCR_SELECTION {
+ UINT16 sizeOfSelect;
+ UINT8 pcrSelect[1];
+} TPM_PCR_SELECTION;
+
+///
+/// Part 2, section 8.2: TPM_PCR_COMPOSITE
+/// Size of pcrValue[] indicated by valueSize
+///
+typedef struct tdTPM_PCR_COMPOSITE {
+ TPM_PCR_SELECTION select;
+ UINT32 valueSize;
+ TPM_PCRVALUE pcrValue[1];
+} TPM_PCR_COMPOSITE;
+
+///
+/// Part 2, section 8.3: TPM_PCR_INFO
+///
+typedef struct tdTPM_PCR_INFO {
+ TPM_PCR_SELECTION pcrSelection;
+ TPM_COMPOSITE_HASH digestAtRelease;
+ TPM_COMPOSITE_HASH digestAtCreation;
+} TPM_PCR_INFO;
+
+///
+/// Part 2, section 8.6: TPM_LOCALITY_SELECTION
+///
+typedef UINT8 TPM_LOCALITY_SELECTION;
+
+#define TPM_LOC_FOUR ((UINT8) 0x10)
+#define TPM_LOC_THREE ((UINT8) 0x08)
+#define TPM_LOC_TWO ((UINT8) 0x04)
+#define TPM_LOC_ONE ((UINT8) 0x02)
+#define TPM_LOC_ZERO ((UINT8) 0x01)
+
+///
+/// Part 2, section 8.4: TPM_PCR_INFO_LONG
+///
+typedef struct tdTPM_PCR_INFO_LONG {
+ TPM_STRUCTURE_TAG tag;
+ TPM_LOCALITY_SELECTION localityAtCreation;
+ TPM_LOCALITY_SELECTION localityAtRelease;
+ TPM_PCR_SELECTION creationPCRSelection;
+ TPM_PCR_SELECTION releasePCRSelection;
+ TPM_COMPOSITE_HASH digestAtCreation;
+ TPM_COMPOSITE_HASH digestAtRelease;
+} TPM_PCR_INFO_LONG;
+
+///
+/// Part 2, section 8.5: TPM_PCR_INFO_SHORT
+///
+typedef struct tdTPM_PCR_INFO_SHORT {
+ TPM_PCR_SELECTION pcrSelection;
+ TPM_LOCALITY_SELECTION localityAtRelease;
+ TPM_COMPOSITE_HASH digestAtRelease;
+} TPM_PCR_INFO_SHORT;
+
+///
+/// Part 2, section 8.8: TPM_PCR_ATTRIBUTES
+///
+typedef struct tdTPM_PCR_ATTRIBUTES {
+ BOOLEAN pcrReset;
+ TPM_LOCALITY_SELECTION pcrExtendLocal;
+ TPM_LOCALITY_SELECTION pcrResetLocal;
+} TPM_PCR_ATTRIBUTES;
+
+//
+// Part 2, section 9: Storage Structures
+//
+
+///
+/// Part 2, section 9.1: TPM_STORED_DATA
+/// [size_is(sealInfoSize)] BYTE* sealInfo;
+/// [size_is(encDataSize)] BYTE* encData;
+///
+typedef struct tdTPM_STORED_DATA {
+ TPM_STRUCT_VER ver;
+ UINT32 sealInfoSize;
+ UINT8 *sealInfo;
+ UINT32 encDataSize;
+ UINT8 *encData;
+} TPM_STORED_DATA;
+
+///
+/// Part 2, section 9.2: TPM_STORED_DATA12
+/// [size_is(sealInfoSize)] BYTE* sealInfo;
+/// [size_is(encDataSize)] BYTE* encData;
+///
+typedef struct tdTPM_STORED_DATA12 {
+ TPM_STRUCTURE_TAG tag;
+ TPM_ENTITY_TYPE et;
+ UINT32 sealInfoSize;
+ UINT8 *sealInfo;
+ UINT32 encDataSize;
+ UINT8 *encData;
+} TPM_STORED_DATA12;
+
+///
+/// Part 2, section 9.3: TPM_SEALED_DATA
+/// [size_is(dataSize)] BYTE* data;
+///
+typedef struct tdTPM_SEALED_DATA {
+ TPM_PAYLOAD_TYPE payload;
+ TPM_SECRET authData;
+ TPM_NONCE tpmProof;
+ TPM_DIGEST storedDigest;
+ UINT32 dataSize;
+ UINT8 *data;
+} TPM_SEALED_DATA;
+
+///
+/// Part 2, section 9.4: TPM_SYMMETRIC_KEY
+/// [size_is(size)] BYTE* data;
+///
+typedef struct tdTPM_SYMMETRIC_KEY {
+ TPM_ALGORITHM_ID algId;
+ TPM_ENC_SCHEME encScheme;
+ UINT16 dataSize;
+ UINT8 *data;
+} TPM_SYMMETRIC_KEY;
+
+///
+/// Part 2, section 9.5: TPM_BOUND_DATA
+///
+typedef struct tdTPM_BOUND_DATA {
+ TPM_STRUCT_VER ver;
+ TPM_PAYLOAD_TYPE payload;
+ UINT8 payloadData[1];
+} TPM_BOUND_DATA;
+
+//
+// Part 2 section 10: TPM_KEY complex
+//
+
+//
+// Section 10.1, 10.4, and 10.5 have been defined previously
+//
+
+///
+/// Part 2, section 10.2: TPM_KEY
+/// [size_is(encDataSize)] BYTE* encData;
+///
+typedef struct tdTPM_KEY {
+ TPM_STRUCT_VER ver;
+ TPM_KEY_USAGE keyUsage;
+ TPM_KEY_FLAGS keyFlags;
+ TPM_AUTH_DATA_USAGE authDataUsage;
+ TPM_KEY_PARMS algorithmParms;
+ UINT32 PCRInfoSize;
+ UINT8 *PCRInfo;
+ TPM_STORE_PUBKEY pubKey;
+ UINT32 encDataSize;
+ UINT8 *encData;
+} TPM_KEY;
+
+///
+/// Part 2, section 10.3: TPM_KEY12
+/// [size_is(encDataSize)] BYTE* encData;
+///
+typedef struct tdTPM_KEY12 {
+ TPM_STRUCTURE_TAG tag;
+ UINT16 fill;
+ TPM_KEY_USAGE keyUsage;
+ TPM_KEY_FLAGS keyFlags;
+ TPM_AUTH_DATA_USAGE authDataUsage;
+ TPM_KEY_PARMS algorithmParms;
+ UINT32 PCRInfoSize;
+ UINT8 *PCRInfo;
+ TPM_STORE_PUBKEY pubKey;
+ UINT32 encDataSize;
+ UINT8 *encData;
+} TPM_KEY12;
+
+///
+/// Part 2, section 10.7: TPM_STORE_PRIVKEY
+/// [size_is(keyLength)] BYTE* key;
+///
+typedef struct tdTPM_STORE_PRIVKEY {
+ UINT32 keyLength;
+ UINT8 *key;
+} TPM_STORE_PRIVKEY;
+
+///
+/// Part 2, section 10.6: TPM_STORE_ASYMKEY
+///
+typedef struct tdTPM_STORE_ASYMKEY {
+ // pos len total
+ TPM_PAYLOAD_TYPE payload; // 0 1 1
+ TPM_SECRET usageAuth; // 1 20 21
+ TPM_SECRET migrationAuth; // 21 20 41
+ TPM_DIGEST pubDataDigest; // 41 20 61
+ TPM_STORE_PRIVKEY privKey; // 61 132-151 193-214
+} TPM_STORE_ASYMKEY;
+
+///
+/// Part 2, section 10.8: TPM_MIGRATE_ASYMKEY
+/// [size_is(partPrivKeyLen)] BYTE* partPrivKey;
+///
+typedef struct tdTPM_MIGRATE_ASYMKEY {
+ // pos len total
+ TPM_PAYLOAD_TYPE payload; // 0 1 1
+ TPM_SECRET usageAuth; // 1 20 21
+ TPM_DIGEST pubDataDigest; // 21 20 41
+ UINT32 partPrivKeyLen; // 41 4 45
+ UINT8 *partPrivKey; // 45 112-127 157-172
+} TPM_MIGRATE_ASYMKEY;
+
+///
+/// Part 2, section 10.9: TPM_KEY_CONTROL
+///
+#define TPM_KEY_CONTROL_OWNER_EVICT ((UINT32) 0x00000001)
+
+//
+// Part 2, section 11: Signed Structures
+//
+
+///
+/// Part 2, section 11.1: TPM_CERTIFY_INFO Structure
+///
+typedef struct tdTPM_CERTIFY_INFO {
+ TPM_STRUCT_VER version;
+ TPM_KEY_USAGE keyUsage;
+ TPM_KEY_FLAGS keyFlags;
+ TPM_AUTH_DATA_USAGE authDataUsage;
+ TPM_KEY_PARMS algorithmParms;
+ TPM_DIGEST pubkeyDigest;
+ TPM_NONCE data;
+ BOOLEAN parentPCRStatus;
+ UINT32 PCRInfoSize;
+ UINT8 *PCRInfo;
+} TPM_CERTIFY_INFO;
+
+///
+/// Part 2, section 11.2: TPM_CERTIFY_INFO2 Structure
+///
+typedef struct tdTPM_CERTIFY_INFO2 {
+ TPM_STRUCTURE_TAG tag;
+ UINT8 fill;
+ TPM_PAYLOAD_TYPE payloadType;
+ TPM_KEY_USAGE keyUsage;
+ TPM_KEY_FLAGS keyFlags;
+ TPM_AUTH_DATA_USAGE authDataUsage;
+ TPM_KEY_PARMS algorithmParms;
+ TPM_DIGEST pubkeyDigest;
+ TPM_NONCE data;
+ BOOLEAN parentPCRStatus;
+ UINT32 PCRInfoSize;
+ UINT8 *PCRInfo;
+ UINT32 migrationAuthoritySize;
+ UINT8 *migrationAuthority;
+} TPM_CERTIFY_INFO2;
+
+///
+/// Part 2, section 11.3 TPM_QUOTE_INFO Structure
+///
+typedef struct tdTPM_QUOTE_INFO {
+ TPM_STRUCT_VER version;
+ UINT8 fixed[4];
+ TPM_COMPOSITE_HASH digestValue;
+ TPM_NONCE externalData;
+} TPM_QUOTE_INFO;
+
+///
+/// Part 2, section 11.4 TPM_QUOTE_INFO2 Structure
+///
+typedef struct tdTPM_QUOTE_INFO2 {
+ TPM_STRUCTURE_TAG tag;
+ UINT8 fixed[4];
+ TPM_NONCE externalData;
+ TPM_PCR_INFO_SHORT infoShort;
+} TPM_QUOTE_INFO2;
+
+//
+// Part 2, section 12: Identity Structures
+//
+
+///
+/// Part 2, section 12.1 TPM_EK_BLOB
+///
+typedef struct tdTPM_EK_BLOB {
+ TPM_STRUCTURE_TAG tag;
+ TPM_EK_TYPE ekType;
+ UINT32 blobSize;
+ UINT8 *blob;
+} TPM_EK_BLOB;
+
+///
+/// Part 2, section 12.2 TPM_EK_BLOB_ACTIVATE
+///
+typedef struct tdTPM_EK_BLOB_ACTIVATE {
+ TPM_STRUCTURE_TAG tag;
+ TPM_SYMMETRIC_KEY sessionKey;
+ TPM_DIGEST idDigest;
+ TPM_PCR_INFO_SHORT pcrInfo;
+} TPM_EK_BLOB_ACTIVATE;
+
+///
+/// Part 2, section 12.3 TPM_EK_BLOB_AUTH
+///
+typedef struct tdTPM_EK_BLOB_AUTH {
+ TPM_STRUCTURE_TAG tag;
+ TPM_SECRET authValue;
+} TPM_EK_BLOB_AUTH;
+
+///
+/// Part 2, section 12.5 TPM_IDENTITY_CONTENTS
+///
+typedef struct tdTPM_IDENTITY_CONTENTS {
+ TPM_STRUCT_VER ver;
+ UINT32 ordinal;
+ TPM_CHOSENID_HASH labelPrivCADigest;
+ TPM_PUBKEY identityPubKey;
+} TPM_IDENTITY_CONTENTS;
+
+///
+/// Part 2, section 12.6 TPM_IDENTITY_REQ
+///
+typedef struct tdTPM_IDENTITY_REQ {
+ UINT32 asymSize;
+ UINT32 symSize;
+ TPM_KEY_PARMS asymAlgorithm;
+ TPM_KEY_PARMS symAlgorithm;
+ UINT8 *asymBlob;
+ UINT8 *symBlob;
+} TPM_IDENTITY_REQ;
+
+///
+/// Part 2, section 12.7 TPM_IDENTITY_PROOF
+///
+typedef struct tdTPM_IDENTITY_PROOF {
+ TPM_STRUCT_VER ver;
+ UINT32 labelSize;
+ UINT32 identityBindingSize;
+ UINT32 endorsementSize;
+ UINT32 platformSize;
+ UINT32 conformanceSize;
+ TPM_PUBKEY identityKey;
+ UINT8 *labelArea;
+ UINT8 *identityBinding;
+ UINT8 *endorsementCredential;
+ UINT8 *platformCredential;
+ UINT8 *conformanceCredential;
+} TPM_IDENTITY_PROOF;
+
+///
+/// Part 2, section 12.8 TPM_ASYM_CA_CONTENTS
+///
+typedef struct tdTPM_ASYM_CA_CONTENTS {
+ TPM_SYMMETRIC_KEY sessionKey;
+ TPM_DIGEST idDigest;
+} TPM_ASYM_CA_CONTENTS;
+
+///
+/// Part 2, section 12.9 TPM_SYM_CA_ATTESTATION
+///
+typedef struct tdTPM_SYM_CA_ATTESTATION {
+ UINT32 credSize;
+ TPM_KEY_PARMS algorithm;
+ UINT8 *credential;
+} TPM_SYM_CA_ATTESTATION;
+
+///
+/// Part 2, section 15: Tick Structures
+/// Placed here out of order because definitions are used in section 13.
+///
+typedef struct tdTPM_CURRENT_TICKS {
+ TPM_STRUCTURE_TAG tag;
+ UINT64 currentTicks;
+ UINT16 tickRate;
+ TPM_NONCE tickNonce;
+} TPM_CURRENT_TICKS;
+
+///
+/// Part 2, section 13: Transport structures
+///
+
+///
+/// Part 2, section 13.1: TPM _TRANSPORT_PUBLIC
+///
+typedef struct tdTPM_TRANSPORT_PUBLIC {
+ TPM_STRUCTURE_TAG tag;
+ TPM_TRANSPORT_ATTRIBUTES transAttributes;
+ TPM_ALGORITHM_ID algId;
+ TPM_ENC_SCHEME encScheme;
+} TPM_TRANSPORT_PUBLIC;
+
+//
+// Part 2, section 13.1.1 TPM_TRANSPORT_ATTRIBUTES Definitions
+//
+#define TPM_TRANSPORT_ENCRYPT ((UINT32)BIT0)
+#define TPM_TRANSPORT_LOG ((UINT32)BIT1)
+#define TPM_TRANSPORT_EXCLUSIVE ((UINT32)BIT2)
+
+///
+/// Part 2, section 13.2 TPM_TRANSPORT_INTERNAL
+///
+typedef struct tdTPM_TRANSPORT_INTERNAL {
+ TPM_STRUCTURE_TAG tag;
+ TPM_AUTHDATA authData;
+ TPM_TRANSPORT_PUBLIC transPublic;
+ TPM_TRANSHANDLE transHandle;
+ TPM_NONCE transNonceEven;
+ TPM_DIGEST transDigest;
+} TPM_TRANSPORT_INTERNAL;
+
+///
+/// Part 2, section 13.3 TPM_TRANSPORT_LOG_IN structure
+///
+typedef struct tdTPM_TRANSPORT_LOG_IN {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST parameters;
+ TPM_DIGEST pubKeyHash;
+} TPM_TRANSPORT_LOG_IN;
+
+///
+/// Part 2, section 13.4 TPM_TRANSPORT_LOG_OUT structure
+///
+typedef struct tdTPM_TRANSPORT_LOG_OUT {
+ TPM_STRUCTURE_TAG tag;
+ TPM_CURRENT_TICKS currentTicks;
+ TPM_DIGEST parameters;
+ TPM_MODIFIER_INDICATOR locality;
+} TPM_TRANSPORT_LOG_OUT;
+
+///
+/// Part 2, section 13.5 TPM_TRANSPORT_AUTH structure
+///
+typedef struct tdTPM_TRANSPORT_AUTH {
+ TPM_STRUCTURE_TAG tag;
+ TPM_AUTHDATA authData;
+} TPM_TRANSPORT_AUTH;
+
+//
+// Part 2, section 14: Audit Structures
+//
+
+///
+/// Part 2, section 14.1 TPM_AUDIT_EVENT_IN structure
+///
+typedef struct tdTPM_AUDIT_EVENT_IN {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST inputParms;
+ TPM_COUNTER_VALUE auditCount;
+} TPM_AUDIT_EVENT_IN;
+
+///
+/// Part 2, section 14.2 TPM_AUDIT_EVENT_OUT structure
+///
+typedef struct tdTPM_AUDIT_EVENT_OUT {
+ TPM_STRUCTURE_TAG tag;
+ TPM_COMMAND_CODE ordinal;
+ TPM_DIGEST outputParms;
+ TPM_COUNTER_VALUE auditCount;
+ TPM_RESULT returnCode;
+} TPM_AUDIT_EVENT_OUT;
+
+//
+// Part 2, section 16: Return Codes
+//
+
+#define TPM_VENDOR_ERROR TPM_Vendor_Specific32
+#define TPM_NON_FATAL 0x00000800
+
+#define TPM_SUCCESS ((TPM_RESULT) TPM_BASE)
+#define TPM_AUTHFAIL ((TPM_RESULT) (TPM_BASE + 1))
+#define TPM_BADINDEX ((TPM_RESULT) (TPM_BASE + 2))
+#define TPM_BAD_PARAMETER ((TPM_RESULT) (TPM_BASE + 3))
+#define TPM_AUDITFAILURE ((TPM_RESULT) (TPM_BASE + 4))
+#define TPM_CLEAR_DISABLED ((TPM_RESULT) (TPM_BASE + 5))
+#define TPM_DEACTIVATED ((TPM_RESULT) (TPM_BASE + 6))
+#define TPM_DISABLED ((TPM_RESULT) (TPM_BASE + 7))
+#define TPM_DISABLED_CMD ((TPM_RESULT) (TPM_BASE + 8))
+#define TPM_FAIL ((TPM_RESULT) (TPM_BASE + 9))
+#define TPM_BAD_ORDINAL ((TPM_RESULT) (TPM_BASE + 10))
+#define TPM_INSTALL_DISABLED ((TPM_RESULT) (TPM_BASE + 11))
+#define TPM_INVALID_KEYHANDLE ((TPM_RESULT) (TPM_BASE + 12))
+#define TPM_KEYNOTFOUND ((TPM_RESULT) (TPM_BASE + 13))
+#define TPM_INAPPROPRIATE_ENC ((TPM_RESULT) (TPM_BASE + 14))
+#define TPM_MIGRATEFAIL ((TPM_RESULT) (TPM_BASE + 15))
+#define TPM_INVALID_PCR_INFO ((TPM_RESULT) (TPM_BASE + 16))
+#define TPM_NOSPACE ((TPM_RESULT) (TPM_BASE + 17))
+#define TPM_NOSRK ((TPM_RESULT) (TPM_BASE + 18))
+#define TPM_NOTSEALED_BLOB ((TPM_RESULT) (TPM_BASE + 19))
+#define TPM_OWNER_SET ((TPM_RESULT) (TPM_BASE + 20))
+#define TPM_RESOURCES ((TPM_RESULT) (TPM_BASE + 21))
+#define TPM_SHORTRANDOM ((TPM_RESULT) (TPM_BASE + 22))
+#define TPM_SIZE ((TPM_RESULT) (TPM_BASE + 23))
+#define TPM_WRONGPCRVAL ((TPM_RESULT) (TPM_BASE + 24))
+#define TPM_BAD_PARAM_SIZE ((TPM_RESULT) (TPM_BASE + 25))
+#define TPM_SHA_THREAD ((TPM_RESULT) (TPM_BASE + 26))
+#define TPM_SHA_ERROR ((TPM_RESULT) (TPM_BASE + 27))
+#define TPM_FAILEDSELFTEST ((TPM_RESULT) (TPM_BASE + 28))
+#define TPM_AUTH2FAIL ((TPM_RESULT) (TPM_BASE + 29))
+#define TPM_BADTAG ((TPM_RESULT) (TPM_BASE + 30))
+#define TPM_IOERROR ((TPM_RESULT) (TPM_BASE + 31))
+#define TPM_ENCRYPT_ERROR ((TPM_RESULT) (TPM_BASE + 32))
+#define TPM_DECRYPT_ERROR ((TPM_RESULT) (TPM_BASE + 33))
+#define TPM_INVALID_AUTHHANDLE ((TPM_RESULT) (TPM_BASE + 34))
+#define TPM_NO_ENDORSEMENT ((TPM_RESULT) (TPM_BASE + 35))
+#define TPM_INVALID_KEYUSAGE ((TPM_RESULT) (TPM_BASE + 36))
+#define TPM_WRONG_ENTITYTYPE ((TPM_RESULT) (TPM_BASE + 37))
+#define TPM_INVALID_POSTINIT ((TPM_RESULT) (TPM_BASE + 38))
+#define TPM_INAPPROPRIATE_SIG ((TPM_RESULT) (TPM_BASE + 39))
+#define TPM_BAD_KEY_PROPERTY ((TPM_RESULT) (TPM_BASE + 40))
+#define TPM_BAD_MIGRATION ((TPM_RESULT) (TPM_BASE + 41))
+#define TPM_BAD_SCHEME ((TPM_RESULT) (TPM_BASE + 42))
+#define TPM_BAD_DATASIZE ((TPM_RESULT) (TPM_BASE + 43))
+#define TPM_BAD_MODE ((TPM_RESULT) (TPM_BASE + 44))
+#define TPM_BAD_PRESENCE ((TPM_RESULT) (TPM_BASE + 45))
+#define TPM_BAD_VERSION ((TPM_RESULT) (TPM_BASE + 46))
+#define TPM_NO_WRAP_TRANSPORT ((TPM_RESULT) (TPM_BASE + 47))
+#define TPM_AUDITFAIL_UNSUCCESSFUL ((TPM_RESULT) (TPM_BASE + 48))
+#define TPM_AUDITFAIL_SUCCESSFUL ((TPM_RESULT) (TPM_BASE + 49))
+#define TPM_NOTRESETABLE ((TPM_RESULT) (TPM_BASE + 50))
+#define TPM_NOTLOCAL ((TPM_RESULT) (TPM_BASE + 51))
+#define TPM_BAD_TYPE ((TPM_RESULT) (TPM_BASE + 52))
+#define TPM_INVALID_RESOURCE ((TPM_RESULT) (TPM_BASE + 53))
+#define TPM_NOTFIPS ((TPM_RESULT) (TPM_BASE + 54))
+#define TPM_INVALID_FAMILY ((TPM_RESULT) (TPM_BASE + 55))
+#define TPM_NO_NV_PERMISSION ((TPM_RESULT) (TPM_BASE + 56))
+#define TPM_REQUIRES_SIGN ((TPM_RESULT) (TPM_BASE + 57))
+#define TPM_KEY_NOTSUPPORTED ((TPM_RESULT) (TPM_BASE + 58))
+#define TPM_AUTH_CONFLICT ((TPM_RESULT) (TPM_BASE + 59))
+#define TPM_AREA_LOCKED ((TPM_RESULT) (TPM_BASE + 60))
+#define TPM_BAD_LOCALITY ((TPM_RESULT) (TPM_BASE + 61))
+#define TPM_READ_ONLY ((TPM_RESULT) (TPM_BASE + 62))
+#define TPM_PER_NOWRITE ((TPM_RESULT) (TPM_BASE + 63))
+#define TPM_FAMILYCOUNT ((TPM_RESULT) (TPM_BASE + 64))
+#define TPM_WRITE_LOCKED ((TPM_RESULT) (TPM_BASE + 65))
+#define TPM_BAD_ATTRIBUTES ((TPM_RESULT) (TPM_BASE + 66))
+#define TPM_INVALID_STRUCTURE ((TPM_RESULT) (TPM_BASE + 67))
+#define TPM_KEY_OWNER_CONTROL ((TPM_RESULT) (TPM_BASE + 68))
+#define TPM_BAD_COUNTER ((TPM_RESULT) (TPM_BASE + 69))
+#define TPM_NOT_FULLWRITE ((TPM_RESULT) (TPM_BASE + 70))
+#define TPM_CONTEXT_GAP ((TPM_RESULT) (TPM_BASE + 71))
+#define TPM_MAXNVWRITES ((TPM_RESULT) (TPM_BASE + 72))
+#define TPM_NOOPERATOR ((TPM_RESULT) (TPM_BASE + 73))
+#define TPM_RESOURCEMISSING ((TPM_RESULT) (TPM_BASE + 74))
+#define TPM_DELEGATE_LOCK ((TPM_RESULT) (TPM_BASE + 75))
+#define TPM_DELEGATE_FAMILY ((TPM_RESULT) (TPM_BASE + 76))
+#define TPM_DELEGATE_ADMIN ((TPM_RESULT) (TPM_BASE + 77))
+#define TPM_TRANSPORT_NOTEXCLUSIVE ((TPM_RESULT) (TPM_BASE + 78))
+#define TPM_OWNER_CONTROL ((TPM_RESULT) (TPM_BASE + 79))
+#define TPM_DAA_RESOURCES ((TPM_RESULT) (TPM_BASE + 80))
+#define TPM_DAA_INPUT_DATA0 ((TPM_RESULT) (TPM_BASE + 81))
+#define TPM_DAA_INPUT_DATA1 ((TPM_RESULT) (TPM_BASE + 82))
+#define TPM_DAA_ISSUER_SETTINGS ((TPM_RESULT) (TPM_BASE + 83))
+#define TPM_DAA_TPM_SETTINGS ((TPM_RESULT) (TPM_BASE + 84))
+#define TPM_DAA_STAGE ((TPM_RESULT) (TPM_BASE + 85))
+#define TPM_DAA_ISSUER_VALIDITY ((TPM_RESULT) (TPM_BASE + 86))
+#define TPM_DAA_WRONG_W ((TPM_RESULT) (TPM_BASE + 87))
+#define TPM_BAD_HANDLE ((TPM_RESULT) (TPM_BASE + 88))
+#define TPM_BAD_DELEGATE ((TPM_RESULT) (TPM_BASE + 89))
+#define TPM_BADCONTEXT ((TPM_RESULT) (TPM_BASE + 90))
+#define TPM_TOOMANYCONTEXTS ((TPM_RESULT) (TPM_BASE + 91))
+#define TPM_MA_TICKET_SIGNATURE ((TPM_RESULT) (TPM_BASE + 92))
+#define TPM_MA_DESTINATION ((TPM_RESULT) (TPM_BASE + 93))
+#define TPM_MA_SOURCE ((TPM_RESULT) (TPM_BASE + 94))
+#define TPM_MA_AUTHORITY ((TPM_RESULT) (TPM_BASE + 95))
+#define TPM_PERMANENTEK ((TPM_RESULT) (TPM_BASE + 97))
+#define TPM_BAD_SIGNATURE ((TPM_RESULT) (TPM_BASE + 98))
+#define TPM_NOCONTEXTSPACE ((TPM_RESULT) (TPM_BASE + 99))
+
+#define TPM_RETRY ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL))
+#define TPM_NEEDS_SELFTEST ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL + 1))
+#define TPM_DOING_SELFTEST ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL + 2))
+#define TPM_DEFEND_LOCK_RUNNING ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL + 3))
+
+//
+// Part 2, section 17: Ordinals
+//
+// Ordinals are 32 bit values. The upper byte contains values that serve as
+// flag indicators, the next byte contains values indicating what committee
+// designated the ordinal, and the final two bytes contain the Command
+// Ordinal Index.
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |P|C|V| Reserved| Purview | Command Ordinal Index |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+// Where:
+//
+// * P is Protected/Unprotected command. When 0 the command is a Protected
+// command, when 1 the command is an Unprotected command.
+//
+// * C is Non-Connection/Connection related command. When 0 this command
+// passes through to either the protected (TPM) or unprotected (TSS)
+// components.
+//
+// * V is TPM/Vendor command. When 0 the command is TPM defined, when 1 the
+// command is vendor defined.
+//
+// * All reserved area bits are set to 0.
+//
+
+#define TPM_ORD_ActivateIdentity ((TPM_COMMAND_CODE) 0x0000007A)
+#define TPM_ORD_AuthorizeMigrationKey ((TPM_COMMAND_CODE) 0x0000002B)
+#define TPM_ORD_CertifyKey ((TPM_COMMAND_CODE) 0x00000032)
+#define TPM_ORD_CertifyKey2 ((TPM_COMMAND_CODE) 0x00000033)
+#define TPM_ORD_CertifySelfTest ((TPM_COMMAND_CODE) 0x00000052)
+#define TPM_ORD_ChangeAuth ((TPM_COMMAND_CODE) 0x0000000C)
+#define TPM_ORD_ChangeAuthAsymFinish ((TPM_COMMAND_CODE) 0x0000000F)
+#define TPM_ORD_ChangeAuthAsymStart ((TPM_COMMAND_CODE) 0x0000000E)
+#define TPM_ORD_ChangeAuthOwner ((TPM_COMMAND_CODE) 0x00000010)
+#define TPM_ORD_CMK_ApproveMA ((TPM_COMMAND_CODE) 0x0000001D)
+#define TPM_ORD_CMK_ConvertMigration ((TPM_COMMAND_CODE) 0x00000024)
+#define TPM_ORD_CMK_CreateBlob ((TPM_COMMAND_CODE) 0x0000001B)
+#define TPM_ORD_CMK_CreateKey ((TPM_COMMAND_CODE) 0x00000013)
+#define TPM_ORD_CMK_CreateTicket ((TPM_COMMAND_CODE) 0x00000012)
+#define TPM_ORD_CMK_SetRestrictions ((TPM_COMMAND_CODE) 0x0000001C)
+#define TPM_ORD_ContinueSelfTest ((TPM_COMMAND_CODE) 0x00000053)
+#define TPM_ORD_ConvertMigrationBlob ((TPM_COMMAND_CODE) 0x0000002A)
+#define TPM_ORD_CreateCounter ((TPM_COMMAND_CODE) 0x000000DC)
+#define TPM_ORD_CreateEndorsementKeyPair ((TPM_COMMAND_CODE) 0x00000078)
+#define TPM_ORD_CreateMaintenanceArchive ((TPM_COMMAND_CODE) 0x0000002C)
+#define TPM_ORD_CreateMigrationBlob ((TPM_COMMAND_CODE) 0x00000028)
+#define TPM_ORD_CreateRevocableEK ((TPM_COMMAND_CODE) 0x0000007F)
+#define TPM_ORD_CreateWrapKey ((TPM_COMMAND_CODE) 0x0000001F)
+#define TPM_ORD_DAA_JOIN ((TPM_COMMAND_CODE) 0x00000029)
+#define TPM_ORD_DAA_SIGN ((TPM_COMMAND_CODE) 0x00000031)
+#define TPM_ORD_Delegate_CreateKeyDelegation ((TPM_COMMAND_CODE) 0x000000D4)
+#define TPM_ORD_Delegate_CreateOwnerDelegation ((TPM_COMMAND_CODE) 0x000000D5)
+#define TPM_ORD_Delegate_LoadOwnerDelegation ((TPM_COMMAND_CODE) 0x000000D8)
+#define TPM_ORD_Delegate_Manage ((TPM_COMMAND_CODE) 0x000000D2)
+#define TPM_ORD_Delegate_ReadTable ((TPM_COMMAND_CODE) 0x000000DB)
+#define TPM_ORD_Delegate_UpdateVerification ((TPM_COMMAND_CODE) 0x000000D1)
+#define TPM_ORD_Delegate_VerifyDelegation ((TPM_COMMAND_CODE) 0x000000D6)
+#define TPM_ORD_DirRead ((TPM_COMMAND_CODE) 0x0000001A)
+#define TPM_ORD_DirWriteAuth ((TPM_COMMAND_CODE) 0x00000019)
+#define TPM_ORD_DisableForceClear ((TPM_COMMAND_CODE) 0x0000005E)
+#define TPM_ORD_DisableOwnerClear ((TPM_COMMAND_CODE) 0x0000005C)
+#define TPM_ORD_DisablePubekRead ((TPM_COMMAND_CODE) 0x0000007E)
+#define TPM_ORD_DSAP ((TPM_COMMAND_CODE) 0x00000011)
+#define TPM_ORD_EstablishTransport ((TPM_COMMAND_CODE) 0x000000E6)
+#define TPM_ORD_EvictKey ((TPM_COMMAND_CODE) 0x00000022)
+#define TPM_ORD_ExecuteTransport ((TPM_COMMAND_CODE) 0x000000E7)
+#define TPM_ORD_Extend ((TPM_COMMAND_CODE) 0x00000014)
+#define TPM_ORD_FieldUpgrade ((TPM_COMMAND_CODE) 0x000000AA)
+#define TPM_ORD_FlushSpecific ((TPM_COMMAND_CODE) 0x000000BA)
+#define TPM_ORD_ForceClear ((TPM_COMMAND_CODE) 0x0000005D)
+#define TPM_ORD_GetAuditDigest ((TPM_COMMAND_CODE) 0x00000085)
+#define TPM_ORD_GetAuditDigestSigned ((TPM_COMMAND_CODE) 0x00000086)
+#define TPM_ORD_GetAuditEvent ((TPM_COMMAND_CODE) 0x00000082)
+#define TPM_ORD_GetAuditEventSigned ((TPM_COMMAND_CODE) 0x00000083)
+#define TPM_ORD_GetCapability ((TPM_COMMAND_CODE) 0x00000065)
+#define TPM_ORD_GetCapabilityOwner ((TPM_COMMAND_CODE) 0x00000066)
+#define TPM_ORD_GetCapabilitySigned ((TPM_COMMAND_CODE) 0x00000064)
+#define TPM_ORD_GetOrdinalAuditStatus ((TPM_COMMAND_CODE) 0x0000008C)
+#define TPM_ORD_GetPubKey ((TPM_COMMAND_CODE) 0x00000021)
+#define TPM_ORD_GetRandom ((TPM_COMMAND_CODE) 0x00000046)
+#define TPM_ORD_GetTestResult ((TPM_COMMAND_CODE) 0x00000054)
+#define TPM_ORD_GetTicks ((TPM_COMMAND_CODE) 0x000000F1)
+#define TPM_ORD_IncrementCounter ((TPM_COMMAND_CODE) 0x000000DD)
+#define TPM_ORD_Init ((TPM_COMMAND_CODE) 0x00000097)
+#define TPM_ORD_KeyControlOwner ((TPM_COMMAND_CODE) 0x00000023)
+#define TPM_ORD_KillMaintenanceFeature ((TPM_COMMAND_CODE) 0x0000002E)
+#define TPM_ORD_LoadAuthContext ((TPM_COMMAND_CODE) 0x000000B7)
+#define TPM_ORD_LoadContext ((TPM_COMMAND_CODE) 0x000000B9)
+#define TPM_ORD_LoadKey ((TPM_COMMAND_CODE) 0x00000020)
+#define TPM_ORD_LoadKey2 ((TPM_COMMAND_CODE) 0x00000041)
+#define TPM_ORD_LoadKeyContext ((TPM_COMMAND_CODE) 0x000000B5)
+#define TPM_ORD_LoadMaintenanceArchive ((TPM_COMMAND_CODE) 0x0000002D)
+#define TPM_ORD_LoadManuMaintPub ((TPM_COMMAND_CODE) 0x0000002F)
+#define TPM_ORD_MakeIdentity ((TPM_COMMAND_CODE) 0x00000079)
+#define TPM_ORD_MigrateKey ((TPM_COMMAND_CODE) 0x00000025)
+#define TPM_ORD_NV_DefineSpace ((TPM_COMMAND_CODE) 0x000000CC)
+#define TPM_ORD_NV_ReadValue ((TPM_COMMAND_CODE) 0x000000CF)
+#define TPM_ORD_NV_ReadValueAuth ((TPM_COMMAND_CODE) 0x000000D0)
+#define TPM_ORD_NV_WriteValue ((TPM_COMMAND_CODE) 0x000000CD)
+#define TPM_ORD_NV_WriteValueAuth ((TPM_COMMAND_CODE) 0x000000CE)
+#define TPM_ORD_OIAP ((TPM_COMMAND_CODE) 0x0000000A)
+#define TPM_ORD_OSAP ((TPM_COMMAND_CODE) 0x0000000B)
+#define TPM_ORD_OwnerClear ((TPM_COMMAND_CODE) 0x0000005B)
+#define TPM_ORD_OwnerReadInternalPub ((TPM_COMMAND_CODE) 0x00000081)
+#define TPM_ORD_OwnerReadPubek ((TPM_COMMAND_CODE) 0x0000007D)
+#define TPM_ORD_OwnerSetDisable ((TPM_COMMAND_CODE) 0x0000006E)
+#define TPM_ORD_PCR_Reset ((TPM_COMMAND_CODE) 0x000000C8)
+#define TPM_ORD_PcrRead ((TPM_COMMAND_CODE) 0x00000015)
+#define TPM_ORD_PhysicalDisable ((TPM_COMMAND_CODE) 0x00000070)
+#define TPM_ORD_PhysicalEnable ((TPM_COMMAND_CODE) 0x0000006F)
+#define TPM_ORD_PhysicalSetDeactivated ((TPM_COMMAND_CODE) 0x00000072)
+#define TPM_ORD_Quote ((TPM_COMMAND_CODE) 0x00000016)
+#define TPM_ORD_Quote2 ((TPM_COMMAND_CODE) 0x0000003E)
+#define TPM_ORD_ReadCounter ((TPM_COMMAND_CODE) 0x000000DE)
+#define TPM_ORD_ReadManuMaintPub ((TPM_COMMAND_CODE) 0x00000030)
+#define TPM_ORD_ReadPubek ((TPM_COMMAND_CODE) 0x0000007C)
+#define TPM_ORD_ReleaseCounter ((TPM_COMMAND_CODE) 0x000000DF)
+#define TPM_ORD_ReleaseCounterOwner ((TPM_COMMAND_CODE) 0x000000E0)
+#define TPM_ORD_ReleaseTransportSigned ((TPM_COMMAND_CODE) 0x000000E8)
+#define TPM_ORD_Reset ((TPM_COMMAND_CODE) 0x0000005A)
+#define TPM_ORD_ResetLockValue ((TPM_COMMAND_CODE) 0x00000040)
+#define TPM_ORD_RevokeTrust ((TPM_COMMAND_CODE) 0x00000080)
+#define TPM_ORD_SaveAuthContext ((TPM_COMMAND_CODE) 0x000000B6)
+#define TPM_ORD_SaveContext ((TPM_COMMAND_CODE) 0x000000B8)
+#define TPM_ORD_SaveKeyContext ((TPM_COMMAND_CODE) 0x000000B4)
+#define TPM_ORD_SaveState ((TPM_COMMAND_CODE) 0x00000098)
+#define TPM_ORD_Seal ((TPM_COMMAND_CODE) 0x00000017)
+#define TPM_ORD_Sealx ((TPM_COMMAND_CODE) 0x0000003D)
+#define TPM_ORD_SelfTestFull ((TPM_COMMAND_CODE) 0x00000050)
+#define TPM_ORD_SetCapability ((TPM_COMMAND_CODE) 0x0000003F)
+#define TPM_ORD_SetOperatorAuth ((TPM_COMMAND_CODE) 0x00000074)
+#define TPM_ORD_SetOrdinalAuditStatus ((TPM_COMMAND_CODE) 0x0000008D)
+#define TPM_ORD_SetOwnerInstall ((TPM_COMMAND_CODE) 0x00000071)
+#define TPM_ORD_SetOwnerPointer ((TPM_COMMAND_CODE) 0x00000075)
+#define TPM_ORD_SetRedirection ((TPM_COMMAND_CODE) 0x0000009A)
+#define TPM_ORD_SetTempDeactivated ((TPM_COMMAND_CODE) 0x00000073)
+#define TPM_ORD_SHA1Complete ((TPM_COMMAND_CODE) 0x000000A2)
+#define TPM_ORD_SHA1CompleteExtend ((TPM_COMMAND_CODE) 0x000000A3)
+#define TPM_ORD_SHA1Start ((TPM_COMMAND_CODE) 0x000000A0)
+#define TPM_ORD_SHA1Update ((TPM_COMMAND_CODE) 0x000000A1)
+#define TPM_ORD_Sign ((TPM_COMMAND_CODE) 0x0000003C)
+#define TPM_ORD_Startup ((TPM_COMMAND_CODE) 0x00000099)
+#define TPM_ORD_StirRandom ((TPM_COMMAND_CODE) 0x00000047)
+#define TPM_ORD_TakeOwnership ((TPM_COMMAND_CODE) 0x0000000D)
+#define TPM_ORD_Terminate_Handle ((TPM_COMMAND_CODE) 0x00000096)
+#define TPM_ORD_TickStampBlob ((TPM_COMMAND_CODE) 0x000000F2)
+#define TPM_ORD_UnBind ((TPM_COMMAND_CODE) 0x0000001E)
+#define TPM_ORD_Unseal ((TPM_COMMAND_CODE) 0x00000018)
+#define TSC_ORD_PhysicalPresence ((TPM_COMMAND_CODE) 0x4000000A)
+#define TSC_ORD_ResetEstablishmentBit ((TPM_COMMAND_CODE) 0x4000000B)
+
+//
+// Part 2, section 18: Context structures
+//
+
+///
+/// Part 2, section 18.1: TPM_CONTEXT_BLOB
+///
+typedef struct tdTPM_CONTEXT_BLOB {
+ TPM_STRUCTURE_TAG tag;
+ TPM_RESOURCE_TYPE resourceType;
+ TPM_HANDLE handle;
+ UINT8 label[16];
+ UINT32 contextCount;
+ TPM_DIGEST integrityDigest;
+ UINT32 additionalSize;
+ UINT8 *additionalData;
+ UINT32 sensitiveSize;
+ UINT8 *sensitiveData;
+} TPM_CONTEXT_BLOB;
+
+///
+/// Part 2, section 18.2 TPM_CONTEXT_SENSITIVE
+///
+typedef struct tdTPM_CONTEXT_SENSITIVE {
+ TPM_STRUCTURE_TAG tag;
+ TPM_NONCE contextNonce;
+ UINT32 internalSize;
+ UINT8 *internalData;
+} TPM_CONTEXT_SENSITIVE;
+
+//
+// Part 2, section 19: NV Structures
+//
+
+//
+// Part 2, section 19.1.1: Required TPM_NV_INDEX values
+//
+#define TPM_NV_INDEX_LOCK ((UINT32)0xffffffff)
+#define TPM_NV_INDEX0 ((UINT32)0x00000000)
+#define TPM_NV_INDEX_DIR ((UINT32)0x10000001)
+#define TPM_NV_INDEX_EKCert ((UINT32)0x0000f000)
+#define TPM_NV_INDEX_TPM_CC ((UINT32)0x0000f001)
+#define TPM_NV_INDEX_PlatformCert ((UINT32)0x0000f002)
+#define TPM_NV_INDEX_Platform_CC ((UINT32)0x0000f003)
+//
+// Part 2, section 19.1.2: Reserved Index values
+//
+#define TPM_NV_INDEX_TSS_BASE ((UINT32)0x00011100)
+#define TPM_NV_INDEX_PC_BASE ((UINT32)0x00011200)
+#define TPM_NV_INDEX_SERVER_BASE ((UINT32)0x00011300)
+#define TPM_NV_INDEX_MOBILE_BASE ((UINT32)0x00011400)
+#define TPM_NV_INDEX_PERIPHERAL_BASE ((UINT32)0x00011500)
+#define TPM_NV_INDEX_GROUP_RESV_BASE ((UINT32)0x00010000)
+
+///
+/// Part 2, section 19.2: TPM_NV_ATTRIBUTES
+///
+typedef struct tdTPM_NV_ATTRIBUTES {
+ TPM_STRUCTURE_TAG tag;
+ UINT32 attributes;
+} TPM_NV_ATTRIBUTES;
+
+#define TPM_NV_PER_READ_STCLEAR (BIT31)
+#define TPM_NV_PER_AUTHREAD (BIT18)
+#define TPM_NV_PER_OWNERREAD (BIT17)
+#define TPM_NV_PER_PPREAD (BIT16)
+#define TPM_NV_PER_GLOBALLOCK (BIT15)
+#define TPM_NV_PER_WRITE_STCLEAR (BIT14)
+#define TPM_NV_PER_WRITEDEFINE (BIT13)
+#define TPM_NV_PER_WRITEALL (BIT12)
+#define TPM_NV_PER_AUTHWRITE (BIT2)
+#define TPM_NV_PER_OWNERWRITE (BIT1)
+#define TPM_NV_PER_PPWRITE (BIT0)
+
+///
+/// Part 2, section 19.3: TPM_NV_DATA_PUBLIC
+///
+typedef struct tdTPM_NV_DATA_PUBLIC {
+ TPM_STRUCTURE_TAG tag;
+ TPM_NV_INDEX nvIndex;
+ TPM_PCR_INFO_SHORT pcrInfoRead;
+ TPM_PCR_INFO_SHORT pcrInfoWrite;
+ TPM_NV_ATTRIBUTES permission;
+ BOOLEAN bReadSTClear;
+ BOOLEAN bWriteSTClear;
+ BOOLEAN bWriteDefine;
+ UINT32 dataSize;
+} TPM_NV_DATA_PUBLIC;
+
+//
+// Part 2, section 20: Delegate Structures
+//
+
+#define TPM_DEL_OWNER_BITS ((UINT32)0x00000001)
+#define TPM_DEL_KEY_BITS ((UINT32)0x00000002)
+///
+/// Part 2, section 20.2: Delegate Definitions
+///
+typedef struct tdTPM_DELEGATIONS {
+ TPM_STRUCTURE_TAG tag;
+ UINT32 delegateType;
+ UINT32 per1;
+ UINT32 per2;
+} TPM_DELEGATIONS;
+
+//
+// Part 2, section 20.2.1: Owner Permission Settings
+//
+#define TPM_DELEGATE_SetOrdinalAuditStatus (BIT30)
+#define TPM_DELEGATE_DirWriteAuth (BIT29)
+#define TPM_DELEGATE_CMK_ApproveMA (BIT28)
+#define TPM_DELEGATE_NV_WriteValue (BIT27)
+#define TPM_DELEGATE_CMK_CreateTicket (BIT26)
+#define TPM_DELEGATE_NV_ReadValue (BIT25)
+#define TPM_DELEGATE_Delegate_LoadOwnerDelegation (BIT24)
+#define TPM_DELEGATE_DAA_Join (BIT23)
+#define TPM_DELEGATE_AuthorizeMigrationKey (BIT22)
+#define TPM_DELEGATE_CreateMaintenanceArchive (BIT21)
+#define TPM_DELEGATE_LoadMaintenanceArchive (BIT20)
+#define TPM_DELEGATE_KillMaintenanceFeature (BIT19)
+#define TPM_DELEGATE_OwnerReadInteralPub (BIT18)
+#define TPM_DELEGATE_ResetLockValue (BIT17)
+#define TPM_DELEGATE_OwnerClear (BIT16)
+#define TPM_DELEGATE_DisableOwnerClear (BIT15)
+#define TPM_DELEGATE_NV_DefineSpace (BIT14)
+#define TPM_DELEGATE_OwnerSetDisable (BIT13)
+#define TPM_DELEGATE_SetCapability (BIT12)
+#define TPM_DELEGATE_MakeIdentity (BIT11)
+#define TPM_DELEGATE_ActivateIdentity (BIT10)
+#define TPM_DELEGATE_OwnerReadPubek (BIT9)
+#define TPM_DELEGATE_DisablePubekRead (BIT8)
+#define TPM_DELEGATE_SetRedirection (BIT7)
+#define TPM_DELEGATE_FieldUpgrade (BIT6)
+#define TPM_DELEGATE_Delegate_UpdateVerification (BIT5)
+#define TPM_DELEGATE_CreateCounter (BIT4)
+#define TPM_DELEGATE_ReleaseCounterOwner (BIT3)
+#define TPM_DELEGATE_DelegateManage (BIT2)
+#define TPM_DELEGATE_Delegate_CreateOwnerDelegation (BIT1)
+#define TPM_DELEGATE_DAA_Sign (BIT0)
+
+//
+// Part 2, section 20.2.3: Key Permission settings
+//
+#define TPM_KEY_DELEGATE_CMK_ConvertMigration (BIT28)
+#define TPM_KEY_DELEGATE_TickStampBlob (BIT27)
+#define TPM_KEY_DELEGATE_ChangeAuthAsymStart (BIT26)
+#define TPM_KEY_DELEGATE_ChangeAuthAsymFinish (BIT25)
+#define TPM_KEY_DELEGATE_CMK_CreateKey (BIT24)
+#define TPM_KEY_DELEGATE_MigrateKey (BIT23)
+#define TPM_KEY_DELEGATE_LoadKey2 (BIT22)
+#define TPM_KEY_DELEGATE_EstablishTransport (BIT21)
+#define TPM_KEY_DELEGATE_ReleaseTransportSigned (BIT20)
+#define TPM_KEY_DELEGATE_Quote2 (BIT19)
+#define TPM_KEY_DELEGATE_Sealx (BIT18)
+#define TPM_KEY_DELEGATE_MakeIdentity (BIT17)
+#define TPM_KEY_DELEGATE_ActivateIdentity (BIT16)
+#define TPM_KEY_DELEGATE_GetAuditDigestSigned (BIT15)
+#define TPM_KEY_DELEGATE_Sign (BIT14)
+#define TPM_KEY_DELEGATE_CertifyKey2 (BIT13)
+#define TPM_KEY_DELEGATE_CertifyKey (BIT12)
+#define TPM_KEY_DELEGATE_CreateWrapKey (BIT11)
+#define TPM_KEY_DELEGATE_CMK_CreateBlob (BIT10)
+#define TPM_KEY_DELEGATE_CreateMigrationBlob (BIT9)
+#define TPM_KEY_DELEGATE_ConvertMigrationBlob (BIT8)
+#define TPM_KEY_DELEGATE_CreateKeyDelegation (BIT7)
+#define TPM_KEY_DELEGATE_ChangeAuth (BIT6)
+#define TPM_KEY_DELEGATE_GetPubKey (BIT5)
+#define TPM_KEY_DELEGATE_UnBind (BIT4)
+#define TPM_KEY_DELEGATE_Quote (BIT3)
+#define TPM_KEY_DELEGATE_Unseal (BIT2)
+#define TPM_KEY_DELEGATE_Seal (BIT1)
+#define TPM_KEY_DELEGATE_LoadKey (BIT0)
+
+//
+// Part 2, section 20.3: TPM_FAMILY_FLAGS
+//
+#define TPM_DELEGATE_ADMIN_LOCK (BIT1)
+#define TPM_FAMFLAG_ENABLE (BIT0)
+
+///
+/// Part 2, section 20.4: TPM_FAMILY_LABEL
+///
+typedef struct tdTPM_FAMILY_LABEL {
+ UINT8 label;
+} TPM_FAMILY_LABEL;
+
+///
+/// Part 2, section 20.5: TPM_FAMILY_TABLE_ENTRY
+///
+typedef struct tdTPM_FAMILY_TABLE_ENTRY {
+ TPM_STRUCTURE_TAG tag;
+ TPM_FAMILY_LABEL label;
+ TPM_FAMILY_ID familyID;
+ TPM_FAMILY_VERIFICATION verificationCount;
+ TPM_FAMILY_FLAGS flags;
+} TPM_FAMILY_TABLE_ENTRY;
+
+//
+// Part 2, section 20.6: TPM_FAMILY_TABLE
+//
+#define TPM_NUM_FAMILY_TABLE_ENTRY_MIN 8
+
+typedef struct tdTPM_FAMILY_TABLE {
+ TPM_FAMILY_TABLE_ENTRY famTableRow[TPM_NUM_FAMILY_TABLE_ENTRY_MIN];
+} TPM_FAMILY_TABLE;
+
+///
+/// Part 2, section 20.7: TPM_DELEGATE_LABEL
+///
+typedef struct tdTPM_DELEGATE_LABEL {
+ UINT8 label;
+} TPM_DELEGATE_LABEL;
+
+///
+/// Part 2, section 20.8: TPM_DELEGATE_PUBLIC
+///
+typedef struct tdTPM_DELEGATE_PUBLIC {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DELEGATE_LABEL label;
+ TPM_PCR_INFO_SHORT pcrInfo;
+ TPM_DELEGATIONS permissions;
+ TPM_FAMILY_ID familyID;
+ TPM_FAMILY_VERIFICATION verificationCount;
+} TPM_DELEGATE_PUBLIC;
+
+///
+/// Part 2, section 20.9: TPM_DELEGATE_TABLE_ROW
+///
+typedef struct tdTPM_DELEGATE_TABLE_ROW {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DELEGATE_PUBLIC pub;
+ TPM_SECRET authValue;
+} TPM_DELEGATE_TABLE_ROW;
+
+//
+// Part 2, section 20.10: TPM_DELEGATE_TABLE
+//
+#define TPM_NUM_DELEGATE_TABLE_ENTRY_MIN 2
+
+typedef struct tdTPM_DELEGATE_TABLE {
+ TPM_DELEGATE_TABLE_ROW delRow[TPM_NUM_DELEGATE_TABLE_ENTRY_MIN];
+} TPM_DELEGATE_TABLE;
+
+///
+/// Part 2, section 20.11: TPM_DELEGATE_SENSITIVE
+///
+typedef struct tdTPM_DELEGATE_SENSITIVE {
+ TPM_STRUCTURE_TAG tag;
+ TPM_SECRET authValue;
+} TPM_DELEGATE_SENSITIVE;
+
+///
+/// Part 2, section 20.12: TPM_DELEGATE_OWNER_BLOB
+///
+typedef struct tdTPM_DELEGATE_OWNER_BLOB {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DELEGATE_PUBLIC pub;
+ TPM_DIGEST integrityDigest;
+ UINT32 additionalSize;
+ UINT8 *additionalArea;
+ UINT32 sensitiveSize;
+ UINT8 *sensitiveArea;
+} TPM_DELEGATE_OWNER_BLOB;
+
+///
+/// Part 2, section 20.13: TTPM_DELEGATE_KEY_BLOB
+///
+typedef struct tdTPM_DELEGATE_KEY_BLOB {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DELEGATE_PUBLIC pub;
+ TPM_DIGEST integrityDigest;
+ TPM_DIGEST pubKeyDigest;
+ UINT32 additionalSize;
+ UINT8 *additionalArea;
+ UINT32 sensitiveSize;
+ UINT8 *sensitiveArea;
+} TPM_DELEGATE_KEY_BLOB;
+
+//
+// Part 2, section 20.14: TPM_FAMILY_OPERATION Values
+//
+#define TPM_FAMILY_CREATE ((UINT32)0x00000001)
+#define TPM_FAMILY_ENABLE ((UINT32)0x00000002)
+#define TPM_FAMILY_ADMIN ((UINT32)0x00000003)
+#define TPM_FAMILY_INVALIDATE ((UINT32)0x00000004)
+
+//
+// Part 2, section 21.1: TPM_CAPABILITY_AREA for GetCapability
+//
+#define TPM_CAP_ORD ((TPM_CAPABILITY_AREA) 0x00000001)
+#define TPM_CAP_ALG ((TPM_CAPABILITY_AREA) 0x00000002)
+#define TPM_CAP_PID ((TPM_CAPABILITY_AREA) 0x00000003)
+#define TPM_CAP_FLAG ((TPM_CAPABILITY_AREA) 0x00000004)
+#define TPM_CAP_PROPERTY ((TPM_CAPABILITY_AREA) 0x00000005)
+#define TPM_CAP_VERSION ((TPM_CAPABILITY_AREA) 0x00000006)
+#define TPM_CAP_KEY_HANDLE ((TPM_CAPABILITY_AREA) 0x00000007)
+#define TPM_CAP_CHECK_LOADED ((TPM_CAPABILITY_AREA) 0x00000008)
+#define TPM_CAP_SYM_MODE ((TPM_CAPABILITY_AREA) 0x00000009)
+#define TPM_CAP_KEY_STATUS ((TPM_CAPABILITY_AREA) 0x0000000C)
+#define TPM_CAP_NV_LIST ((TPM_CAPABILITY_AREA) 0x0000000D)
+#define TPM_CAP_MFR ((TPM_CAPABILITY_AREA) 0x00000010)
+#define TPM_CAP_NV_INDEX ((TPM_CAPABILITY_AREA) 0x00000011)
+#define TPM_CAP_TRANS_ALG ((TPM_CAPABILITY_AREA) 0x00000012)
+#define TPM_CAP_HANDLE ((TPM_CAPABILITY_AREA) 0x00000014)
+#define TPM_CAP_TRANS_ES ((TPM_CAPABILITY_AREA) 0x00000015)
+#define TPM_CAP_AUTH_ENCRYPT ((TPM_CAPABILITY_AREA) 0x00000017)
+#define TPM_CAP_SELECT_SIZE ((TPM_CAPABILITY_AREA) 0x00000018)
+#define TPM_CAP_VERSION_VAL ((TPM_CAPABILITY_AREA) 0x0000001A)
+
+#define TPM_CAP_FLAG_PERMANENT ((TPM_CAPABILITY_AREA) 0x00000108)
+#define TPM_CAP_FLAG_VOLATILE ((TPM_CAPABILITY_AREA) 0x00000109)
+
+//
+// Part 2, section 21.2: CAP_PROPERTY Subcap values for GetCapability
+//
+#define TPM_CAP_PROP_PCR ((TPM_CAPABILITY_AREA) 0x00000101)
+#define TPM_CAP_PROP_DIR ((TPM_CAPABILITY_AREA) 0x00000102)
+#define TPM_CAP_PROP_MANUFACTURER ((TPM_CAPABILITY_AREA) 0x00000103)
+#define TPM_CAP_PROP_KEYS ((TPM_CAPABILITY_AREA) 0x00000104)
+#define TPM_CAP_PROP_MIN_COUNTER ((TPM_CAPABILITY_AREA) 0x00000107)
+#define TPM_CAP_PROP_AUTHSESS ((TPM_CAPABILITY_AREA) 0x0000010A)
+#define TPM_CAP_PROP_TRANSESS ((TPM_CAPABILITY_AREA) 0x0000010B)
+#define TPM_CAP_PROP_COUNTERS ((TPM_CAPABILITY_AREA) 0x0000010C)
+#define TPM_CAP_PROP_MAX_AUTHSESS ((TPM_CAPABILITY_AREA) 0x0000010D)
+#define TPM_CAP_PROP_MAX_TRANSESS ((TPM_CAPABILITY_AREA) 0x0000010E)
+#define TPM_CAP_PROP_MAX_COUNTERS ((TPM_CAPABILITY_AREA) 0x0000010F)
+#define TPM_CAP_PROP_MAX_KEYS ((TPM_CAPABILITY_AREA) 0x00000110)
+#define TPM_CAP_PROP_OWNER ((TPM_CAPABILITY_AREA) 0x00000111)
+#define TPM_CAP_PROP_CONTEXT ((TPM_CAPABILITY_AREA) 0x00000112)
+#define TPM_CAP_PROP_MAX_CONTEXT ((TPM_CAPABILITY_AREA) 0x00000113)
+#define TPM_CAP_PROP_FAMILYROWS ((TPM_CAPABILITY_AREA) 0x00000114)
+#define TPM_CAP_PROP_TIS_TIMEOUT ((TPM_CAPABILITY_AREA) 0x00000115)
+#define TPM_CAP_PROP_STARTUP_EFFECT ((TPM_CAPABILITY_AREA) 0x00000116)
+#define TPM_CAP_PROP_DELEGATE_ROW ((TPM_CAPABILITY_AREA) 0x00000117)
+#define TPM_CAP_PROP_DAA_MAX ((TPM_CAPABILITY_AREA) 0x00000119)
+#define CAP_PROP_SESSION_DAA ((TPM_CAPABILITY_AREA) 0x0000011A)
+#define TPM_CAP_PROP_CONTEXT_DIST ((TPM_CAPABILITY_AREA) 0x0000011B)
+#define TPM_CAP_PROP_DAA_INTERRUPT ((TPM_CAPABILITY_AREA) 0x0000011C)
+#define TPM_CAP_PROP_SESSIONS ((TPM_CAPABILITY_AREA) 0x0000011D)
+#define TPM_CAP_PROP_MAX_SESSIONS ((TPM_CAPABILITY_AREA) 0x0000011E)
+#define TPM_CAP_PROP_CMK_RESTRICTION ((TPM_CAPABILITY_AREA) 0x0000011F)
+#define TPM_CAP_PROP_DURATION ((TPM_CAPABILITY_AREA) 0x00000120)
+#define TPM_CAP_PROP_ACTIVE_COUNTER ((TPM_CAPABILITY_AREA) 0x00000122)
+#define TPM_CAP_PROP_MAX_NV_AVAILABLE ((TPM_CAPABILITY_AREA) 0x00000123)
+#define TPM_CAP_PROP_INPUT_BUFFER ((TPM_CAPABILITY_AREA) 0x00000124)
+
+//
+// Part 2, section 21.4: TPM_CAPABILITY_AREA for SetCapability
+//
+#define TPM_SET_PERM_FLAGS ((TPM_CAPABILITY_AREA) 0x00000001)
+#define TPM_SET_PERM_DATA ((TPM_CAPABILITY_AREA) 0x00000002)
+#define TPM_SET_STCLEAR_FLAGS ((TPM_CAPABILITY_AREA) 0x00000003)
+#define TPM_SET_STCLEAR_DATA ((TPM_CAPABILITY_AREA) 0x00000004)
+#define TPM_SET_STANY_FLAGS ((TPM_CAPABILITY_AREA) 0x00000005)
+#define TPM_SET_STANY_DATA ((TPM_CAPABILITY_AREA) 0x00000006)
+
+///
+/// Part 2, section 21.6: TPM_CAP_VERSION_INFO
+/// [size_is(vendorSpecificSize)] BYTE* vendorSpecific;
+///
+typedef struct tdTPM_CAP_VERSION_INFO {
+ TPM_STRUCTURE_TAG tag;
+ TPM_VERSION version;
+ UINT16 specLevel;
+ UINT8 errataRev;
+ UINT8 tpmVendorID[4];
+ UINT16 vendorSpecificSize;
+ UINT8 *vendorSpecific;
+} TPM_CAP_VERSION_INFO;
+
+///
+/// Part 2, section 21.10: TPM_DA_ACTION_TYPE
+///
+typedef struct tdTPM_DA_ACTION_TYPE {
+ TPM_STRUCTURE_TAG tag;
+ UINT32 actions;
+} TPM_DA_ACTION_TYPE;
+
+#define TPM_DA_ACTION_FAILURE_MODE (((UINT32)1)<<3)
+#define TPM_DA_ACTION_DEACTIVATE (((UINT32)1)<<2)
+#define TPM_DA_ACTION_DISABLE (((UINT32)1)<<1)
+#define TPM_DA_ACTION_TIMEOUT (((UINT32)1)<<0)
+
+///
+/// Part 2, section 21.7: TPM_DA_INFO
+///
+typedef struct tdTPM_DA_INFO {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DA_STATE state;
+ UINT16 currentCount;
+ UINT16 thresholdCount;
+ TPM_DA_ACTION_TYPE actionAtThreshold;
+ UINT32 actionDependValue;
+ UINT32 vendorDataSize;
+ UINT8 *vendorData;
+} TPM_DA_INFO;
+
+///
+/// Part 2, section 21.8: TPM_DA_INFO_LIMITED
+///
+typedef struct tdTPM_DA_INFO_LIMITED {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DA_STATE state;
+ TPM_DA_ACTION_TYPE actionAtThreshold;
+ UINT32 vendorDataSize;
+ UINT8 *vendorData;
+} TPM_DA_INFO_LIMITED;
+
+//
+// Part 2, section 21.9: CAP_PROPERTY Subcap values for GetCapability
+//
+#define TPM_DA_STATE_INACTIVE ((UINT8)0x00)
+#define TPM_DA_STATE_ACTIVE ((UINT8)0x01)
+
+//
+// Part 2, section 22: DAA Structures
+//
+
+//
+// Part 2, section 22.1: Size definitions
+//
+#define TPM_DAA_SIZE_r0 (43)
+#define TPM_DAA_SIZE_r1 (43)
+#define TPM_DAA_SIZE_r2 (128)
+#define TPM_DAA_SIZE_r3 (168)
+#define TPM_DAA_SIZE_r4 (219)
+#define TPM_DAA_SIZE_NT (20)
+#define TPM_DAA_SIZE_v0 (128)
+#define TPM_DAA_SIZE_v1 (192)
+#define TPM_DAA_SIZE_NE (256)
+#define TPM_DAA_SIZE_w (256)
+#define TPM_DAA_SIZE_issuerModulus (256)
+//
+// Part 2, section 22.2: Constant definitions
+//
+#define TPM_DAA_power0 (104)
+#define TPM_DAA_power1 (1024)
+
+///
+/// Part 2, section 22.3: TPM_DAA_ISSUER
+///
+typedef struct tdTPM_DAA_ISSUER {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST DAA_digest_R0;
+ TPM_DIGEST DAA_digest_R1;
+ TPM_DIGEST DAA_digest_S0;
+ TPM_DIGEST DAA_digest_S1;
+ TPM_DIGEST DAA_digest_n;
+ TPM_DIGEST DAA_digest_gamma;
+ UINT8 DAA_generic_q[26];
+} TPM_DAA_ISSUER;
+
+///
+/// Part 2, section 22.4: TPM_DAA_TPM
+///
+typedef struct tdTPM_DAA_TPM {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST DAA_digestIssuer;
+ TPM_DIGEST DAA_digest_v0;
+ TPM_DIGEST DAA_digest_v1;
+ TPM_DIGEST DAA_rekey;
+ UINT32 DAA_count;
+} TPM_DAA_TPM;
+
+///
+/// Part 2, section 22.5: TPM_DAA_CONTEXT
+///
+typedef struct tdTPM_DAA_CONTEXT {
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST DAA_digestContext;
+ TPM_DIGEST DAA_digest;
+ TPM_DAA_CONTEXT_SEED DAA_contextSeed;
+ UINT8 DAA_scratch[256];
+ UINT8 DAA_stage;
+} TPM_DAA_CONTEXT;
+
+///
+/// Part 2, section 22.6: TPM_DAA_JOINDATA
+///
+typedef struct tdTPM_DAA_JOINDATA {
+ UINT8 DAA_join_u0[128];
+ UINT8 DAA_join_u1[138];
+ TPM_DIGEST DAA_digest_n0;
+} TPM_DAA_JOINDATA;
+
+///
+/// Part 2, section 22.8: TPM_DAA_BLOB
+///
+typedef struct tdTPM_DAA_BLOB {
+ TPM_STRUCTURE_TAG tag;
+ TPM_RESOURCE_TYPE resourceType;
+ UINT8 label[16];
+ TPM_DIGEST blobIntegrity;
+ UINT32 additionalSize;
+ UINT8 *additionalData;
+ UINT32 sensitiveSize;
+ UINT8 *sensitiveData;
+} TPM_DAA_BLOB;
+
+///
+/// Part 2, section 22.9: TPM_DAA_SENSITIVE
+///
+typedef struct tdTPM_DAA_SENSITIVE {
+ TPM_STRUCTURE_TAG tag;
+ UINT32 internalSize;
+ UINT8 *internalData;
+} TPM_DAA_SENSITIVE;
+
+//
+// Part 2, section 23: Redirection
+//
+
+///
+/// Part 2 section 23.1: TPM_REDIR_COMMAND
+/// This section defines exactly one value but does not
+/// give it a name. The definition of TPM_SetRedirection in Part3
+/// refers to exactly one name but does not give its value. We join
+/// them here.
+///
+#define TPM_REDIR_GPIO (0x00000001)
+
+///
+/// TPM Command Headers defined in Part 3
+///
+typedef struct tdTPM_RQU_COMMAND_HDR {
+ TPM_STRUCTURE_TAG tag;
+ UINT32 paramSize;
+ TPM_COMMAND_CODE ordinal;
+} TPM_RQU_COMMAND_HDR;
+
+///
+/// TPM Response Headers defined in Part 3
+///
+typedef struct tdTPM_RSP_COMMAND_HDR {
+ TPM_STRUCTURE_TAG tag;
+ UINT32 paramSize;
+ TPM_RESULT returnCode;
+} TPM_RSP_COMMAND_HDR;
+
+#pragma pack ()
+
+#endif
diff --git a/sys/contrib/edk2/Include/IndustryStandard/Tpm20.h b/sys/contrib/edk2/Include/IndustryStandard/Tpm20.h new file mode 100644 index 000000000000..609b727ac8ee --- /dev/null +++ b/sys/contrib/edk2/Include/IndustryStandard/Tpm20.h @@ -0,0 +1,1813 @@ +/** @file
+ TPM2.0 Specification data structures
+ (Trusted Platform Module Library Specification, Family "2.0", Level 00, Revision 00.96,
+ @http://www.trustedcomputinggroup.org/resources/tpm_library_specification)
+
+ Check http://trustedcomputinggroup.org for latest specification updates.
+
+Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved. <BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _TPM20_H_
+#define _TPM20_H_
+
+#include <IndustryStandard/Tpm12.h>
+
+#pragma pack (1)
+
+// Annex A Algorithm Constants
+
+// Table 205 - Defines for SHA1 Hash Values
+#define SHA1_DIGEST_SIZE 20
+#define SHA1_BLOCK_SIZE 64
+
+// Table 206 - Defines for SHA256 Hash Values
+#define SHA256_DIGEST_SIZE 32
+#define SHA256_BLOCK_SIZE 64
+
+// Table 207 - Defines for SHA384 Hash Values
+#define SHA384_DIGEST_SIZE 48
+#define SHA384_BLOCK_SIZE 128
+
+// Table 208 - Defines for SHA512 Hash Values
+#define SHA512_DIGEST_SIZE 64
+#define SHA512_BLOCK_SIZE 128
+
+// Table 209 - Defines for SM3_256 Hash Values
+#define SM3_256_DIGEST_SIZE 32
+#define SM3_256_BLOCK_SIZE 64
+
+// Table 210 - Defines for Architectural Limits Values
+#define MAX_SESSION_NUMBER 3
+
+// Annex B Implementation Definitions
+
+// Table 211 - Defines for Logic Values
+#define YES 1
+#define NO 0
+#define SET 1
+#define CLEAR 0
+
+// Table 215 - Defines for RSA Algorithm Constants
+#define MAX_RSA_KEY_BITS 2048
+#define MAX_RSA_KEY_BYTES ((MAX_RSA_KEY_BITS + 7) / 8)
+
+// Table 216 - Defines for ECC Algorithm Constants
+#define MAX_ECC_KEY_BITS 256
+#define MAX_ECC_KEY_BYTES ((MAX_ECC_KEY_BITS + 7) / 8)
+
+// Table 217 - Defines for AES Algorithm Constants
+#define MAX_AES_KEY_BITS 128
+#define MAX_AES_BLOCK_SIZE_BYTES 16
+#define MAX_AES_KEY_BYTES ((MAX_AES_KEY_BITS + 7) / 8)
+
+// Table 218 - Defines for SM4 Algorithm Constants
+#define MAX_SM4_KEY_BITS 128
+#define MAX_SM4_BLOCK_SIZE_BYTES 16
+#define MAX_SM4_KEY_BYTES ((MAX_SM4_KEY_BITS + 7) / 8)
+
+// Table 219 - Defines for Symmetric Algorithm Constants
+#define MAX_SYM_KEY_BITS MAX_AES_KEY_BITS
+#define MAX_SYM_KEY_BYTES MAX_AES_KEY_BYTES
+#define MAX_SYM_BLOCK_SIZE MAX_AES_BLOCK_SIZE_BYTES
+
+// Table 220 - Defines for Implementation Values
+typedef UINT16 BSIZE;
+#define BUFFER_ALIGNMENT 4
+#define IMPLEMENTATION_PCR 24
+#define PLATFORM_PCR 24
+#define DRTM_PCR 17
+#define NUM_LOCALITIES 5
+#define MAX_HANDLE_NUM 3
+#define MAX_ACTIVE_SESSIONS 64
+typedef UINT16 CONTEXT_SLOT;
+typedef UINT64 CONTEXT_COUNTER;
+#define MAX_LOADED_SESSIONS 3
+#define MAX_SESSION_NUM 3
+#define MAX_LOADED_OBJECTS 3
+#define MIN_EVICT_OBJECTS 2
+#define PCR_SELECT_MIN ((PLATFORM_PCR + 7) / 8)
+#define PCR_SELECT_MAX ((IMPLEMENTATION_PCR + 7) / 8)
+#define NUM_POLICY_PCR_GROUP 1
+#define NUM_AUTHVALUE_PCR_GROUP 1
+#define MAX_CONTEXT_SIZE 4000
+#define MAX_DIGEST_BUFFER 1024
+#define MAX_NV_INDEX_SIZE 1024
+#define MAX_CAP_BUFFER 1024
+#define NV_MEMORY_SIZE 16384
+#define NUM_STATIC_PCR 16
+#define MAX_ALG_LIST_SIZE 64
+#define TIMER_PRESCALE 100000
+#define PRIMARY_SEED_SIZE 32
+#define CONTEXT_ENCRYPT_ALG TPM_ALG_AES
+#define CONTEXT_ENCRYPT_KEY_BITS MAX_SYM_KEY_BITS
+#define CONTEXT_ENCRYPT_KEY_BYTES ((CONTEXT_ENCRYPT_KEY_BITS + 7) / 8)
+#define CONTEXT_INTEGRITY_HASH_ALG TPM_ALG_SHA256
+#define CONTEXT_INTEGRITY_HASH_SIZE SHA256_DIGEST_SIZE
+#define PROOF_SIZE CONTEXT_INTEGRITY_HASH_SIZE
+#define NV_CLOCK_UPDATE_INTERVAL 12
+#define NUM_POLICY_PCR 1
+#define MAX_COMMAND_SIZE 4096
+#define MAX_RESPONSE_SIZE 4096
+#define ORDERLY_BITS 8
+#define MAX_ORDERLY_COUNT ((1 << ORDERLY_BITS) - 1)
+#define ALG_ID_FIRST TPM_ALG_FIRST
+#define ALG_ID_LAST TPM_ALG_LAST
+#define MAX_SYM_DATA 128
+#define MAX_RNG_ENTROPY_SIZE 64
+#define RAM_INDEX_SPACE 512
+#define RSA_DEFAULT_PUBLIC_EXPONENT 0x00010001
+#define CRT_FORMAT_RSA YES
+#define PRIVATE_VENDOR_SPECIFIC_BYTES ((MAX_RSA_KEY_BYTES / 2) * ( 3 + CRT_FORMAT_RSA * 2))
+
+// Capability related MAX_ value
+#define MAX_CAP_DATA (MAX_CAP_BUFFER - sizeof(TPM_CAP) - sizeof(UINT32))
+#define MAX_CAP_ALGS (MAX_CAP_DATA / sizeof(TPMS_ALG_PROPERTY))
+#define MAX_CAP_HANDLES (MAX_CAP_DATA / sizeof(TPM_HANDLE))
+#define MAX_CAP_CC (MAX_CAP_DATA / sizeof(TPM_CC))
+#define MAX_TPM_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PROPERTY))
+#define MAX_PCR_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PCR_SELECT))
+#define MAX_ECC_CURVES (MAX_CAP_DATA / sizeof(TPM_ECC_CURVE))
+
+//
+// Always set 5 here, because we want to support all hash algo in BIOS.
+//
+#define HASH_COUNT 5
+
+// 5 Base Types
+
+// Table 3 - Definition of Base Types
+typedef UINT8 BYTE;
+
+// Table 4 - Definition of Types for Documentation Clarity
+//
+// NOTE: Comment because it has same name as TPM1.2 (value is same, so not runtime issue)
+//
+// typedef UINT32 TPM_ALGORITHM_ID;
+// typedef UINT32 TPM_MODIFIER_INDICATOR;
+typedef UINT32 TPM_AUTHORIZATION_SIZE;
+typedef UINT32 TPM_PARAMETER_SIZE;
+typedef UINT16 TPM_KEY_SIZE;
+typedef UINT16 TPM_KEY_BITS;
+
+// 6 Constants
+
+// Table 6 - TPM_GENERATED Constants
+typedef UINT32 TPM_GENERATED;
+#define TPM_GENERATED_VALUE (TPM_GENERATED)(0xff544347)
+
+// Table 7 - TPM_ALG_ID Constants
+typedef UINT16 TPM_ALG_ID;
+//
+// NOTE: Comment some algo which has same name as TPM1.2 (value is same, so not runtime issue)
+//
+#define TPM_ALG_ERROR (TPM_ALG_ID)(0x0000)
+#define TPM_ALG_FIRST (TPM_ALG_ID)(0x0001)
+// #define TPM_ALG_RSA (TPM_ALG_ID)(0x0001)
+// #define TPM_ALG_SHA (TPM_ALG_ID)(0x0004)
+#define TPM_ALG_SHA1 (TPM_ALG_ID)(0x0004)
+// #define TPM_ALG_HMAC (TPM_ALG_ID)(0x0005)
+#define TPM_ALG_AES (TPM_ALG_ID)(0x0006)
+// #define TPM_ALG_MGF1 (TPM_ALG_ID)(0x0007)
+#define TPM_ALG_KEYEDHASH (TPM_ALG_ID)(0x0008)
+// #define TPM_ALG_XOR (TPM_ALG_ID)(0x000A)
+#define TPM_ALG_SHA256 (TPM_ALG_ID)(0x000B)
+#define TPM_ALG_SHA384 (TPM_ALG_ID)(0x000C)
+#define TPM_ALG_SHA512 (TPM_ALG_ID)(0x000D)
+#define TPM_ALG_NULL (TPM_ALG_ID)(0x0010)
+#define TPM_ALG_SM3_256 (TPM_ALG_ID)(0x0012)
+#define TPM_ALG_SM4 (TPM_ALG_ID)(0x0013)
+#define TPM_ALG_RSASSA (TPM_ALG_ID)(0x0014)
+#define TPM_ALG_RSAES (TPM_ALG_ID)(0x0015)
+#define TPM_ALG_RSAPSS (TPM_ALG_ID)(0x0016)
+#define TPM_ALG_OAEP (TPM_ALG_ID)(0x0017)
+#define TPM_ALG_ECDSA (TPM_ALG_ID)(0x0018)
+#define TPM_ALG_ECDH (TPM_ALG_ID)(0x0019)
+#define TPM_ALG_ECDAA (TPM_ALG_ID)(0x001A)
+#define TPM_ALG_SM2 (TPM_ALG_ID)(0x001B)
+#define TPM_ALG_ECSCHNORR (TPM_ALG_ID)(0x001C)
+#define TPM_ALG_ECMQV (TPM_ALG_ID)(0x001D)
+#define TPM_ALG_KDF1_SP800_56a (TPM_ALG_ID)(0x0020)
+#define TPM_ALG_KDF2 (TPM_ALG_ID)(0x0021)
+#define TPM_ALG_KDF1_SP800_108 (TPM_ALG_ID)(0x0022)
+#define TPM_ALG_ECC (TPM_ALG_ID)(0x0023)
+#define TPM_ALG_SYMCIPHER (TPM_ALG_ID)(0x0025)
+#define TPM_ALG_CTR (TPM_ALG_ID)(0x0040)
+#define TPM_ALG_OFB (TPM_ALG_ID)(0x0041)
+#define TPM_ALG_CBC (TPM_ALG_ID)(0x0042)
+#define TPM_ALG_CFB (TPM_ALG_ID)(0x0043)
+#define TPM_ALG_ECB (TPM_ALG_ID)(0x0044)
+#define TPM_ALG_LAST (TPM_ALG_ID)(0x0044)
+
+// Table 8 - TPM_ECC_CURVE Constants
+typedef UINT16 TPM_ECC_CURVE;
+#define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000)
+#define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001)
+#define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002)
+#define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003)
+#define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004)
+#define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005)
+#define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010)
+#define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011)
+#define TPM_ECC_SM2_P256 (TPM_ECC_CURVE)(0x0020)
+#define TPM_ECC_BP_P512_R1 (TPM_ECC_CURVE)(0x0032)
+
+// Table 11 - TPM_CC Constants (Numeric Order)
+typedef UINT32 TPM_CC;
+#define TPM_CC_FIRST (TPM_CC)(0x0000011F)
+#define TPM_CC_PP_FIRST (TPM_CC)(0x0000011F)
+#define TPM_CC_NV_UndefineSpaceSpecial (TPM_CC)(0x0000011F)
+#define TPM_CC_EvictControl (TPM_CC)(0x00000120)
+#define TPM_CC_HierarchyControl (TPM_CC)(0x00000121)
+#define TPM_CC_NV_UndefineSpace (TPM_CC)(0x00000122)
+#define TPM_CC_ChangeEPS (TPM_CC)(0x00000124)
+#define TPM_CC_ChangePPS (TPM_CC)(0x00000125)
+#define TPM_CC_Clear (TPM_CC)(0x00000126)
+#define TPM_CC_ClearControl (TPM_CC)(0x00000127)
+#define TPM_CC_ClockSet (TPM_CC)(0x00000128)
+#define TPM_CC_HierarchyChangeAuth (TPM_CC)(0x00000129)
+#define TPM_CC_NV_DefineSpace (TPM_CC)(0x0000012A)
+#define TPM_CC_PCR_Allocate (TPM_CC)(0x0000012B)
+#define TPM_CC_PCR_SetAuthPolicy (TPM_CC)(0x0000012C)
+#define TPM_CC_PP_Commands (TPM_CC)(0x0000012D)
+#define TPM_CC_SetPrimaryPolicy (TPM_CC)(0x0000012E)
+#define TPM_CC_FieldUpgradeStart (TPM_CC)(0x0000012F)
+#define TPM_CC_ClockRateAdjust (TPM_CC)(0x00000130)
+#define TPM_CC_CreatePrimary (TPM_CC)(0x00000131)
+#define TPM_CC_NV_GlobalWriteLock (TPM_CC)(0x00000132)
+#define TPM_CC_PP_LAST (TPM_CC)(0x00000132)
+#define TPM_CC_GetCommandAuditDigest (TPM_CC)(0x00000133)
+#define TPM_CC_NV_Increment (TPM_CC)(0x00000134)
+#define TPM_CC_NV_SetBits (TPM_CC)(0x00000135)
+#define TPM_CC_NV_Extend (TPM_CC)(0x00000136)
+#define TPM_CC_NV_Write (TPM_CC)(0x00000137)
+#define TPM_CC_NV_WriteLock (TPM_CC)(0x00000138)
+#define TPM_CC_DictionaryAttackLockReset (TPM_CC)(0x00000139)
+#define TPM_CC_DictionaryAttackParameters (TPM_CC)(0x0000013A)
+#define TPM_CC_NV_ChangeAuth (TPM_CC)(0x0000013B)
+#define TPM_CC_PCR_Event (TPM_CC)(0x0000013C)
+#define TPM_CC_PCR_Reset (TPM_CC)(0x0000013D)
+#define TPM_CC_SequenceComplete (TPM_CC)(0x0000013E)
+#define TPM_CC_SetAlgorithmSet (TPM_CC)(0x0000013F)
+#define TPM_CC_SetCommandCodeAuditStatus (TPM_CC)(0x00000140)
+#define TPM_CC_FieldUpgradeData (TPM_CC)(0x00000141)
+#define TPM_CC_IncrementalSelfTest (TPM_CC)(0x00000142)
+#define TPM_CC_SelfTest (TPM_CC)(0x00000143)
+#define TPM_CC_Startup (TPM_CC)(0x00000144)
+#define TPM_CC_Shutdown (TPM_CC)(0x00000145)
+#define TPM_CC_StirRandom (TPM_CC)(0x00000146)
+#define TPM_CC_ActivateCredential (TPM_CC)(0x00000147)
+#define TPM_CC_Certify (TPM_CC)(0x00000148)
+#define TPM_CC_PolicyNV (TPM_CC)(0x00000149)
+#define TPM_CC_CertifyCreation (TPM_CC)(0x0000014A)
+#define TPM_CC_Duplicate (TPM_CC)(0x0000014B)
+#define TPM_CC_GetTime (TPM_CC)(0x0000014C)
+#define TPM_CC_GetSessionAuditDigest (TPM_CC)(0x0000014D)
+#define TPM_CC_NV_Read (TPM_CC)(0x0000014E)
+#define TPM_CC_NV_ReadLock (TPM_CC)(0x0000014F)
+#define TPM_CC_ObjectChangeAuth (TPM_CC)(0x00000150)
+#define TPM_CC_PolicySecret (TPM_CC)(0x00000151)
+#define TPM_CC_Rewrap (TPM_CC)(0x00000152)
+#define TPM_CC_Create (TPM_CC)(0x00000153)
+#define TPM_CC_ECDH_ZGen (TPM_CC)(0x00000154)
+#define TPM_CC_HMAC (TPM_CC)(0x00000155)
+#define TPM_CC_Import (TPM_CC)(0x00000156)
+#define TPM_CC_Load (TPM_CC)(0x00000157)
+#define TPM_CC_Quote (TPM_CC)(0x00000158)
+#define TPM_CC_RSA_Decrypt (TPM_CC)(0x00000159)
+#define TPM_CC_HMAC_Start (TPM_CC)(0x0000015B)
+#define TPM_CC_SequenceUpdate (TPM_CC)(0x0000015C)
+#define TPM_CC_Sign (TPM_CC)(0x0000015D)
+#define TPM_CC_Unseal (TPM_CC)(0x0000015E)
+#define TPM_CC_PolicySigned (TPM_CC)(0x00000160)
+#define TPM_CC_ContextLoad (TPM_CC)(0x00000161)
+#define TPM_CC_ContextSave (TPM_CC)(0x00000162)
+#define TPM_CC_ECDH_KeyGen (TPM_CC)(0x00000163)
+#define TPM_CC_EncryptDecrypt (TPM_CC)(0x00000164)
+#define TPM_CC_FlushContext (TPM_CC)(0x00000165)
+#define TPM_CC_LoadExternal (TPM_CC)(0x00000167)
+#define TPM_CC_MakeCredential (TPM_CC)(0x00000168)
+#define TPM_CC_NV_ReadPublic (TPM_CC)(0x00000169)
+#define TPM_CC_PolicyAuthorize (TPM_CC)(0x0000016A)
+#define TPM_CC_PolicyAuthValue (TPM_CC)(0x0000016B)
+#define TPM_CC_PolicyCommandCode (TPM_CC)(0x0000016C)
+#define TPM_CC_PolicyCounterTimer (TPM_CC)(0x0000016D)
+#define TPM_CC_PolicyCpHash (TPM_CC)(0x0000016E)
+#define TPM_CC_PolicyLocality (TPM_CC)(0x0000016F)
+#define TPM_CC_PolicyNameHash (TPM_CC)(0x00000170)
+#define TPM_CC_PolicyOR (TPM_CC)(0x00000171)
+#define TPM_CC_PolicyTicket (TPM_CC)(0x00000172)
+#define TPM_CC_ReadPublic (TPM_CC)(0x00000173)
+#define TPM_CC_RSA_Encrypt (TPM_CC)(0x00000174)
+#define TPM_CC_StartAuthSession (TPM_CC)(0x00000176)
+#define TPM_CC_VerifySignature (TPM_CC)(0x00000177)
+#define TPM_CC_ECC_Parameters (TPM_CC)(0x00000178)
+#define TPM_CC_FirmwareRead (TPM_CC)(0x00000179)
+#define TPM_CC_GetCapability (TPM_CC)(0x0000017A)
+#define TPM_CC_GetRandom (TPM_CC)(0x0000017B)
+#define TPM_CC_GetTestResult (TPM_CC)(0x0000017C)
+#define TPM_CC_Hash (TPM_CC)(0x0000017D)
+#define TPM_CC_PCR_Read (TPM_CC)(0x0000017E)
+#define TPM_CC_PolicyPCR (TPM_CC)(0x0000017F)
+#define TPM_CC_PolicyRestart (TPM_CC)(0x00000180)
+#define TPM_CC_ReadClock (TPM_CC)(0x00000181)
+#define TPM_CC_PCR_Extend (TPM_CC)(0x00000182)
+#define TPM_CC_PCR_SetAuthValue (TPM_CC)(0x00000183)
+#define TPM_CC_NV_Certify (TPM_CC)(0x00000184)
+#define TPM_CC_EventSequenceComplete (TPM_CC)(0x00000185)
+#define TPM_CC_HashSequenceStart (TPM_CC)(0x00000186)
+#define TPM_CC_PolicyPhysicalPresence (TPM_CC)(0x00000187)
+#define TPM_CC_PolicyDuplicationSelect (TPM_CC)(0x00000188)
+#define TPM_CC_PolicyGetDigest (TPM_CC)(0x00000189)
+#define TPM_CC_TestParms (TPM_CC)(0x0000018A)
+#define TPM_CC_Commit (TPM_CC)(0x0000018B)
+#define TPM_CC_PolicyPassword (TPM_CC)(0x0000018C)
+#define TPM_CC_ZGen_2Phase (TPM_CC)(0x0000018D)
+#define TPM_CC_EC_Ephemeral (TPM_CC)(0x0000018E)
+#define TPM_CC_LAST (TPM_CC)(0x0000018E)
+
+// Table 15 - TPM_RC Constants (Actions)
+typedef UINT32 TPM_RC;
+#define TPM_RC_SUCCESS (TPM_RC)(0x000)
+#define TPM_RC_BAD_TAG (TPM_RC)(0x030)
+#define RC_VER1 (TPM_RC)(0x100)
+#define TPM_RC_INITIALIZE (TPM_RC)(RC_VER1 + 0x000)
+#define TPM_RC_FAILURE (TPM_RC)(RC_VER1 + 0x001)
+#define TPM_RC_SEQUENCE (TPM_RC)(RC_VER1 + 0x003)
+#define TPM_RC_PRIVATE (TPM_RC)(RC_VER1 + 0x00B)
+#define TPM_RC_HMAC (TPM_RC)(RC_VER1 + 0x019)
+#define TPM_RC_DISABLED (TPM_RC)(RC_VER1 + 0x020)
+#define TPM_RC_EXCLUSIVE (TPM_RC)(RC_VER1 + 0x021)
+#define TPM_RC_AUTH_TYPE (TPM_RC)(RC_VER1 + 0x024)
+#define TPM_RC_AUTH_MISSING (TPM_RC)(RC_VER1 + 0x025)
+#define TPM_RC_POLICY (TPM_RC)(RC_VER1 + 0x026)
+#define TPM_RC_PCR (TPM_RC)(RC_VER1 + 0x027)
+#define TPM_RC_PCR_CHANGED (TPM_RC)(RC_VER1 + 0x028)
+#define TPM_RC_UPGRADE (TPM_RC)(RC_VER1 + 0x02D)
+#define TPM_RC_TOO_MANY_CONTEXTS (TPM_RC)(RC_VER1 + 0x02E)
+#define TPM_RC_AUTH_UNAVAILABLE (TPM_RC)(RC_VER1 + 0x02F)
+#define TPM_RC_REBOOT (TPM_RC)(RC_VER1 + 0x030)
+#define TPM_RC_UNBALANCED (TPM_RC)(RC_VER1 + 0x031)
+#define TPM_RC_COMMAND_SIZE (TPM_RC)(RC_VER1 + 0x042)
+#define TPM_RC_COMMAND_CODE (TPM_RC)(RC_VER1 + 0x043)
+#define TPM_RC_AUTHSIZE (TPM_RC)(RC_VER1 + 0x044)
+#define TPM_RC_AUTH_CONTEXT (TPM_RC)(RC_VER1 + 0x045)
+#define TPM_RC_NV_RANGE (TPM_RC)(RC_VER1 + 0x046)
+#define TPM_RC_NV_SIZE (TPM_RC)(RC_VER1 + 0x047)
+#define TPM_RC_NV_LOCKED (TPM_RC)(RC_VER1 + 0x048)
+#define TPM_RC_NV_AUTHORIZATION (TPM_RC)(RC_VER1 + 0x049)
+#define TPM_RC_NV_UNINITIALIZED (TPM_RC)(RC_VER1 + 0x04A)
+#define TPM_RC_NV_SPACE (TPM_RC)(RC_VER1 + 0x04B)
+#define TPM_RC_NV_DEFINED (TPM_RC)(RC_VER1 + 0x04C)
+#define TPM_RC_BAD_CONTEXT (TPM_RC)(RC_VER1 + 0x050)
+#define TPM_RC_CPHASH (TPM_RC)(RC_VER1 + 0x051)
+#define TPM_RC_PARENT (TPM_RC)(RC_VER1 + 0x052)
+#define TPM_RC_NEEDS_TEST (TPM_RC)(RC_VER1 + 0x053)
+#define TPM_RC_NO_RESULT (TPM_RC)(RC_VER1 + 0x054)
+#define TPM_RC_SENSITIVE (TPM_RC)(RC_VER1 + 0x055)
+#define RC_MAX_FM0 (TPM_RC)(RC_VER1 + 0x07F)
+#define RC_FMT1 (TPM_RC)(0x080)
+#define TPM_RC_ASYMMETRIC (TPM_RC)(RC_FMT1 + 0x001)
+#define TPM_RC_ATTRIBUTES (TPM_RC)(RC_FMT1 + 0x002)
+#define TPM_RC_HASH (TPM_RC)(RC_FMT1 + 0x003)
+#define TPM_RC_VALUE (TPM_RC)(RC_FMT1 + 0x004)
+#define TPM_RC_HIERARCHY (TPM_RC)(RC_FMT1 + 0x005)
+#define TPM_RC_KEY_SIZE (TPM_RC)(RC_FMT1 + 0x007)
+#define TPM_RC_MGF (TPM_RC)(RC_FMT1 + 0x008)
+#define TPM_RC_MODE (TPM_RC)(RC_FMT1 + 0x009)
+#define TPM_RC_TYPE (TPM_RC)(RC_FMT1 + 0x00A)
+#define TPM_RC_HANDLE (TPM_RC)(RC_FMT1 + 0x00B)
+#define TPM_RC_KDF (TPM_RC)(RC_FMT1 + 0x00C)
+#define TPM_RC_RANGE (TPM_RC)(RC_FMT1 + 0x00D)
+#define TPM_RC_AUTH_FAIL (TPM_RC)(RC_FMT1 + 0x00E)
+#define TPM_RC_NONCE (TPM_RC)(RC_FMT1 + 0x00F)
+#define TPM_RC_PP (TPM_RC)(RC_FMT1 + 0x010)
+#define TPM_RC_SCHEME (TPM_RC)(RC_FMT1 + 0x012)
+#define TPM_RC_SIZE (TPM_RC)(RC_FMT1 + 0x015)
+#define TPM_RC_SYMMETRIC (TPM_RC)(RC_FMT1 + 0x016)
+#define TPM_RC_TAG (TPM_RC)(RC_FMT1 + 0x017)
+#define TPM_RC_SELECTOR (TPM_RC)(RC_FMT1 + 0x018)
+#define TPM_RC_INSUFFICIENT (TPM_RC)(RC_FMT1 + 0x01A)
+#define TPM_RC_SIGNATURE (TPM_RC)(RC_FMT1 + 0x01B)
+#define TPM_RC_KEY (TPM_RC)(RC_FMT1 + 0x01C)
+#define TPM_RC_POLICY_FAIL (TPM_RC)(RC_FMT1 + 0x01D)
+#define TPM_RC_INTEGRITY (TPM_RC)(RC_FMT1 + 0x01F)
+#define TPM_RC_TICKET (TPM_RC)(RC_FMT1 + 0x020)
+#define TPM_RC_RESERVED_BITS (TPM_RC)(RC_FMT1 + 0x021)
+#define TPM_RC_BAD_AUTH (TPM_RC)(RC_FMT1 + 0x022)
+#define TPM_RC_EXPIRED (TPM_RC)(RC_FMT1 + 0x023)
+#define TPM_RC_POLICY_CC (TPM_RC)(RC_FMT1 + 0x024 )
+#define TPM_RC_BINDING (TPM_RC)(RC_FMT1 + 0x025)
+#define TPM_RC_CURVE (TPM_RC)(RC_FMT1 + 0x026)
+#define TPM_RC_ECC_POINT (TPM_RC)(RC_FMT1 + 0x027)
+#define RC_WARN (TPM_RC)(0x900)
+#define TPM_RC_CONTEXT_GAP (TPM_RC)(RC_WARN + 0x001)
+#define TPM_RC_OBJECT_MEMORY (TPM_RC)(RC_WARN + 0x002)
+#define TPM_RC_SESSION_MEMORY (TPM_RC)(RC_WARN + 0x003)
+#define TPM_RC_MEMORY (TPM_RC)(RC_WARN + 0x004)
+#define TPM_RC_SESSION_HANDLES (TPM_RC)(RC_WARN + 0x005)
+#define TPM_RC_OBJECT_HANDLES (TPM_RC)(RC_WARN + 0x006)
+#define TPM_RC_LOCALITY (TPM_RC)(RC_WARN + 0x007)
+#define TPM_RC_YIELDED (TPM_RC)(RC_WARN + 0x008)
+#define TPM_RC_CANCELED (TPM_RC)(RC_WARN + 0x009)
+#define TPM_RC_TESTING (TPM_RC)(RC_WARN + 0x00A)
+#define TPM_RC_REFERENCE_H0 (TPM_RC)(RC_WARN + 0x010)
+#define TPM_RC_REFERENCE_H1 (TPM_RC)(RC_WARN + 0x011)
+#define TPM_RC_REFERENCE_H2 (TPM_RC)(RC_WARN + 0x012)
+#define TPM_RC_REFERENCE_H3 (TPM_RC)(RC_WARN + 0x013)
+#define TPM_RC_REFERENCE_H4 (TPM_RC)(RC_WARN + 0x014)
+#define TPM_RC_REFERENCE_H5 (TPM_RC)(RC_WARN + 0x015)
+#define TPM_RC_REFERENCE_H6 (TPM_RC)(RC_WARN + 0x016)
+#define TPM_RC_REFERENCE_S0 (TPM_RC)(RC_WARN + 0x018)
+#define TPM_RC_REFERENCE_S1 (TPM_RC)(RC_WARN + 0x019)
+#define TPM_RC_REFERENCE_S2 (TPM_RC)(RC_WARN + 0x01A)
+#define TPM_RC_REFERENCE_S3 (TPM_RC)(RC_WARN + 0x01B)
+#define TPM_RC_REFERENCE_S4 (TPM_RC)(RC_WARN + 0x01C)
+#define TPM_RC_REFERENCE_S5 (TPM_RC)(RC_WARN + 0x01D)
+#define TPM_RC_REFERENCE_S6 (TPM_RC)(RC_WARN + 0x01E)
+#define TPM_RC_NV_RATE (TPM_RC)(RC_WARN + 0x020)
+#define TPM_RC_LOCKOUT (TPM_RC)(RC_WARN + 0x021)
+#define TPM_RC_RETRY (TPM_RC)(RC_WARN + 0x022)
+#define TPM_RC_NV_UNAVAILABLE (TPM_RC)(RC_WARN + 0x023)
+#define TPM_RC_NOT_USED (TPM_RC)(RC_WARN + 0x7F)
+#define TPM_RC_H (TPM_RC)(0x000)
+#define TPM_RC_P (TPM_RC)(0x040)
+#define TPM_RC_S (TPM_RC)(0x800)
+#define TPM_RC_1 (TPM_RC)(0x100)
+#define TPM_RC_2 (TPM_RC)(0x200)
+#define TPM_RC_3 (TPM_RC)(0x300)
+#define TPM_RC_4 (TPM_RC)(0x400)
+#define TPM_RC_5 (TPM_RC)(0x500)
+#define TPM_RC_6 (TPM_RC)(0x600)
+#define TPM_RC_7 (TPM_RC)(0x700)
+#define TPM_RC_8 (TPM_RC)(0x800)
+#define TPM_RC_9 (TPM_RC)(0x900)
+#define TPM_RC_A (TPM_RC)(0xA00)
+#define TPM_RC_B (TPM_RC)(0xB00)
+#define TPM_RC_C (TPM_RC)(0xC00)
+#define TPM_RC_D (TPM_RC)(0xD00)
+#define TPM_RC_E (TPM_RC)(0xE00)
+#define TPM_RC_F (TPM_RC)(0xF00)
+#define TPM_RC_N_MASK (TPM_RC)(0xF00)
+
+// Table 16 - TPM_CLOCK_ADJUST Constants
+typedef INT8 TPM_CLOCK_ADJUST;
+#define TPM_CLOCK_COARSE_SLOWER (TPM_CLOCK_ADJUST)(-3)
+#define TPM_CLOCK_MEDIUM_SLOWER (TPM_CLOCK_ADJUST)(-2)
+#define TPM_CLOCK_FINE_SLOWER (TPM_CLOCK_ADJUST)(-1)
+#define TPM_CLOCK_NO_CHANGE (TPM_CLOCK_ADJUST)(0)
+#define TPM_CLOCK_FINE_FASTER (TPM_CLOCK_ADJUST)(1)
+#define TPM_CLOCK_MEDIUM_FASTER (TPM_CLOCK_ADJUST)(2)
+#define TPM_CLOCK_COARSE_FASTER (TPM_CLOCK_ADJUST)(3)
+
+// Table 17 - TPM_EO Constants
+typedef UINT16 TPM_EO;
+#define TPM_EO_EQ (TPM_EO)(0x0000)
+#define TPM_EO_NEQ (TPM_EO)(0x0001)
+#define TPM_EO_SIGNED_GT (TPM_EO)(0x0002)
+#define TPM_EO_UNSIGNED_GT (TPM_EO)(0x0003)
+#define TPM_EO_SIGNED_LT (TPM_EO)(0x0004)
+#define TPM_EO_UNSIGNED_LT (TPM_EO)(0x0005)
+#define TPM_EO_SIGNED_GE (TPM_EO)(0x0006)
+#define TPM_EO_UNSIGNED_GE (TPM_EO)(0x0007)
+#define TPM_EO_SIGNED_LE (TPM_EO)(0x0008)
+#define TPM_EO_UNSIGNED_LE (TPM_EO)(0x0009)
+#define TPM_EO_BITSET (TPM_EO)(0x000A)
+#define TPM_EO_BITCLEAR (TPM_EO)(0x000B)
+
+// Table 18 - TPM_ST Constants
+typedef UINT16 TPM_ST;
+#define TPM_ST_RSP_COMMAND (TPM_ST)(0x00C4)
+#define TPM_ST_NULL (TPM_ST)(0X8000)
+#define TPM_ST_NO_SESSIONS (TPM_ST)(0x8001)
+#define TPM_ST_SESSIONS (TPM_ST)(0x8002)
+#define TPM_ST_ATTEST_NV (TPM_ST)(0x8014)
+#define TPM_ST_ATTEST_COMMAND_AUDIT (TPM_ST)(0x8015)
+#define TPM_ST_ATTEST_SESSION_AUDIT (TPM_ST)(0x8016)
+#define TPM_ST_ATTEST_CERTIFY (TPM_ST)(0x8017)
+#define TPM_ST_ATTEST_QUOTE (TPM_ST)(0x8018)
+#define TPM_ST_ATTEST_TIME (TPM_ST)(0x8019)
+#define TPM_ST_ATTEST_CREATION (TPM_ST)(0x801A)
+#define TPM_ST_CREATION (TPM_ST)(0x8021)
+#define TPM_ST_VERIFIED (TPM_ST)(0x8022)
+#define TPM_ST_AUTH_SECRET (TPM_ST)(0x8023)
+#define TPM_ST_HASHCHECK (TPM_ST)(0x8024)
+#define TPM_ST_AUTH_SIGNED (TPM_ST)(0x8025)
+#define TPM_ST_FU_MANIFEST (TPM_ST)(0x8029)
+
+// Table 19 - TPM_SU Constants
+typedef UINT16 TPM_SU;
+#define TPM_SU_CLEAR (TPM_SU)(0x0000)
+#define TPM_SU_STATE (TPM_SU)(0x0001)
+
+// Table 20 - TPM_SE Constants
+typedef UINT8 TPM_SE;
+#define TPM_SE_HMAC (TPM_SE)(0x00)
+#define TPM_SE_POLICY (TPM_SE)(0x01)
+#define TPM_SE_TRIAL (TPM_SE)(0x03)
+
+// Table 21 - TPM_CAP Constants
+typedef UINT32 TPM_CAP;
+#define TPM_CAP_FIRST (TPM_CAP)(0x00000000)
+#define TPM_CAP_ALGS (TPM_CAP)(0x00000000)
+#define TPM_CAP_HANDLES (TPM_CAP)(0x00000001)
+#define TPM_CAP_COMMANDS (TPM_CAP)(0x00000002)
+#define TPM_CAP_PP_COMMANDS (TPM_CAP)(0x00000003)
+#define TPM_CAP_AUDIT_COMMANDS (TPM_CAP)(0x00000004)
+#define TPM_CAP_PCRS (TPM_CAP)(0x00000005)
+#define TPM_CAP_TPM_PROPERTIES (TPM_CAP)(0x00000006)
+#define TPM_CAP_PCR_PROPERTIES (TPM_CAP)(0x00000007)
+#define TPM_CAP_ECC_CURVES (TPM_CAP)(0x00000008)
+#define TPM_CAP_LAST (TPM_CAP)(0x00000008)
+#define TPM_CAP_VENDOR_PROPERTY (TPM_CAP)(0x00000100)
+
+// Table 22 - TPM_PT Constants
+typedef UINT32 TPM_PT;
+#define TPM_PT_NONE (TPM_PT)(0x00000000)
+#define PT_GROUP (TPM_PT)(0x00000100)
+#define PT_FIXED (TPM_PT)(PT_GROUP * 1)
+#define TPM_PT_FAMILY_INDICATOR (TPM_PT)(PT_FIXED + 0)
+#define TPM_PT_LEVEL (TPM_PT)(PT_FIXED + 1)
+#define TPM_PT_REVISION (TPM_PT)(PT_FIXED + 2)
+#define TPM_PT_DAY_OF_YEAR (TPM_PT)(PT_FIXED + 3)
+#define TPM_PT_YEAR (TPM_PT)(PT_FIXED + 4)
+#define TPM_PT_MANUFACTURER (TPM_PT)(PT_FIXED + 5)
+#define TPM_PT_VENDOR_STRING_1 (TPM_PT)(PT_FIXED + 6)
+#define TPM_PT_VENDOR_STRING_2 (TPM_PT)(PT_FIXED + 7)
+#define TPM_PT_VENDOR_STRING_3 (TPM_PT)(PT_FIXED + 8)
+#define TPM_PT_VENDOR_STRING_4 (TPM_PT)(PT_FIXED + 9)
+#define TPM_PT_VENDOR_TPM_TYPE (TPM_PT)(PT_FIXED + 10)
+#define TPM_PT_FIRMWARE_VERSION_1 (TPM_PT)(PT_FIXED + 11)
+#define TPM_PT_FIRMWARE_VERSION_2 (TPM_PT)(PT_FIXED + 12)
+#define TPM_PT_INPUT_BUFFER (TPM_PT)(PT_FIXED + 13)
+#define TPM_PT_HR_TRANSIENT_MIN (TPM_PT)(PT_FIXED + 14)
+#define TPM_PT_HR_PERSISTENT_MIN (TPM_PT)(PT_FIXED + 15)
+#define TPM_PT_HR_LOADED_MIN (TPM_PT)(PT_FIXED + 16)
+#define TPM_PT_ACTIVE_SESSIONS_MAX (TPM_PT)(PT_FIXED + 17)
+#define TPM_PT_PCR_COUNT (TPM_PT)(PT_FIXED + 18)
+#define TPM_PT_PCR_SELECT_MIN (TPM_PT)(PT_FIXED + 19)
+#define TPM_PT_CONTEXT_GAP_MAX (TPM_PT)(PT_FIXED + 20)
+#define TPM_PT_NV_COUNTERS_MAX (TPM_PT)(PT_FIXED + 22)
+#define TPM_PT_NV_INDEX_MAX (TPM_PT)(PT_FIXED + 23)
+#define TPM_PT_MEMORY (TPM_PT)(PT_FIXED + 24)
+#define TPM_PT_CLOCK_UPDATE (TPM_PT)(PT_FIXED + 25)
+#define TPM_PT_CONTEXT_HASH (TPM_PT)(PT_FIXED + 26)
+#define TPM_PT_CONTEXT_SYM (TPM_PT)(PT_FIXED + 27)
+#define TPM_PT_CONTEXT_SYM_SIZE (TPM_PT)(PT_FIXED + 28)
+#define TPM_PT_ORDERLY_COUNT (TPM_PT)(PT_FIXED + 29)
+#define TPM_PT_MAX_COMMAND_SIZE (TPM_PT)(PT_FIXED + 30)
+#define TPM_PT_MAX_RESPONSE_SIZE (TPM_PT)(PT_FIXED + 31)
+#define TPM_PT_MAX_DIGEST (TPM_PT)(PT_FIXED + 32)
+#define TPM_PT_MAX_OBJECT_CONTEXT (TPM_PT)(PT_FIXED + 33)
+#define TPM_PT_MAX_SESSION_CONTEXT (TPM_PT)(PT_FIXED + 34)
+#define TPM_PT_PS_FAMILY_INDICATOR (TPM_PT)(PT_FIXED + 35)
+#define TPM_PT_PS_LEVEL (TPM_PT)(PT_FIXED + 36)
+#define TPM_PT_PS_REVISION (TPM_PT)(PT_FIXED + 37)
+#define TPM_PT_PS_DAY_OF_YEAR (TPM_PT)(PT_FIXED + 38)
+#define TPM_PT_PS_YEAR (TPM_PT)(PT_FIXED + 39)
+#define TPM_PT_SPLIT_MAX (TPM_PT)(PT_FIXED + 40)
+#define TPM_PT_TOTAL_COMMANDS (TPM_PT)(PT_FIXED + 41)
+#define TPM_PT_LIBRARY_COMMANDS (TPM_PT)(PT_FIXED + 42)
+#define TPM_PT_VENDOR_COMMANDS (TPM_PT)(PT_FIXED + 43)
+#define PT_VAR (TPM_PT)(PT_GROUP * 2)
+#define TPM_PT_PERMANENT (TPM_PT)(PT_VAR + 0)
+#define TPM_PT_STARTUP_CLEAR (TPM_PT)(PT_VAR + 1)
+#define TPM_PT_HR_NV_INDEX (TPM_PT)(PT_VAR + 2)
+#define TPM_PT_HR_LOADED (TPM_PT)(PT_VAR + 3)
+#define TPM_PT_HR_LOADED_AVAIL (TPM_PT)(PT_VAR + 4)
+#define TPM_PT_HR_ACTIVE (TPM_PT)(PT_VAR + 5)
+#define TPM_PT_HR_ACTIVE_AVAIL (TPM_PT)(PT_VAR + 6)
+#define TPM_PT_HR_TRANSIENT_AVAIL (TPM_PT)(PT_VAR + 7)
+#define TPM_PT_HR_PERSISTENT (TPM_PT)(PT_VAR + 8)
+#define TPM_PT_HR_PERSISTENT_AVAIL (TPM_PT)(PT_VAR + 9)
+#define TPM_PT_NV_COUNTERS (TPM_PT)(PT_VAR + 10)
+#define TPM_PT_NV_COUNTERS_AVAIL (TPM_PT)(PT_VAR + 11)
+#define TPM_PT_ALGORITHM_SET (TPM_PT)(PT_VAR + 12)
+#define TPM_PT_LOADED_CURVES (TPM_PT)(PT_VAR + 13)
+#define TPM_PT_LOCKOUT_COUNTER (TPM_PT)(PT_VAR + 14)
+#define TPM_PT_MAX_AUTH_FAIL (TPM_PT)(PT_VAR + 15)
+#define TPM_PT_LOCKOUT_INTERVAL (TPM_PT)(PT_VAR + 16)
+#define TPM_PT_LOCKOUT_RECOVERY (TPM_PT)(PT_VAR + 17)
+#define TPM_PT_NV_WRITE_RECOVERY (TPM_PT)(PT_VAR + 18)
+#define TPM_PT_AUDIT_COUNTER_0 (TPM_PT)(PT_VAR + 19)
+#define TPM_PT_AUDIT_COUNTER_1 (TPM_PT)(PT_VAR + 20)
+
+// Table 23 - TPM_PT_PCR Constants
+typedef UINT32 TPM_PT_PCR;
+#define TPM_PT_PCR_FIRST (TPM_PT_PCR)(0x00000000)
+#define TPM_PT_PCR_SAVE (TPM_PT_PCR)(0x00000000)
+#define TPM_PT_PCR_EXTEND_L0 (TPM_PT_PCR)(0x00000001)
+#define TPM_PT_PCR_RESET_L0 (TPM_PT_PCR)(0x00000002)
+#define TPM_PT_PCR_EXTEND_L1 (TPM_PT_PCR)(0x00000003)
+#define TPM_PT_PCR_RESET_L1 (TPM_PT_PCR)(0x00000004)
+#define TPM_PT_PCR_EXTEND_L2 (TPM_PT_PCR)(0x00000005)
+#define TPM_PT_PCR_RESET_L2 (TPM_PT_PCR)(0x00000006)
+#define TPM_PT_PCR_EXTEND_L3 (TPM_PT_PCR)(0x00000007)
+#define TPM_PT_PCR_RESET_L3 (TPM_PT_PCR)(0x00000008)
+#define TPM_PT_PCR_EXTEND_L4 (TPM_PT_PCR)(0x00000009)
+#define TPM_PT_PCR_RESET_L4 (TPM_PT_PCR)(0x0000000A)
+#define TPM_PT_PCR_NO_INCREMENT (TPM_PT_PCR)(0x00000011)
+#define TPM_PT_PCR_DRTM_RESET (TPM_PT_PCR)(0x00000012)
+#define TPM_PT_PCR_POLICY (TPM_PT_PCR)(0x00000013)
+#define TPM_PT_PCR_AUTH (TPM_PT_PCR)(0x00000014)
+#define TPM_PT_PCR_LAST (TPM_PT_PCR)(0x00000014)
+
+// Table 24 - TPM_PS Constants
+typedef UINT32 TPM_PS;
+#define TPM_PS_MAIN (TPM_PS)(0x00000000)
+#define TPM_PS_PC (TPM_PS)(0x00000001)
+#define TPM_PS_PDA (TPM_PS)(0x00000002)
+#define TPM_PS_CELL_PHONE (TPM_PS)(0x00000003)
+#define TPM_PS_SERVER (TPM_PS)(0x00000004)
+#define TPM_PS_PERIPHERAL (TPM_PS)(0x00000005)
+#define TPM_PS_TSS (TPM_PS)(0x00000006)
+#define TPM_PS_STORAGE (TPM_PS)(0x00000007)
+#define TPM_PS_AUTHENTICATION (TPM_PS)(0x00000008)
+#define TPM_PS_EMBEDDED (TPM_PS)(0x00000009)
+#define TPM_PS_HARDCOPY (TPM_PS)(0x0000000A)
+#define TPM_PS_INFRASTRUCTURE (TPM_PS)(0x0000000B)
+#define TPM_PS_VIRTUALIZATION (TPM_PS)(0x0000000C)
+#define TPM_PS_TNC (TPM_PS)(0x0000000D)
+#define TPM_PS_MULTI_TENANT (TPM_PS)(0x0000000E)
+#define TPM_PS_TC (TPM_PS)(0x0000000F)
+
+// 7 Handles
+
+// Table 25 - Handles Types
+//
+// NOTE: Comment because it has same name as TPM1.2 (value is same, so not runtime issue)
+//
+// typedef UINT32 TPM_HANDLE;
+
+// Table 26 - TPM_HT Constants
+typedef UINT8 TPM_HT;
+#define TPM_HT_PCR (TPM_HT)(0x00)
+#define TPM_HT_NV_INDEX (TPM_HT)(0x01)
+#define TPM_HT_HMAC_SESSION (TPM_HT)(0x02)
+#define TPM_HT_LOADED_SESSION (TPM_HT)(0x02)
+#define TPM_HT_POLICY_SESSION (TPM_HT)(0x03)
+#define TPM_HT_ACTIVE_SESSION (TPM_HT)(0x03)
+#define TPM_HT_PERMANENT (TPM_HT)(0x40)
+#define TPM_HT_TRANSIENT (TPM_HT)(0x80)
+#define TPM_HT_PERSISTENT (TPM_HT)(0x81)
+
+// Table 27 - TPM_RH Constants
+typedef UINT32 TPM_RH;
+#define TPM_RH_FIRST (TPM_RH)(0x40000000)
+#define TPM_RH_SRK (TPM_RH)(0x40000000)
+#define TPM_RH_OWNER (TPM_RH)(0x40000001)
+#define TPM_RH_REVOKE (TPM_RH)(0x40000002)
+#define TPM_RH_TRANSPORT (TPM_RH)(0x40000003)
+#define TPM_RH_OPERATOR (TPM_RH)(0x40000004)
+#define TPM_RH_ADMIN (TPM_RH)(0x40000005)
+#define TPM_RH_EK (TPM_RH)(0x40000006)
+#define TPM_RH_NULL (TPM_RH)(0x40000007)
+#define TPM_RH_UNASSIGNED (TPM_RH)(0x40000008)
+#define TPM_RS_PW (TPM_RH)(0x40000009)
+#define TPM_RH_LOCKOUT (TPM_RH)(0x4000000A)
+#define TPM_RH_ENDORSEMENT (TPM_RH)(0x4000000B)
+#define TPM_RH_PLATFORM (TPM_RH)(0x4000000C)
+#define TPM_RH_PLATFORM_NV (TPM_RH)(0x4000000D)
+#define TPM_RH_AUTH_00 (TPM_RH)(0x40000010)
+#define TPM_RH_AUTH_FF (TPM_RH)(0x4000010F)
+#define TPM_RH_LAST (TPM_RH)(0x4000010F)
+
+// Table 28 - TPM_HC Constants
+typedef TPM_HANDLE TPM_HC;
+#define HR_HANDLE_MASK (TPM_HC)(0x00FFFFFF)
+#define HR_RANGE_MASK (TPM_HC)(0xFF000000)
+#define HR_SHIFT (TPM_HC)(24)
+#define HR_PCR (TPM_HC)((TPM_HC)TPM_HT_PCR << HR_SHIFT)
+#define HR_HMAC_SESSION (TPM_HC)((TPM_HC)TPM_HT_HMAC_SESSION << HR_SHIFT)
+#define HR_POLICY_SESSION (TPM_HC)((TPM_HC)TPM_HT_POLICY_SESSION << HR_SHIFT)
+#define HR_TRANSIENT (TPM_HC)((TPM_HC)TPM_HT_TRANSIENT << HR_SHIFT)
+#define HR_PERSISTENT (TPM_HC)((TPM_HC)TPM_HT_PERSISTENT << HR_SHIFT)
+#define HR_NV_INDEX (TPM_HC)((TPM_HC)TPM_HT_NV_INDEX << HR_SHIFT)
+#define HR_PERMANENT (TPM_HC)((TPM_HC)TPM_HT_PERMANENT << HR_SHIFT)
+#define PCR_FIRST (TPM_HC)(HR_PCR + 0)
+#define PCR_LAST (TPM_HC)(PCR_FIRST + IMPLEMENTATION_PCR - 1)
+#define HMAC_SESSION_FIRST (TPM_HC)(HR_HMAC_SESSION + 0)
+#define HMAC_SESSION_LAST (TPM_HC)(HMAC_SESSION_FIRST + MAX_ACTIVE_SESSIONS - 1)
+#define LOADED_SESSION_FIRST (TPM_HC)(HMAC_SESSION_FIRST)
+#define LOADED_SESSION_LAST (TPM_HC)(HMAC_SESSION_LAST)
+#define POLICY_SESSION_FIRST (TPM_HC)(HR_POLICY_SESSION + 0)
+#define POLICY_SESSION_LAST (TPM_HC)(POLICY_SESSION_FIRST + MAX_ACTIVE_SESSIONS - 1)
+#define TRANSIENT_FIRST (TPM_HC)(HR_TRANSIENT + 0)
+#define ACTIVE_SESSION_FIRST (TPM_HC)(POLICY_SESSION_FIRST)
+#define ACTIVE_SESSION_LAST (TPM_HC)(POLICY_SESSION_LAST)
+#define TRANSIENT_LAST (TPM_HC)(TRANSIENT_FIRST+MAX_LOADED_OBJECTS - 1)
+#define PERSISTENT_FIRST (TPM_HC)(HR_PERSISTENT + 0)
+#define PERSISTENT_LAST (TPM_HC)(PERSISTENT_FIRST + 0x00FFFFFF)
+#define PLATFORM_PERSISTENT (TPM_HC)(PERSISTENT_FIRST + 0x00800000)
+#define NV_INDEX_FIRST (TPM_HC)(HR_NV_INDEX + 0)
+#define NV_INDEX_LAST (TPM_HC)(NV_INDEX_FIRST + 0x00FFFFFF)
+#define PERMANENT_FIRST (TPM_HC)(TPM_RH_FIRST)
+#define PERMANENT_LAST (TPM_HC)(TPM_RH_LAST)
+
+// 8 Attribute Structures
+
+// Table 29 - TPMA_ALGORITHM Bits
+typedef struct {
+ UINT32 asymmetric : 1;
+ UINT32 symmetric : 1;
+ UINT32 hash : 1;
+ UINT32 object : 1;
+ UINT32 reserved4_7 : 4;
+ UINT32 signing : 1;
+ UINT32 encrypting : 1;
+ UINT32 method : 1;
+ UINT32 reserved11_31 : 21;
+} TPMA_ALGORITHM;
+
+// Table 30 - TPMA_OBJECT Bits
+typedef struct {
+ UINT32 reserved1 : 1;
+ UINT32 fixedTPM : 1;
+ UINT32 stClear : 1;
+ UINT32 reserved4 : 1;
+ UINT32 fixedParent : 1;
+ UINT32 sensitiveDataOrigin : 1;
+ UINT32 userWithAuth : 1;
+ UINT32 adminWithPolicy : 1;
+ UINT32 reserved8_9 : 2;
+ UINT32 noDA : 1;
+ UINT32 encryptedDuplication : 1;
+ UINT32 reserved12_15 : 4;
+ UINT32 restricted : 1;
+ UINT32 decrypt : 1;
+ UINT32 sign : 1;
+ UINT32 reserved19_31 : 13;
+} TPMA_OBJECT;
+
+// Table 31 - TPMA_SESSION Bits
+typedef struct {
+ UINT8 continueSession : 1;
+ UINT8 auditExclusive : 1;
+ UINT8 auditReset : 1;
+ UINT8 reserved3_4 : 2;
+ UINT8 decrypt : 1;
+ UINT8 encrypt : 1;
+ UINT8 audit : 1;
+} TPMA_SESSION;
+
+// Table 32 - TPMA_LOCALITY Bits
+//
+// NOTE: Use low case here to resolve conflict
+//
+typedef struct {
+ UINT8 locZero : 1;
+ UINT8 locOne : 1;
+ UINT8 locTwo : 1;
+ UINT8 locThree : 1;
+ UINT8 locFour : 1;
+ UINT8 Extended : 3;
+} TPMA_LOCALITY;
+
+// Table 33 - TPMA_PERMANENT Bits
+typedef struct {
+ UINT32 ownerAuthSet : 1;
+ UINT32 endorsementAuthSet : 1;
+ UINT32 lockoutAuthSet : 1;
+ UINT32 reserved3_7 : 5;
+ UINT32 disableClear : 1;
+ UINT32 inLockout : 1;
+ UINT32 tpmGeneratedEPS : 1;
+ UINT32 reserved11_31 : 21;
+} TPMA_PERMANENT;
+
+// Table 34 - TPMA_STARTUP_CLEAR Bits
+typedef struct {
+ UINT32 phEnable : 1;
+ UINT32 shEnable : 1;
+ UINT32 ehEnable : 1;
+ UINT32 reserved3_30 : 28;
+ UINT32 orderly : 1;
+} TPMA_STARTUP_CLEAR;
+
+// Table 35 - TPMA_MEMORY Bits
+typedef struct {
+ UINT32 sharedRAM : 1;
+ UINT32 sharedNV : 1;
+ UINT32 objectCopiedToRam : 1;
+ UINT32 reserved3_31 : 29;
+} TPMA_MEMORY;
+
+// Table 36 - TPMA_CC Bits
+typedef struct {
+ UINT32 commandIndex : 16;
+ UINT32 reserved16_21 : 6;
+ UINT32 nv : 1;
+ UINT32 extensive : 1;
+ UINT32 flushed : 1;
+ UINT32 cHandles : 3;
+ UINT32 rHandle : 1;
+ UINT32 V : 1;
+ UINT32 Res : 2;
+} TPMA_CC;
+
+// 9 Interface Types
+
+// Table 37 - TPMI_YES_NO Type
+typedef BYTE TPMI_YES_NO;
+
+// Table 38 - TPMI_DH_OBJECT Type
+typedef TPM_HANDLE TPMI_DH_OBJECT;
+
+// Table 39 - TPMI_DH_PERSISTENT Type
+typedef TPM_HANDLE TPMI_DH_PERSISTENT;
+
+// Table 40 - TPMI_DH_ENTITY Type
+typedef TPM_HANDLE TPMI_DH_ENTITY;
+
+// Table 41 - TPMI_DH_PCR Type
+typedef TPM_HANDLE TPMI_DH_PCR;
+
+// Table 42 - TPMI_SH_AUTH_SESSION Type
+typedef TPM_HANDLE TPMI_SH_AUTH_SESSION;
+
+// Table 43 - TPMI_SH_HMAC Type
+typedef TPM_HANDLE TPMI_SH_HMAC;
+
+// Table 44 - TPMI_SH_POLICY Type
+typedef TPM_HANDLE TPMI_SH_POLICY;
+
+// Table 45 - TPMI_DH_CONTEXT Type
+typedef TPM_HANDLE TPMI_DH_CONTEXT;
+
+// Table 46 - TPMI_RH_HIERARCHY Type
+typedef TPM_HANDLE TPMI_RH_HIERARCHY;
+
+// Table 47 - TPMI_RH_HIERARCHY_AUTH Type
+typedef TPM_HANDLE TPMI_RH_HIERARCHY_AUTH;
+
+// Table 48 - TPMI_RH_PLATFORM Type
+typedef TPM_HANDLE TPMI_RH_PLATFORM;
+
+// Table 49 - TPMI_RH_OWNER Type
+typedef TPM_HANDLE TPMI_RH_OWNER;
+
+// Table 50 - TPMI_RH_ENDORSEMENT Type
+typedef TPM_HANDLE TPMI_RH_ENDORSEMENT;
+
+// Table 51 - TPMI_RH_PROVISION Type
+typedef TPM_HANDLE TPMI_RH_PROVISION;
+
+// Table 52 - TPMI_RH_CLEAR Type
+typedef TPM_HANDLE TPMI_RH_CLEAR;
+
+// Table 53 - TPMI_RH_NV_AUTH Type
+typedef TPM_HANDLE TPMI_RH_NV_AUTH;
+
+// Table 54 - TPMI_RH_LOCKOUT Type
+typedef TPM_HANDLE TPMI_RH_LOCKOUT;
+
+// Table 55 - TPMI_RH_NV_INDEX Type
+typedef TPM_HANDLE TPMI_RH_NV_INDEX;
+
+// Table 56 - TPMI_ALG_HASH Type
+typedef TPM_ALG_ID TPMI_ALG_HASH;
+
+// Table 57 - TPMI_ALG_ASYM Type
+typedef TPM_ALG_ID TPMI_ALG_ASYM;
+
+// Table 58 - TPMI_ALG_SYM Type
+typedef TPM_ALG_ID TPMI_ALG_SYM;
+
+// Table 59 - TPMI_ALG_SYM_OBJECT Type
+typedef TPM_ALG_ID TPMI_ALG_SYM_OBJECT;
+
+// Table 60 - TPMI_ALG_SYM_MODE Type
+typedef TPM_ALG_ID TPMI_ALG_SYM_MODE;
+
+// Table 61 - TPMI_ALG_KDF Type
+typedef TPM_ALG_ID TPMI_ALG_KDF;
+
+// Table 62 - TPMI_ALG_SIG_SCHEME Type
+typedef TPM_ALG_ID TPMI_ALG_SIG_SCHEME;
+
+// Table 63 - TPMI_ECC_KEY_EXCHANGE Type
+typedef TPM_ALG_ID TPMI_ECC_KEY_EXCHANGE;
+
+// Table 64 - TPMI_ST_COMMAND_TAG Type
+typedef TPM_ST TPMI_ST_COMMAND_TAG;
+
+// 10 Structure Definitions
+
+// Table 65 - TPMS_ALGORITHM_DESCRIPTION Structure
+typedef struct {
+ TPM_ALG_ID alg;
+ TPMA_ALGORITHM attributes;
+} TPMS_ALGORITHM_DESCRIPTION;
+
+// Table 66 - TPMU_HA Union
+typedef union {
+ BYTE sha1[SHA1_DIGEST_SIZE];
+ BYTE sha256[SHA256_DIGEST_SIZE];
+ BYTE sm3_256[SM3_256_DIGEST_SIZE];
+ BYTE sha384[SHA384_DIGEST_SIZE];
+ BYTE sha512[SHA512_DIGEST_SIZE];
+} TPMU_HA;
+
+// Table 67 - TPMT_HA Structure
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+ TPMU_HA digest;
+} TPMT_HA;
+
+// Table 68 - TPM2B_DIGEST Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[sizeof (TPMU_HA)];
+} TPM2B_DIGEST;
+
+// Table 69 - TPM2B_DATA Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[sizeof (TPMT_HA)];
+} TPM2B_DATA;
+
+// Table 70 - TPM2B_NONCE Types
+typedef TPM2B_DIGEST TPM2B_NONCE;
+
+// Table 71 - TPM2B_AUTH Types
+typedef TPM2B_DIGEST TPM2B_AUTH;
+
+// Table 72 - TPM2B_OPERAND Types
+typedef TPM2B_DIGEST TPM2B_OPERAND;
+
+// Table 73 - TPM2B_EVENT Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[1024];
+} TPM2B_EVENT;
+
+// Table 74 - TPM2B_MAX_BUFFER Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_DIGEST_BUFFER];
+} TPM2B_MAX_BUFFER;
+
+// Table 75 - TPM2B_MAX_NV_BUFFER Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_NV_INDEX_SIZE];
+} TPM2B_MAX_NV_BUFFER;
+
+// Table 76 - TPM2B_TIMEOUT Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[sizeof (UINT64)];
+} TPM2B_TIMEOUT;
+
+// Table 77 -- TPM2B_IV Structure <I/O>
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_SYM_BLOCK_SIZE];
+} TPM2B_IV;
+
+// Table 78 - TPMU_NAME Union
+typedef union {
+ TPMT_HA digest;
+ TPM_HANDLE handle;
+} TPMU_NAME;
+
+// Table 79 - TPM2B_NAME Structure
+typedef struct {
+ UINT16 size;
+ BYTE name[sizeof (TPMU_NAME)];
+} TPM2B_NAME;
+
+// Table 80 - TPMS_PCR_SELECT Structure
+typedef struct {
+ UINT8 sizeofSelect;
+ BYTE pcrSelect[PCR_SELECT_MAX];
+} TPMS_PCR_SELECT;
+
+// Table 81 - TPMS_PCR_SELECTION Structure
+typedef struct {
+ TPMI_ALG_HASH hash;
+ UINT8 sizeofSelect;
+ BYTE pcrSelect[PCR_SELECT_MAX];
+} TPMS_PCR_SELECTION;
+
+// Table 84 - TPMT_TK_CREATION Structure
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_CREATION;
+
+// Table 85 - TPMT_TK_VERIFIED Structure
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_VERIFIED;
+
+// Table 86 - TPMT_TK_AUTH Structure
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_AUTH;
+
+// Table 87 - TPMT_TK_HASHCHECK Structure
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_HASHCHECK;
+
+// Table 88 - TPMS_ALG_PROPERTY Structure
+typedef struct {
+ TPM_ALG_ID alg;
+ TPMA_ALGORITHM algProperties;
+} TPMS_ALG_PROPERTY;
+
+// Table 89 - TPMS_TAGGED_PROPERTY Structure
+typedef struct {
+ TPM_PT property;
+ UINT32 value;
+} TPMS_TAGGED_PROPERTY;
+
+// Table 90 - TPMS_TAGGED_PCR_SELECT Structure
+typedef struct {
+ TPM_PT tag;
+ UINT8 sizeofSelect;
+ BYTE pcrSelect[PCR_SELECT_MAX];
+} TPMS_TAGGED_PCR_SELECT;
+
+// Table 91 - TPML_CC Structure
+typedef struct {
+ UINT32 count;
+ TPM_CC commandCodes[MAX_CAP_CC];
+} TPML_CC;
+
+// Table 92 - TPML_CCA Structure
+typedef struct {
+ UINT32 count;
+ TPMA_CC commandAttributes[MAX_CAP_CC];
+} TPML_CCA;
+
+// Table 93 - TPML_ALG Structure
+typedef struct {
+ UINT32 count;
+ TPM_ALG_ID algorithms[MAX_ALG_LIST_SIZE];
+} TPML_ALG;
+
+// Table 94 - TPML_HANDLE Structure
+typedef struct {
+ UINT32 count;
+ TPM_HANDLE handle[MAX_CAP_HANDLES];
+} TPML_HANDLE;
+
+// Table 95 - TPML_DIGEST Structure
+typedef struct {
+ UINT32 count;
+ TPM2B_DIGEST digests[8];
+} TPML_DIGEST;
+
+// Table 96 -- TPML_DIGEST_VALUES Structure <I/O>
+typedef struct {
+ UINT32 count;
+ TPMT_HA digests[HASH_COUNT];
+} TPML_DIGEST_VALUES;
+
+// Table 97 - TPM2B_DIGEST_VALUES Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[sizeof (TPML_DIGEST_VALUES)];
+} TPM2B_DIGEST_VALUES;
+
+// Table 98 - TPML_PCR_SELECTION Structure
+typedef struct {
+ UINT32 count;
+ TPMS_PCR_SELECTION pcrSelections[HASH_COUNT];
+} TPML_PCR_SELECTION;
+
+// Table 99 - TPML_ALG_PROPERTY Structure
+typedef struct {
+ UINT32 count;
+ TPMS_ALG_PROPERTY algProperties[MAX_CAP_ALGS];
+} TPML_ALG_PROPERTY;
+
+// Table 100 - TPML_TAGGED_TPM_PROPERTY Structure
+typedef struct {
+ UINT32 count;
+ TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES];
+} TPML_TAGGED_TPM_PROPERTY;
+
+// Table 101 - TPML_TAGGED_PCR_PROPERTY Structure
+typedef struct {
+ UINT32 count;
+ TPMS_TAGGED_PCR_SELECT pcrProperty[MAX_PCR_PROPERTIES];
+} TPML_TAGGED_PCR_PROPERTY;
+
+// Table 102 - TPML_ECC_CURVE Structure
+typedef struct {
+ UINT32 count;
+ TPM_ECC_CURVE eccCurves[MAX_ECC_CURVES];
+} TPML_ECC_CURVE;
+
+// Table 103 - TPMU_CAPABILITIES Union
+typedef union {
+ TPML_ALG_PROPERTY algorithms;
+ TPML_HANDLE handles;
+ TPML_CCA command;
+ TPML_CC ppCommands;
+ TPML_CC auditCommands;
+ TPML_PCR_SELECTION assignedPCR;
+ TPML_TAGGED_TPM_PROPERTY tpmProperties;
+ TPML_TAGGED_PCR_PROPERTY pcrProperties;
+ TPML_ECC_CURVE eccCurves;
+} TPMU_CAPABILITIES;
+
+// Table 104 - TPMS_CAPABILITY_DATA Structure
+typedef struct {
+ TPM_CAP capability;
+ TPMU_CAPABILITIES data;
+} TPMS_CAPABILITY_DATA;
+
+// Table 105 - TPMS_CLOCK_INFO Structure
+typedef struct {
+ UINT64 clock;
+ UINT32 resetCount;
+ UINT32 restartCount;
+ TPMI_YES_NO safe;
+} TPMS_CLOCK_INFO;
+
+// Table 106 - TPMS_TIME_INFO Structure
+typedef struct {
+ UINT64 time;
+ TPMS_CLOCK_INFO clockInfo;
+} TPMS_TIME_INFO;
+
+// Table 107 - TPMS_TIME_ATTEST_INFO Structure
+typedef struct {
+ TPMS_TIME_INFO time;
+ UINT64 firmwareVersion;
+} TPMS_TIME_ATTEST_INFO;
+
+// Table 108 - TPMS_CERTIFY_INFO Structure
+typedef struct {
+ TPM2B_NAME name;
+ TPM2B_NAME qualifiedName;
+} TPMS_CERTIFY_INFO;
+
+// Table 109 - TPMS_QUOTE_INFO Structure
+typedef struct {
+ TPML_PCR_SELECTION pcrSelect;
+ TPM2B_DIGEST pcrDigest;
+} TPMS_QUOTE_INFO;
+
+// Table 110 - TPMS_COMMAND_AUDIT_INFO Structure
+typedef struct {
+ UINT64 auditCounter;
+ TPM_ALG_ID digestAlg;
+ TPM2B_DIGEST auditDigest;
+ TPM2B_DIGEST commandDigest;
+} TPMS_COMMAND_AUDIT_INFO;
+
+// Table 111 - TPMS_SESSION_AUDIT_INFO Structure
+typedef struct {
+ TPMI_YES_NO exclusiveSession;
+ TPM2B_DIGEST sessionDigest;
+} TPMS_SESSION_AUDIT_INFO;
+
+// Table 112 - TPMS_CREATION_INFO Structure
+typedef struct {
+ TPM2B_NAME objectName;
+ TPM2B_DIGEST creationHash;
+} TPMS_CREATION_INFO;
+
+// Table 113 - TPMS_NV_CERTIFY_INFO Structure
+typedef struct {
+ TPM2B_NAME indexName;
+ UINT16 offset;
+ TPM2B_MAX_NV_BUFFER nvContents;
+} TPMS_NV_CERTIFY_INFO;
+
+// Table 114 - TPMI_ST_ATTEST Type
+typedef TPM_ST TPMI_ST_ATTEST;
+
+// Table 115 - TPMU_ATTEST Union
+typedef union {
+ TPMS_CERTIFY_INFO certify;
+ TPMS_CREATION_INFO creation;
+ TPMS_QUOTE_INFO quote;
+ TPMS_COMMAND_AUDIT_INFO commandAudit;
+ TPMS_SESSION_AUDIT_INFO sessionAudit;
+ TPMS_TIME_ATTEST_INFO time;
+ TPMS_NV_CERTIFY_INFO nv;
+} TPMU_ATTEST;
+
+// Table 116 - TPMS_ATTEST Structure
+typedef struct {
+ TPM_GENERATED magic;
+ TPMI_ST_ATTEST type;
+ TPM2B_NAME qualifiedSigner;
+ TPM2B_DATA extraData;
+ TPMS_CLOCK_INFO clockInfo;
+ UINT64 firmwareVersion;
+ TPMU_ATTEST attested;
+} TPMS_ATTEST;
+
+// Table 117 - TPM2B_ATTEST Structure
+typedef struct {
+ UINT16 size;
+ BYTE attestationData[sizeof (TPMS_ATTEST)];
+} TPM2B_ATTEST;
+
+// Table 118 - TPMS_AUTH_COMMAND Structure
+typedef struct {
+ TPMI_SH_AUTH_SESSION sessionHandle;
+ TPM2B_NONCE nonce;
+ TPMA_SESSION sessionAttributes;
+ TPM2B_AUTH hmac;
+} TPMS_AUTH_COMMAND;
+
+// Table 119 - TPMS_AUTH_RESPONSE Structure
+typedef struct {
+ TPM2B_NONCE nonce;
+ TPMA_SESSION sessionAttributes;
+ TPM2B_AUTH hmac;
+} TPMS_AUTH_RESPONSE;
+
+// 11 Algorithm Parameters and Structures
+
+// Table 120 - TPMI_AES_KEY_BITS Type
+typedef TPM_KEY_BITS TPMI_AES_KEY_BITS;
+
+// Table 121 - TPMI_SM4_KEY_BITS Type
+typedef TPM_KEY_BITS TPMI_SM4_KEY_BITS;
+
+// Table 122 - TPMU_SYM_KEY_BITS Union
+typedef union {
+ TPMI_AES_KEY_BITS aes;
+ TPMI_SM4_KEY_BITS SM4;
+ TPM_KEY_BITS sym;
+ TPMI_ALG_HASH xor_;
+} TPMU_SYM_KEY_BITS;
+
+// Table 123 - TPMU_SYM_MODE Union
+typedef union {
+ TPMI_ALG_SYM_MODE aes;
+ TPMI_ALG_SYM_MODE SM4;
+ TPMI_ALG_SYM_MODE sym;
+} TPMU_SYM_MODE;
+
+// Table 125 - TPMT_SYM_DEF Structure
+typedef struct {
+ TPMI_ALG_SYM algorithm;
+ TPMU_SYM_KEY_BITS keyBits;
+ TPMU_SYM_MODE mode;
+} TPMT_SYM_DEF;
+
+// Table 126 - TPMT_SYM_DEF_OBJECT Structure
+typedef struct {
+ TPMI_ALG_SYM_OBJECT algorithm;
+ TPMU_SYM_KEY_BITS keyBits;
+ TPMU_SYM_MODE mode;
+} TPMT_SYM_DEF_OBJECT;
+
+// Table 127 - TPM2B_SYM_KEY Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_SYM_KEY_BYTES];
+} TPM2B_SYM_KEY;
+
+// Table 128 - TPMS_SYMCIPHER_PARMS Structure
+typedef struct {
+ TPMT_SYM_DEF_OBJECT sym;
+} TPMS_SYMCIPHER_PARMS;
+
+// Table 129 - TPM2B_SENSITIVE_DATA Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_SYM_DATA];
+} TPM2B_SENSITIVE_DATA;
+
+// Table 130 - TPMS_SENSITIVE_CREATE Structure
+typedef struct {
+ TPM2B_AUTH userAuth;
+ TPM2B_SENSITIVE_DATA data;
+} TPMS_SENSITIVE_CREATE;
+
+// Table 131 - TPM2B_SENSITIVE_CREATE Structure
+typedef struct {
+ UINT16 size;
+ TPMS_SENSITIVE_CREATE sensitive;
+} TPM2B_SENSITIVE_CREATE;
+
+// Table 132 - TPMS_SCHEME_SIGHASH Structure
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_SIGHASH;
+
+// Table 133 - TPMI_ALG_KEYEDHASH_SCHEME Type
+typedef TPM_ALG_ID TPMI_ALG_KEYEDHASH_SCHEME;
+
+// Table 134 - HMAC_SIG_SCHEME Types
+typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_HMAC;
+
+// Table 135 - TPMS_SCHEME_XOR Structure
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+ TPMI_ALG_KDF kdf;
+} TPMS_SCHEME_XOR;
+
+// Table 136 - TPMU_SCHEME_KEYEDHASH Union
+typedef union {
+ TPMS_SCHEME_HMAC hmac;
+ TPMS_SCHEME_XOR xor_;
+} TPMU_SCHEME_KEYEDHASH;
+
+// Table 137 - TPMT_KEYEDHASH_SCHEME Structure
+typedef struct {
+ TPMI_ALG_KEYEDHASH_SCHEME scheme;
+ TPMU_SCHEME_KEYEDHASH details;
+} TPMT_KEYEDHASH_SCHEME;
+
+// Table 138 - RSA_SIG_SCHEMES Types
+typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_RSASSA;
+typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_RSAPSS;
+
+// Table 139 - ECC_SIG_SCHEMES Types
+typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_ECDSA;
+typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_SM2;
+typedef TPMS_SCHEME_SIGHASH TPMS_SCHEME_ECSCHNORR;
+
+// Table 140 - TPMS_SCHEME_ECDAA Structure
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+ UINT16 count;
+} TPMS_SCHEME_ECDAA;
+
+// Table 141 - TPMU_SIG_SCHEME Union
+typedef union {
+ TPMS_SCHEME_RSASSA rsassa;
+ TPMS_SCHEME_RSAPSS rsapss;
+ TPMS_SCHEME_ECDSA ecdsa;
+ TPMS_SCHEME_ECDAA ecdaa;
+ TPMS_SCHEME_ECSCHNORR ecSchnorr;
+ TPMS_SCHEME_HMAC hmac;
+ TPMS_SCHEME_SIGHASH any;
+} TPMU_SIG_SCHEME;
+
+// Table 142 - TPMT_SIG_SCHEME Structure
+typedef struct {
+ TPMI_ALG_SIG_SCHEME scheme;
+ TPMU_SIG_SCHEME details;
+} TPMT_SIG_SCHEME;
+
+// Table 143 - TPMS_SCHEME_OAEP Structure
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_OAEP;
+
+// Table 144 - TPMS_SCHEME_ECDH Structure
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_ECDH;
+
+// Table 145 - TPMS_SCHEME_MGF1 Structure
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_MGF1;
+
+// Table 146 - TPMS_SCHEME_KDF1_SP800_56a Structure
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_KDF1_SP800_56a;
+
+// Table 147 - TPMS_SCHEME_KDF2 Structure
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_KDF2;
+
+// Table 148 - TPMS_SCHEME_KDF1_SP800_108 Structure
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_KDF1_SP800_108;
+
+// Table 149 - TPMU_KDF_SCHEME Union
+typedef union {
+ TPMS_SCHEME_MGF1 mgf1;
+ TPMS_SCHEME_KDF1_SP800_56a kdf1_SP800_56a;
+ TPMS_SCHEME_KDF2 kdf2;
+ TPMS_SCHEME_KDF1_SP800_108 kdf1_sp800_108;
+} TPMU_KDF_SCHEME;
+
+// Table 150 - TPMT_KDF_SCHEME Structure
+typedef struct {
+ TPMI_ALG_KDF scheme;
+ TPMU_KDF_SCHEME details;
+} TPMT_KDF_SCHEME;
+
+// Table 151 - TPMI_ALG_ASYM_SCHEME Type
+typedef TPM_ALG_ID TPMI_ALG_ASYM_SCHEME;
+
+// Table 152 - TPMU_ASYM_SCHEME Union
+typedef union {
+ TPMS_SCHEME_RSASSA rsassa;
+ TPMS_SCHEME_RSAPSS rsapss;
+ TPMS_SCHEME_OAEP oaep;
+ TPMS_SCHEME_ECDSA ecdsa;
+ TPMS_SCHEME_ECDAA ecdaa;
+ TPMS_SCHEME_ECSCHNORR ecSchnorr;
+ TPMS_SCHEME_SIGHASH anySig;
+} TPMU_ASYM_SCHEME;
+
+// Table 153 - TPMT_ASYM_SCHEME Structure
+typedef struct {
+ TPMI_ALG_ASYM_SCHEME scheme;
+ TPMU_ASYM_SCHEME details;
+} TPMT_ASYM_SCHEME;
+
+// Table 154 - TPMI_ALG_RSA_SCHEME Type
+typedef TPM_ALG_ID TPMI_ALG_RSA_SCHEME;
+
+// Table 155 - TPMT_RSA_SCHEME Structure
+typedef struct {
+ TPMI_ALG_RSA_SCHEME scheme;
+ TPMU_ASYM_SCHEME details;
+} TPMT_RSA_SCHEME;
+
+// Table 156 - TPMI_ALG_RSA_DECRYPT Type
+typedef TPM_ALG_ID TPMI_ALG_RSA_DECRYPT;
+
+// Table 157 - TPMT_RSA_DECRYPT Structure
+typedef struct {
+ TPMI_ALG_RSA_DECRYPT scheme;
+ TPMU_ASYM_SCHEME details;
+} TPMT_RSA_DECRYPT;
+
+// Table 158 - TPM2B_PUBLIC_KEY_RSA Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_RSA_KEY_BYTES];
+} TPM2B_PUBLIC_KEY_RSA;
+
+// Table 159 - TPMI_RSA_KEY_BITS Type
+typedef TPM_KEY_BITS TPMI_RSA_KEY_BITS;
+
+// Table 160 - TPM2B_PRIVATE_KEY_RSA Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_RSA_KEY_BYTES/2];
+} TPM2B_PRIVATE_KEY_RSA;
+
+// Table 161 - TPM2B_ECC_PARAMETER Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_ECC_KEY_BYTES];
+} TPM2B_ECC_PARAMETER;
+
+// Table 162 - TPMS_ECC_POINT Structure
+typedef struct {
+ TPM2B_ECC_PARAMETER x;
+ TPM2B_ECC_PARAMETER y;
+} TPMS_ECC_POINT;
+
+// Table 163 -- TPM2B_ECC_POINT Structure <I/O>
+typedef struct {
+ UINT16 size;
+ TPMS_ECC_POINT point;
+} TPM2B_ECC_POINT;
+
+// Table 164 - TPMI_ALG_ECC_SCHEME Type
+typedef TPM_ALG_ID TPMI_ALG_ECC_SCHEME;
+
+// Table 165 - TPMI_ECC_CURVE Type
+typedef TPM_ECC_CURVE TPMI_ECC_CURVE;
+
+// Table 166 - TPMT_ECC_SCHEME Structure
+typedef struct {
+ TPMI_ALG_ECC_SCHEME scheme;
+ TPMU_SIG_SCHEME details;
+} TPMT_ECC_SCHEME;
+
+// Table 167 - TPMS_ALGORITHM_DETAIL_ECC Structure
+typedef struct {
+ TPM_ECC_CURVE curveID;
+ UINT16 keySize;
+ TPMT_KDF_SCHEME kdf;
+ TPMT_ECC_SCHEME sign;
+ TPM2B_ECC_PARAMETER p;
+ TPM2B_ECC_PARAMETER a;
+ TPM2B_ECC_PARAMETER b;
+ TPM2B_ECC_PARAMETER gX;
+ TPM2B_ECC_PARAMETER gY;
+ TPM2B_ECC_PARAMETER n;
+ TPM2B_ECC_PARAMETER h;
+} TPMS_ALGORITHM_DETAIL_ECC;
+
+// Table 168 - TPMS_SIGNATURE_RSASSA Structure
+typedef struct {
+ TPMI_ALG_HASH hash;
+ TPM2B_PUBLIC_KEY_RSA sig;
+} TPMS_SIGNATURE_RSASSA;
+
+// Table 169 - TPMS_SIGNATURE_RSAPSS Structure
+typedef struct {
+ TPMI_ALG_HASH hash;
+ TPM2B_PUBLIC_KEY_RSA sig;
+} TPMS_SIGNATURE_RSAPSS;
+
+// Table 170 - TPMS_SIGNATURE_ECDSA Structure
+typedef struct {
+ TPMI_ALG_HASH hash;
+ TPM2B_ECC_PARAMETER signatureR;
+ TPM2B_ECC_PARAMETER signatureS;
+} TPMS_SIGNATURE_ECDSA;
+
+// Table 171 - TPMU_SIGNATURE Union
+typedef union {
+ TPMS_SIGNATURE_RSASSA rsassa;
+ TPMS_SIGNATURE_RSAPSS rsapss;
+ TPMS_SIGNATURE_ECDSA ecdsa;
+ TPMS_SIGNATURE_ECDSA sm2;
+ TPMS_SIGNATURE_ECDSA ecdaa;
+ TPMS_SIGNATURE_ECDSA ecschnorr;
+ TPMT_HA hmac;
+ TPMS_SCHEME_SIGHASH any;
+} TPMU_SIGNATURE;
+
+// Table 172 - TPMT_SIGNATURE Structure
+typedef struct {
+ TPMI_ALG_SIG_SCHEME sigAlg;
+ TPMU_SIGNATURE signature;
+} TPMT_SIGNATURE;
+
+// Table 173 - TPMU_ENCRYPTED_SECRET Union
+typedef union {
+ BYTE ecc[sizeof (TPMS_ECC_POINT)];
+ BYTE rsa[MAX_RSA_KEY_BYTES];
+ BYTE symmetric[sizeof (TPM2B_DIGEST)];
+ BYTE keyedHash[sizeof (TPM2B_DIGEST)];
+} TPMU_ENCRYPTED_SECRET;
+
+// Table 174 - TPM2B_ENCRYPTED_SECRET Structure
+typedef struct {
+ UINT16 size;
+ BYTE secret[sizeof (TPMU_ENCRYPTED_SECRET)];
+} TPM2B_ENCRYPTED_SECRET;
+
+// 12 Key/Object Complex
+
+// Table 175 - TPMI_ALG_PUBLIC Type
+typedef TPM_ALG_ID TPMI_ALG_PUBLIC;
+
+// Table 176 - TPMU_PUBLIC_ID Union
+typedef union {
+ TPM2B_DIGEST keyedHash;
+ TPM2B_DIGEST sym;
+ TPM2B_PUBLIC_KEY_RSA rsa;
+ TPMS_ECC_POINT ecc;
+} TPMU_PUBLIC_ID;
+
+// Table 177 - TPMS_KEYEDHASH_PARMS Structure
+typedef struct {
+ TPMT_KEYEDHASH_SCHEME scheme;
+} TPMS_KEYEDHASH_PARMS;
+
+// Table 178 - TPMS_ASYM_PARMS Structure
+typedef struct {
+ TPMT_SYM_DEF_OBJECT symmetric;
+ TPMT_ASYM_SCHEME scheme;
+} TPMS_ASYM_PARMS;
+
+// Table 179 - TPMS_RSA_PARMS Structure
+typedef struct {
+ TPMT_SYM_DEF_OBJECT symmetric;
+ TPMT_RSA_SCHEME scheme;
+ TPMI_RSA_KEY_BITS keyBits;
+ UINT32 exponent;
+} TPMS_RSA_PARMS;
+
+// Table 180 - TPMS_ECC_PARMS Structure
+typedef struct {
+ TPMT_SYM_DEF_OBJECT symmetric;
+ TPMT_ECC_SCHEME scheme;
+ TPMI_ECC_CURVE curveID;
+ TPMT_KDF_SCHEME kdf;
+} TPMS_ECC_PARMS;
+
+// Table 181 - TPMU_PUBLIC_PARMS Union
+typedef union {
+ TPMS_KEYEDHASH_PARMS keyedHashDetail;
+ TPMT_SYM_DEF_OBJECT symDetail;
+ TPMS_RSA_PARMS rsaDetail;
+ TPMS_ECC_PARMS eccDetail;
+ TPMS_ASYM_PARMS asymDetail;
+} TPMU_PUBLIC_PARMS;
+
+// Table 182 - TPMT_PUBLIC_PARMS Structure
+typedef struct {
+ TPMI_ALG_PUBLIC type;
+ TPMU_PUBLIC_PARMS parameters;
+} TPMT_PUBLIC_PARMS;
+
+// Table 183 - TPMT_PUBLIC Structure
+typedef struct {
+ TPMI_ALG_PUBLIC type;
+ TPMI_ALG_HASH nameAlg;
+ TPMA_OBJECT objectAttributes;
+ TPM2B_DIGEST authPolicy;
+ TPMU_PUBLIC_PARMS parameters;
+ TPMU_PUBLIC_ID unique;
+} TPMT_PUBLIC;
+
+// Table 184 - TPM2B_PUBLIC Structure
+typedef struct {
+ UINT16 size;
+ TPMT_PUBLIC publicArea;
+} TPM2B_PUBLIC;
+
+// Table 185 - TPM2B_PRIVATE_VENDOR_SPECIFIC Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[PRIVATE_VENDOR_SPECIFIC_BYTES];
+} TPM2B_PRIVATE_VENDOR_SPECIFIC;
+
+// Table 186 - TPMU_SENSITIVE_COMPOSITE Union
+typedef union {
+ TPM2B_PRIVATE_KEY_RSA rsa;
+ TPM2B_ECC_PARAMETER ecc;
+ TPM2B_SENSITIVE_DATA bits;
+ TPM2B_SYM_KEY sym;
+ TPM2B_PRIVATE_VENDOR_SPECIFIC any;
+} TPMU_SENSITIVE_COMPOSITE;
+
+// Table 187 - TPMT_SENSITIVE Structure
+typedef struct {
+ TPMI_ALG_PUBLIC sensitiveType;
+ TPM2B_AUTH authValue;
+ TPM2B_DIGEST seedValue;
+ TPMU_SENSITIVE_COMPOSITE sensitive;
+} TPMT_SENSITIVE;
+
+// Table 188 - TPM2B_SENSITIVE Structure
+typedef struct {
+ UINT16 size;
+ TPMT_SENSITIVE sensitiveArea;
+} TPM2B_SENSITIVE;
+
+// Table 189 - _PRIVATE Structure
+typedef struct {
+ TPM2B_DIGEST integrityOuter;
+ TPM2B_DIGEST integrityInner;
+ TPMT_SENSITIVE sensitive;
+} _PRIVATE;
+
+// Table 190 - TPM2B_PRIVATE Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[sizeof (_PRIVATE)];
+} TPM2B_PRIVATE;
+
+// Table 191 - _ID_OBJECT Structure
+typedef struct {
+ TPM2B_DIGEST integrityHMAC;
+ TPM2B_DIGEST encIdentity;
+} _ID_OBJECT;
+
+// Table 192 - TPM2B_ID_OBJECT Structure
+typedef struct {
+ UINT16 size;
+ BYTE credential[sizeof (_ID_OBJECT)];
+} TPM2B_ID_OBJECT;
+
+// 13 NV Storage Structures
+
+// Table 193 - TPM_NV_INDEX Bits
+//
+// NOTE: Comment here to resolve conflict
+//
+// typedef struct {
+// UINT32 index : 22;
+// UINT32 space : 2;
+// UINT32 RH_NV : 8;
+// } TPM_NV_INDEX;
+
+// Table 195 - TPMA_NV Bits
+typedef struct {
+ UINT32 TPMA_NV_PPWRITE : 1;
+ UINT32 TPMA_NV_OWNERWRITE : 1;
+ UINT32 TPMA_NV_AUTHWRITE : 1;
+ UINT32 TPMA_NV_POLICYWRITE : 1;
+ UINT32 TPMA_NV_COUNTER : 1;
+ UINT32 TPMA_NV_BITS : 1;
+ UINT32 TPMA_NV_EXTEND : 1;
+ UINT32 reserved7_9 : 3;
+ UINT32 TPMA_NV_POLICY_DELETE : 1;
+ UINT32 TPMA_NV_WRITELOCKED : 1;
+ UINT32 TPMA_NV_WRITEALL : 1;
+ UINT32 TPMA_NV_WRITEDEFINE : 1;
+ UINT32 TPMA_NV_WRITE_STCLEAR : 1;
+ UINT32 TPMA_NV_GLOBALLOCK : 1;
+ UINT32 TPMA_NV_PPREAD : 1;
+ UINT32 TPMA_NV_OWNERREAD : 1;
+ UINT32 TPMA_NV_AUTHREAD : 1;
+ UINT32 TPMA_NV_POLICYREAD : 1;
+ UINT32 reserved20_24 : 5;
+ UINT32 TPMA_NV_NO_DA : 1;
+ UINT32 TPMA_NV_ORDERLY : 1;
+ UINT32 TPMA_NV_CLEAR_STCLEAR : 1;
+ UINT32 TPMA_NV_READLOCKED : 1;
+ UINT32 TPMA_NV_WRITTEN : 1;
+ UINT32 TPMA_NV_PLATFORMCREATE : 1;
+ UINT32 TPMA_NV_READ_STCLEAR : 1;
+} TPMA_NV;
+
+// Table 196 - TPMS_NV_PUBLIC Structure
+typedef struct {
+ TPMI_RH_NV_INDEX nvIndex;
+ TPMI_ALG_HASH nameAlg;
+ TPMA_NV attributes;
+ TPM2B_DIGEST authPolicy;
+ UINT16 dataSize;
+} TPMS_NV_PUBLIC;
+
+// Table 197 - TPM2B_NV_PUBLIC Structure
+typedef struct {
+ UINT16 size;
+ TPMS_NV_PUBLIC nvPublic;
+} TPM2B_NV_PUBLIC;
+
+// 14 Context Data
+
+// Table 198 - TPM2B_CONTEXT_SENSITIVE Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_CONTEXT_SIZE];
+} TPM2B_CONTEXT_SENSITIVE;
+
+// Table 199 - TPMS_CONTEXT_DATA Structure
+typedef struct {
+ TPM2B_DIGEST integrity;
+ TPM2B_CONTEXT_SENSITIVE encrypted;
+} TPMS_CONTEXT_DATA;
+
+// Table 200 - TPM2B_CONTEXT_DATA Structure
+typedef struct {
+ UINT16 size;
+ BYTE buffer[sizeof (TPMS_CONTEXT_DATA)];
+} TPM2B_CONTEXT_DATA;
+
+// Table 201 - TPMS_CONTEXT Structure
+typedef struct {
+ UINT64 sequence;
+ TPMI_DH_CONTEXT savedHandle;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_CONTEXT_DATA contextBlob;
+} TPMS_CONTEXT;
+
+// 15 Creation Data
+
+// Table 203 - TPMS_CREATION_DATA Structure
+typedef struct {
+ TPML_PCR_SELECTION pcrSelect;
+ TPM2B_DIGEST pcrDigest;
+ TPMA_LOCALITY locality;
+ TPM_ALG_ID parentNameAlg;
+ TPM2B_NAME parentName;
+ TPM2B_NAME parentQualifiedName;
+ TPM2B_DATA outsideInfo;
+} TPMS_CREATION_DATA;
+
+// Table 204 - TPM2B_CREATION_DATA Structure
+typedef struct {
+ UINT16 size;
+ TPMS_CREATION_DATA creationData;
+} TPM2B_CREATION_DATA;
+
+//
+// Command Header
+//
+typedef struct {
+ TPM_ST tag;
+ UINT32 paramSize;
+ TPM_CC commandCode;
+} TPM2_COMMAND_HEADER;
+
+typedef struct {
+ TPM_ST tag;
+ UINT32 paramSize;
+ TPM_RC responseCode;
+} TPM2_RESPONSE_HEADER;
+
+#pragma pack ()
+
+//
+// TCG Algorithm Registry
+//
+#define HASH_ALG_SHA1 0x00000001
+#define HASH_ALG_SHA256 0x00000002
+#define HASH_ALG_SHA384 0x00000004
+#define HASH_ALG_SHA512 0x00000008
+#define HASH_ALG_SM3_256 0x00000010
+
+#endif
diff --git a/sys/contrib/edk2/Include/IndustryStandard/UefiTcgPlatform.h b/sys/contrib/edk2/Include/IndustryStandard/UefiTcgPlatform.h new file mode 100644 index 000000000000..272e224052ad --- /dev/null +++ b/sys/contrib/edk2/Include/IndustryStandard/UefiTcgPlatform.h @@ -0,0 +1,722 @@ +/** @file
+ TCG EFI Platform Definition in TCG_EFI_Platform_1_20_Final and
+ TCG PC Client Platform Firmware Profile Specification, Revision 1.06
+
+ Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __UEFI_TCG_PLATFORM_H__
+#define __UEFI_TCG_PLATFORM_H__
+
+#include <IndustryStandard/Tpm12.h>
+#include <IndustryStandard/Tpm20.h>
+#include <Uefi.h>
+
+//
+// Standard event types
+//
+#define EV_PREBOOT_CERT ((TCG_EVENTTYPE) 0x00000000)
+#define EV_POST_CODE ((TCG_EVENTTYPE) 0x00000001)
+#define EV_NO_ACTION ((TCG_EVENTTYPE) 0x00000003)
+#define EV_SEPARATOR ((TCG_EVENTTYPE) 0x00000004)
+#define EV_ACTION ((TCG_EVENTTYPE) 0x00000005)
+#define EV_EVENT_TAG ((TCG_EVENTTYPE) 0x00000006)
+#define EV_S_CRTM_CONTENTS ((TCG_EVENTTYPE) 0x00000007)
+#define EV_S_CRTM_VERSION ((TCG_EVENTTYPE) 0x00000008)
+#define EV_CPU_MICROCODE ((TCG_EVENTTYPE) 0x00000009)
+#define EV_PLATFORM_CONFIG_FLAGS ((TCG_EVENTTYPE) 0x0000000A)
+#define EV_TABLE_OF_DEVICES ((TCG_EVENTTYPE) 0x0000000B)
+#define EV_COMPACT_HASH ((TCG_EVENTTYPE) 0x0000000C)
+#define EV_NONHOST_CODE ((TCG_EVENTTYPE) 0x0000000F)
+#define EV_NONHOST_CONFIG ((TCG_EVENTTYPE) 0x00000010)
+#define EV_NONHOST_INFO ((TCG_EVENTTYPE) 0x00000011)
+#define EV_OMIT_BOOT_DEVICE_EVENTS ((TCG_EVENTTYPE) 0x00000012)
+
+//
+// EFI specific event types
+//
+#define EV_EFI_EVENT_BASE ((TCG_EVENTTYPE) 0x80000000)
+#define EV_EFI_VARIABLE_DRIVER_CONFIG (EV_EFI_EVENT_BASE + 1)
+#define EV_EFI_VARIABLE_BOOT (EV_EFI_EVENT_BASE + 2)
+#define EV_EFI_BOOT_SERVICES_APPLICATION (EV_EFI_EVENT_BASE + 3)
+#define EV_EFI_BOOT_SERVICES_DRIVER (EV_EFI_EVENT_BASE + 4)
+#define EV_EFI_RUNTIME_SERVICES_DRIVER (EV_EFI_EVENT_BASE + 5)
+#define EV_EFI_GPT_EVENT (EV_EFI_EVENT_BASE + 6)
+#define EV_EFI_ACTION (EV_EFI_EVENT_BASE + 7)
+#define EV_EFI_PLATFORM_FIRMWARE_BLOB (EV_EFI_EVENT_BASE + 8)
+#define EV_EFI_HANDOFF_TABLES (EV_EFI_EVENT_BASE + 9)
+#define EV_EFI_PLATFORM_FIRMWARE_BLOB2 (EV_EFI_EVENT_BASE + 0xA)
+#define EV_EFI_HANDOFF_TABLES2 (EV_EFI_EVENT_BASE + 0xB)
+#define EV_EFI_HCRTM_EVENT (EV_EFI_EVENT_BASE + 0x10)
+#define EV_EFI_VARIABLE_AUTHORITY (EV_EFI_EVENT_BASE + 0xE0)
+#define EV_EFI_SPDM_FIRMWARE_BLOB (EV_EFI_EVENT_BASE + 0xE1)
+#define EV_EFI_SPDM_FIRMWARE_CONFIG (EV_EFI_EVENT_BASE + 0xE2)
+#define EV_EFI_SPDM_DEVICE_BLOB EV_EFI_SPDM_FIRMWARE_BLOB
+#define EV_EFI_SPDM_DEVICE_CONFIG EV_EFI_SPDM_FIRMWARE_CONFIG
+//
+// The SPDM policy database for SPDM verification.
+// It goes to PCR7
+//
+#define EV_EFI_SPDM_DEVICE_POLICY (EV_EFI_EVENT_BASE + 0xE3)
+//
+// The SPDM policy authority for SPDM verification for the signature
+// of GET_MEASUREMENT or CHALLENGE_AUTH. It goes to PCR7.
+//
+#define EV_EFI_SPDM_DEVICE_AUTHORITY (EV_EFI_EVENT_BASE + 0xE4)
+
+#define EFI_CALLING_EFI_APPLICATION \
+ "Calling EFI Application from Boot Option"
+#define EFI_RETURNING_FROM_EFI_APPLICATION \
+ "Returning from EFI Application from Boot Option"
+#define EFI_EXIT_BOOT_SERVICES_INVOCATION \
+ "Exit Boot Services Invocation"
+#define EFI_EXIT_BOOT_SERVICES_FAILED \
+ "Exit Boot Services Returned with Failure"
+#define EFI_EXIT_BOOT_SERVICES_SUCCEEDED \
+ "Exit Boot Services Returned with Success"
+
+#define EV_POSTCODE_INFO_POST_CODE "POST CODE"
+#define POST_CODE_STR_LEN (sizeof(EV_POSTCODE_INFO_POST_CODE) - 1)
+
+#define EV_POSTCODE_INFO_SMM_CODE "SMM CODE"
+#define SMM_CODE_STR_LEN (sizeof(EV_POSTCODE_INFO_SMM_CODE) - 1)
+
+#define EV_POSTCODE_INFO_ACPI_DATA "ACPI DATA"
+#define ACPI_DATA_LEN (sizeof(EV_POSTCODE_INFO_ACPI_DATA) - 1)
+
+#define EV_POSTCODE_INFO_BIS_CODE "BIS CODE"
+#define BIS_CODE_LEN (sizeof(EV_POSTCODE_INFO_BIS_CODE) - 1)
+
+#define EV_POSTCODE_INFO_UEFI_PI "UEFI PI"
+#define UEFI_PI_LEN (sizeof(EV_POSTCODE_INFO_UEFI_PI) - 1)
+
+#define EV_POSTCODE_INFO_OPROM "Embedded Option ROM"
+#define OPROM_LEN (sizeof(EV_POSTCODE_INFO_OPROM) - 1)
+
+#define EV_POSTCODE_INFO_EMBEDDED_UEFI_DRIVER "Embedded UEFI Driver"
+#define EMBEDDED_UEFI_DRIVER_LEN (sizeof(EV_POSTCODE_INFO_EMBEDDED_UEFI_DRIVER) - 1)
+
+#define FIRMWARE_DEBUGGER_EVENT_STRING "UEFI Debug Mode"
+#define FIRMWARE_DEBUGGER_EVENT_STRING_LEN (sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1)
+
+//
+// Set structure alignment to 1-byte
+//
+#pragma pack (1)
+
+typedef UINT32 TCG_EVENTTYPE;
+typedef TPM_PCRINDEX TCG_PCRINDEX;
+typedef TPM_DIGEST TCG_DIGEST;
+///
+/// Event Log Entry Structure Definition
+///
+typedef struct tdTCG_PCR_EVENT {
+ TCG_PCRINDEX PCRIndex; ///< PCRIndex event extended to
+ TCG_EVENTTYPE EventType; ///< TCG EFI event type
+ TCG_DIGEST Digest; ///< Value extended into PCRIndex
+ UINT32 EventSize; ///< Size of the event data
+ UINT8 Event[1]; ///< The event data
+} TCG_PCR_EVENT;
+
+#define TSS_EVENT_DATA_MAX_SIZE 256
+
+///
+/// TCG_PCR_EVENT_HDR
+///
+typedef struct tdTCG_PCR_EVENT_HDR {
+ TCG_PCRINDEX PCRIndex;
+ TCG_EVENTTYPE EventType;
+ TCG_DIGEST Digest;
+ UINT32 EventSize;
+} TCG_PCR_EVENT_HDR;
+
+///
+/// EFI_PLATFORM_FIRMWARE_BLOB
+///
+/// BlobLength should be of type UINTN but we use UINT64 here
+/// because PEI is 32-bit while DXE is 64-bit on x64 platforms
+///
+typedef struct tdEFI_PLATFORM_FIRMWARE_BLOB {
+ EFI_PHYSICAL_ADDRESS BlobBase;
+ UINT64 BlobLength;
+} EFI_PLATFORM_FIRMWARE_BLOB;
+
+///
+/// UEFI_PLATFORM_FIRMWARE_BLOB
+///
+/// This structure is used in EV_EFI_PLATFORM_FIRMWARE_BLOB
+/// event to facilitate the measurement of firmware volume.
+///
+typedef struct tdUEFI_PLATFORM_FIRMWARE_BLOB {
+ EFI_PHYSICAL_ADDRESS BlobBase;
+ UINT64 BlobLength;
+} UEFI_PLATFORM_FIRMWARE_BLOB;
+
+///
+/// UEFI_PLATFORM_FIRMWARE_BLOB2
+///
+/// This structure is used in EV_EFI_PLATFORM_FIRMWARE_BLOB2
+/// event to facilitate the measurement of firmware volume.
+///
+typedef struct tdUEFI_PLATFORM_FIRMWARE_BLOB2 {
+ UINT8 BlobDescriptionSize;
+ // UINT8 BlobDescription[BlobDescriptionSize];
+ // EFI_PHYSICAL_ADDRESS BlobBase;
+ // UINT64 BlobLength;
+} UEFI_PLATFORM_FIRMWARE_BLOB2;
+
+///
+/// EFI_IMAGE_LOAD_EVENT
+///
+/// This structure is used in EV_EFI_BOOT_SERVICES_APPLICATION,
+/// EV_EFI_BOOT_SERVICES_DRIVER and EV_EFI_RUNTIME_SERVICES_DRIVER
+///
+typedef struct tdEFI_IMAGE_LOAD_EVENT {
+ EFI_PHYSICAL_ADDRESS ImageLocationInMemory;
+ UINTN ImageLengthInMemory;
+ UINTN ImageLinkTimeAddress;
+ UINTN LengthOfDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL DevicePath[1];
+} EFI_IMAGE_LOAD_EVENT;
+
+///
+/// UEFI_IMAGE_LOAD_EVENT
+///
+/// This structure is used in EV_EFI_BOOT_SERVICES_APPLICATION,
+/// EV_EFI_BOOT_SERVICES_DRIVER and EV_EFI_RUNTIME_SERVICES_DRIVER
+///
+typedef struct tdUEFI_IMAGE_LOAD_EVENT {
+ EFI_PHYSICAL_ADDRESS ImageLocationInMemory;
+ UINT64 ImageLengthInMemory;
+ UINT64 ImageLinkTimeAddress;
+ UINT64 LengthOfDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL DevicePath[1];
+} UEFI_IMAGE_LOAD_EVENT;
+
+///
+/// EFI_HANDOFF_TABLE_POINTERS
+///
+/// This structure is used in EV_EFI_HANDOFF_TABLES event to facilitate
+/// the measurement of given configuration tables.
+///
+typedef struct tdEFI_HANDOFF_TABLE_POINTERS {
+ UINTN NumberOfTables;
+ EFI_CONFIGURATION_TABLE TableEntry[1];
+} EFI_HANDOFF_TABLE_POINTERS;
+
+///
+/// UEFI_HANDOFF_TABLE_POINTERS
+///
+/// This structure is used in EV_EFI_HANDOFF_TABLES event to facilitate
+/// the measurement of given configuration tables.
+///
+typedef struct tdUEFI_HANDOFF_TABLE_POINTERS {
+ UINT64 NumberOfTables;
+ EFI_CONFIGURATION_TABLE TableEntry[1];
+} UEFI_HANDOFF_TABLE_POINTERS;
+
+///
+/// UEFI_HANDOFF_TABLE_POINTERS2
+///
+/// This structure is used in EV_EFI_HANDOFF_TABLES2 event to facilitate
+/// the measurement of given configuration tables.
+///
+typedef struct tdUEFI_HANDOFF_TABLE_POINTERS2 {
+ UINT8 TableDescriptionSize;
+ // UINT8 TableDescription[TableDescriptionSize];
+ // UINT64 NumberOfTables;
+ // EFI_CONFIGURATION_TABLE TableEntry[1];
+} UEFI_HANDOFF_TABLE_POINTERS2;
+
+///
+/// EFI_VARIABLE_DATA
+///
+/// This structure serves as the header for measuring variables. The name of the
+/// variable (in Unicode format) should immediately follow, then the variable
+/// data.
+/// This is defined in TCG EFI Platform Spec for TPM1.1 or 1.2 V1.22
+///
+typedef struct tdEFI_VARIABLE_DATA {
+ EFI_GUID VariableName;
+ UINTN UnicodeNameLength;
+ UINTN VariableDataLength;
+ CHAR16 UnicodeName[1];
+ INT8 VariableData[1]; ///< Driver or platform-specific data
+} EFI_VARIABLE_DATA;
+
+///
+/// UEFI_VARIABLE_DATA
+///
+/// This structure serves as the header for measuring variables. The name of the
+/// variable (in Unicode format) should immediately follow, then the variable
+/// data.
+/// This is defined in TCG PC Client Firmware Profile Spec 00.21
+///
+typedef struct tdUEFI_VARIABLE_DATA {
+ EFI_GUID VariableName;
+ UINT64 UnicodeNameLength;
+ UINT64 VariableDataLength;
+ CHAR16 UnicodeName[1];
+ INT8 VariableData[1]; ///< Driver or platform-specific data
+} UEFI_VARIABLE_DATA;
+
+//
+// For TrEE1.0 compatibility
+//
+typedef struct {
+ EFI_GUID VariableName;
+ UINT64 UnicodeNameLength; // The TCG Definition used UINTN
+ UINT64 VariableDataLength; // The TCG Definition used UINTN
+ CHAR16 UnicodeName[1];
+ INT8 VariableData[1];
+} EFI_VARIABLE_DATA_TREE;
+
+typedef struct tdEFI_GPT_DATA {
+ EFI_PARTITION_TABLE_HEADER EfiPartitionHeader;
+ UINTN NumberOfPartitions;
+ EFI_PARTITION_ENTRY Partitions[1];
+} EFI_GPT_DATA;
+
+typedef struct tdUEFI_GPT_DATA {
+ EFI_PARTITION_TABLE_HEADER EfiPartitionHeader;
+ UINT64 NumberOfPartitions;
+ EFI_PARTITION_ENTRY Partitions[1];
+} UEFI_GPT_DATA;
+
+#define TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE "SPDM Device Sec"
+#define TCG_DEVICE_SECURITY_EVENT_DATA_VERSION 1
+
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_NULL 0
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI 1
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_USB 2
+
+///
+/// TCG_DEVICE_SECURITY_EVENT_DATA_HEADER
+/// This is the header of TCG_DEVICE_SECURITY_EVENT_DATA, which is
+/// used in EV_EFI_SPDM_FIRMWARE_BLOB and EV_EFI_SPDM_FIRMWARE_CONFIG.
+///
+typedef struct {
+ UINT8 Signature[16];
+ UINT16 Version;
+ UINT16 Length;
+ UINT32 SpdmHashAlgo;
+ UINT32 DeviceType;
+ // SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock;
+} TCG_DEVICE_SECURITY_EVENT_DATA_HEADER;
+
+#define TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_VERSION 0
+
+///
+/// TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT
+/// This is the PCI context data of TCG_DEVICE_SECURITY_EVENT_DATA, which is
+/// used in EV_EFI_SPDM_FIRMWARE_BLOB and EV_EFI_SPDM_FIRMWARE_CONFIG.
+///
+typedef struct {
+ UINT16 Version;
+ UINT16 Length;
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT8 RevisionID;
+ UINT8 ClassCode[3];
+ UINT16 SubsystemVendorID;
+ UINT16 SubsystemID;
+} TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT;
+
+#define TCG_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT_VERSION 0
+
+///
+/// TCG_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT
+/// This is the USB context data of TCG_DEVICE_SECURITY_EVENT_DATA, which is
+/// used in EV_EFI_SPDM_FIRMWARE_BLOB and EV_EFI_SPDM_FIRMWARE_CONFIG.
+///
+typedef struct {
+ UINT16 Version;
+ UINT16 Length;
+ // UINT8 DeviceDescriptor[DescLen];
+ // UINT8 BodDescriptor[DescLen];
+ // UINT8 ConfigurationDescriptor[DescLen][NumOfConfiguration];
+} TCG_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT;
+
+//
+// Crypto Agile Log Entry Format
+//
+typedef struct tdTCG_PCR_EVENT2 {
+ TCG_PCRINDEX PCRIndex;
+ TCG_EVENTTYPE EventType;
+ TPML_DIGEST_VALUES Digest;
+ UINT32 EventSize;
+ UINT8 Event[1];
+} TCG_PCR_EVENT2;
+
+//
+// TCG PCR Event2 Header
+// Follow TCG EFI Protocol Spec 5.2 Crypto Agile Log Entry Format
+//
+typedef struct tdTCG_PCR_EVENT2_HDR {
+ TCG_PCRINDEX PCRIndex;
+ TCG_EVENTTYPE EventType;
+ TPML_DIGEST_VALUES Digests;
+ UINT32 EventSize;
+} TCG_PCR_EVENT2_HDR;
+
+//
+// Log Header Entry Data
+//
+typedef struct {
+ //
+ // TCG defined hashing algorithm ID.
+ //
+ UINT16 algorithmId;
+ //
+ // The size of the digest for the respective hashing algorithm.
+ //
+ UINT16 digestSize;
+} TCG_EfiSpecIdEventAlgorithmSize;
+
+#define TCG_EfiSpecIDEventStruct_SIGNATURE_02 "Spec ID Event02"
+#define TCG_EfiSpecIDEventStruct_SIGNATURE_03 "Spec ID Event03"
+
+#define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM12 1
+#define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM12 2
+#define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM12 2
+
+#define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2 2
+#define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2 0
+#define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2 0
+#define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105 105
+#define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_106 106
+
+typedef struct {
+ UINT8 signature[16];
+ //
+ // The value for the Platform Class.
+ // The enumeration is defined in the TCG ACPI Specification Client Common Header.
+ //
+ UINT32 platformClass;
+ //
+ // The TCG EFI Platform Specification minor version number this BIOS supports.
+ // Any BIOS supporting version (1.22) MUST set this value to 02h.
+ // Any BIOS supporting version (2.0) SHALL set this value to 0x00.
+ //
+ UINT8 specVersionMinor;
+ //
+ // The TCG EFI Platform Specification major version number this BIOS supports.
+ // Any BIOS supporting version (1.22) MUST set this value to 01h.
+ // Any BIOS supporting version (2.0) SHALL set this value to 0x02.
+ //
+ UINT8 specVersionMajor;
+ //
+ // The TCG EFI Platform Specification errata for this specification this BIOS supports.
+ // Any BIOS supporting version and errata (1.22) MUST set this value to 02h.
+ // Any BIOS supporting version and errata (2.0) SHALL set this value to 0x00.
+ //
+ UINT8 specErrata;
+ //
+ // Specifies the size of the UINTN fields used in various data structures used in this specification.
+ // 0x01 indicates UINT32 and 0x02 indicates UINT64.
+ //
+ UINT8 uintnSize;
+ //
+ // This field is added in "Spec ID Event03".
+ // The number of hashing algorithms used in this event log (except the first event).
+ // All events in this event log use all hashing algorithms defined here.
+ //
+ UINT32 numberOfAlgorithms;
+ //
+ // This field is added in "Spec ID Event03".
+ // An array of size numberOfAlgorithms of value pairs.
+ //
+ //TCG_EfiSpecIdEventAlgorithmSize digestSize[numberOfAlgorithms];
+ TCG_EfiSpecIdEventAlgorithmSize digestSize[];
+ //
+ // Size in bytes of the VendorInfo field.
+ // Maximum value SHALL be FFh bytes.
+ //
+ //UINT8 vendorInfoSize;
+ //
+ // Provided for use by the BIOS implementer.
+ // The value might be used, for example, to provide more detailed information about the specific BIOS such as BIOS revision numbers, etc.
+ // The values within this field are not standardized and are implementer-specific.
+ // Platform-specific or -unique information SHALL NOT be provided in this field.
+ //
+ //UINT8 vendorInfo[vendorInfoSize];
+} TCG_EfiSpecIDEventStruct;
+
+typedef struct tdTCG_PCClientTaggedEvent {
+ UINT32 taggedEventID;
+ UINT32 taggedEventDataSize;
+ // UINT8 taggedEventData[taggedEventDataSize];
+} TCG_PCClientTaggedEvent;
+
+#define TCG_Sp800_155_PlatformId_Event_SIGNATURE "SP800-155 Event"
+#define TCG_Sp800_155_PlatformId_Event2_SIGNATURE "SP800-155 Event2"
+#define TCG_Sp800_155_PlatformId_Event3_SIGNATURE "SP800-155 Event3"
+
+typedef struct tdTCG_Sp800_155_PlatformId_Event2 {
+ UINT8 Signature[16];
+ //
+ // Where Vendor ID is an integer defined
+ // at http://www.iana.org/assignments/enterprisenumbers
+ //
+ UINT32 VendorId;
+ //
+ // 16-byte identifier of a given platform's static configuration of code
+ //
+ EFI_GUID ReferenceManifestGuid;
+ //
+ // Below structure is newly added in TCG_Sp800_155_PlatformId_Event2.
+ //
+ // UINT8 PlatformManufacturerStrSize;
+ // UINT8 PlatformManufacturerStr[PlatformManufacturerStrSize];
+ // UINT8 PlatformModelSize;
+ // UINT8 PlatformModel[PlatformModelSize];
+ // UINT8 PlatformVersionSize;
+ // UINT8 PlatformVersion[PlatformVersionSize];
+ // UINT8 FirmwareManufacturerStrSize;
+ // UINT8 FirmwareManufacturerStr[FirmwareManufacturerStrSize];
+ // UINT32 FirmwareManufacturerId;
+ // UINT8 FirmwareVersion;
+ // UINT8 FirmwareVersion[FirmwareVersionSize];
+} TCG_Sp800_155_PlatformId_Event2;
+
+typedef struct tdTCG_Sp800_155_PlatformId_Event3 {
+ UINT8 Signature[16];
+ //
+ // Where Vendor ID is an integer defined
+ // at http://www.iana.org/assignments/enterprisenumbers
+ //
+ UINT32 VendorId;
+ //
+ // 16-byte identifier of a given platform's static configuration of code
+ //
+ EFI_GUID ReferenceManifestGuid;
+ // UINT8 PlatformManufacturerStrSize;
+ // UINT8 PlatformManufacturerStr[PlatformManufacturerStrSize];
+ // UINT8 PlatformModelSize;
+ // UINT8 PlatformModel[PlatformModelSize];
+ // UINT8 PlatformVersionSize;
+ // UINT8 PlatformVersion[PlatformVersionSize];
+ // UINT8 FirmwareManufacturerStrSize;
+ // UINT8 FirmwareManufacturerStr[FirmwareManufacturerStrSize];
+ // UINT32 FirmwareManufacturerId;
+ // UINT8 FirmwareVersion;
+ // UINT8 FirmwareVersion[FirmwareVersionSize];
+ //
+ // Below structure is newly added in TCG_Sp800_155_PlatformId_Event3
+ //
+ // UINT32 RimLocatorType;
+ // UINT32 RimLocatorLength;
+ // UINT8 RimLocator[RimLocatorLength];
+ // UINT32 PlatformCertLocatorType;
+ // UINT32 PlatformCertLocatorLength;
+ // UINT8 PlatformCertLocator[PlatformCertLocatorLength];
+} TCG_Sp800_155_PlatformId_Event3;
+
+/**
+ * TCG specifies a locator type with the following values
+ * 0 - Raw data in the locator itself.
+ * 1 - URI in rtf2396 format.
+ * 2 - local device path in EFI_DEVICE_PATH_PROTOCOL format.
+ * 3 - UEFI variable (16 byte EFI_GUID, then 00-terminated UCS2 string)
+**/
+#define TCG_LOCATOR_TYPE_RAW_DATA 0
+#define TCG_LOCATOR_TYPE_URI 1
+#define TCG_LOCATOR_TYPE_DEVICE_PATH 2
+#define TCG_LOCATOR_TYPE_UEFI_VARIABLE 3
+
+#define TCG_EfiStartupLocalityEvent_SIGNATURE "StartupLocality"
+
+//
+// The Locality Indicator which sent the TPM2_Startup command
+//
+#define LOCALITY_0_INDICATOR 0x00
+#define LOCALITY_3_INDICATOR 0x03
+
+//
+// Startup Locality Event
+//
+typedef struct tdTCG_EfiStartupLocalityEvent {
+ UINT8 Signature[16];
+ //
+ // The Locality Indicator which sent the TPM2_Startup command
+ //
+ UINT8 StartupLocality;
+} TCG_EfiStartupLocalityEvent;
+
+//
+// Restore original structure alignment
+//
+#pragma pack ()
+
+//
+// ======================================================================================================================
+// Event Type PCR Event Log Usage
+// ======================================================================================================================
+// EV_EFI_SPDM_DEVICE_BLOB 2 SPDM_MEASUREMENT_BLOCK (subtype) MEASUREMENT from device
+// EV_EFI_SPDM_DEVICE_CONFIG 3 SPDM_MEASUREMENT_BLOCK (subtype) MEASUREMENT from device
+// EV_EFI_SPDM_DEVICE_BLOB 2 SPDM_MEASUREMENT_SUMMARY_HASH.TCB (subtype) SUMMARY_HASH from device
+
+// EV_EFI_SPDM_DEVICE_POLICY 7 UEFI_VARIABLE_DATA with EFI_SIGNATURE_LIST Provisioned device public cert.
+// EV_EFI_SPDM_DEVICE_AUTHORITY 7 UEFI_VARIABLE_DATA with EFI_SIGNATURE_DATA CHALLENGE_AUTH signature verification
+// ======================================================================================================================
+//
+
+#define PCR_INDEX_FOR_SIGNATURE_DB 7
+
+#pragma pack(1)
+
+#define TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_1 1
+#define TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2 2
+#define TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2 "SPDM Device Sec2"
+
+typedef struct {
+ UINT8 Signature[16];
+ UINT16 Version;
+ UINT8 AuthState;
+ UINT8 Reserved;
+ UINT32 Length; // Length in bytes for all following structures.
+ UINT32 DeviceType;
+ UINT32 SubHeaderType;
+ UINT32 SubHeaderLength; // Length in bytes of the sub header followed by.
+ UINT64 SubHeaderUID; // Universal identifier assigned by the event log creator. It can be used to bind two sub header structure together.
+ // UINT64 DevicePathLength;
+ // UINT8 DevicePath[DevicePathLength];
+} TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2;
+
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS 0
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_AUTH 1
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_BINDING 2
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG 3
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID 4
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_SPDM 0xFF
+
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_MEASUREMENT_BLOCK 0
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_CERT_CHAIN 1
+
+typedef struct {
+ UINT16 SpdmVersion;
+ UINT8 SpdmMeasurementBlockCount;
+ UINT8 Reserved;
+ UINT32 SpdmMeasurementHashAlgo;
+ // SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock;
+} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK;
+
+typedef struct {
+ UINT16 SpdmVersion;
+ UINT8 SpdmSlotId;
+ UINT8 Reserved;
+ UINT32 SpdmHashAlgo;
+ // SPDM_CERT_CHAIN SpdmCertChain;
+} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN;
+
+typedef struct {
+ UINT32 Type;
+ UINT32 Length;
+ UINT8 Value[1];
+} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_OEM_MEASUREMENT;
+
+typedef union {
+ TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK SpdmMeasurementBlock;
+ TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN SpdmCertChain;
+ TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_OEM_MEASUREMENT OemMeasurement;
+} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER;
+
+typedef union {
+ TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT Pci;
+ TCG_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT Usb;
+} TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT;
+
+typedef struct {
+ TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2 EventDataHeader;
+ TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER EventDataSubHeader;
+ TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT DeviceContext;
+} TCG_DEVICE_SECURITY_EVENT_DATA2;
+
+#pragma pack()
+
+//
+// EventType:EV_NO_ACTION
+// ======================================================================================================================
+// NVIndex Name PCR/NvIndex Event Log Usage
+// ======================================================================================================================
+// NV_EXTEND_INDEX_FOR_INSTANCE 0x01C40200 NV_INDEX_INSTANCE_EVENT_LOG_STRUCT NV Extend Record for instance data (CertChain)
+// NV_EXTEND_INDEX_FOR_DYNAMIC 0x01C40201 NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT NV Extend Record for dynamic data (Nonce)
+
+// EVENT_LOG_INTEGRITY_NV_INDEX_EXIT_PM_AUTH 0x01C40202 EVENT_LOG_INTEGRITY_NV_INDEX_STRUCT Event Log Integrity for ExitPmAuth
+// EVENT_LOG_INTEGRITY_NV_INDEX_READY_TO_BOOT 0x01C40203 EVENT_LOG_INTEGRITY_NV_INDEX_STRUCT Event Log Integrity for ReadyToBoot
+// ======================================================================================================================
+//
+
+#define TCG_NV_EXTEND_INDEX_FOR_INSTANCE 0x01C40200
+#define TCG_NV_EXTEND_INDEX_FOR_DYNAMIC 0x01C40201
+#define TCG_EVENT_LOG_INTEGRITY_NV_INDEX_EXIT_PM_AUTH 0x01C40202
+#define TCG_EVENT_LOG_INTEGRITY_NV_INDEX_READY_TO_BOOT 0x01C40203
+
+#pragma pack(1)
+
+#define TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE "NvIndexInstance"
+#define TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_VERSION 1
+
+typedef struct {
+ UINT8 Signature[16];
+ UINT16 Version;
+ UINT8 Reserved[6];
+ // TCG_DEVICE_SECURITY_EVENT_DATA2 Data;
+} TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT;
+
+#define TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE "NvIndexDynamic "
+#define TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION 1
+
+#define TCG_SPDM_CHALLENGE_DESCRIPTION "SPDM CHALLENGE"
+#define TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION "SPDM CHALLENGE_AUTH"
+#define TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION "SPDM GET_MEASUREMENTS"
+#define TCG_SPDM_MEASUREMENTS_DESCRIPTION "SPDM MEASUREMENTS"
+
+typedef struct {
+ UINT8 Signature[16];
+ UINT16 Version;
+ UINT8 Reserved[6];
+ UINT64 Uid;
+ // UINT16 DescriptionSize;
+ // UINT8 Description[DescriptionSize];
+ // UINT16 DataSize;
+ // UINT8 Data[DataSize];
+} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT;
+
+typedef struct {
+ TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT Header;
+ UINT16 DescriptionSize;
+ UINT8 Description[sizeof (TCG_SPDM_CHALLENGE_DESCRIPTION)];
+ UINT16 DataSize;
+ UINT8 Data[32];
+} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE;
+
+typedef struct {
+ TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT Header;
+ UINT16 DescriptionSize;
+ UINT8 Description[sizeof (TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION)];
+ UINT16 DataSize;
+ UINT8 Data[32];
+} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE_AUTH;
+
+typedef struct {
+ TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT Header;
+ UINT16 DescriptionSize;
+ UINT8 Description[sizeof (TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION)];
+ UINT16 DataSize;
+ UINT8 Data[32];
+} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_GET_MEASUREMENTS;
+
+typedef struct {
+ TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT Header;
+ UINT16 DescriptionSize;
+ UINT8 Description[sizeof (TCG_SPDM_MEASUREMENTS_DESCRIPTION)];
+ UINT16 DataSize;
+ UINT8 Data[32];
+} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_MEASUREMENTS;
+
+#pragma pack()
+
+#endif
diff --git a/sys/contrib/edk2/Include/IndustryStandard/Usb.h b/sys/contrib/edk2/Include/IndustryStandard/Usb.h new file mode 100644 index 000000000000..a8dfe62ca77f --- /dev/null +++ b/sys/contrib/edk2/Include/IndustryStandard/Usb.h @@ -0,0 +1,397 @@ +/** @file + Support for USB 2.0 standard. + + Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2024, American Megatrends International LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __USB_H__ +#define __USB_H__ + +// +// Subset of Class and Subclass definitions from USB Specs +// + +// +// Usb mass storage class code +// +#define USB_MASS_STORE_CLASS 0x08 + +// +// Usb mass storage subclass code, specify the command set used. +// +#define USB_MASS_STORE_RBC 0x01 ///< Reduced Block Commands +#define USB_MASS_STORE_8020I 0x02 ///< SFF-8020i, typically a CD/DVD device +#define USB_MASS_STORE_QIC 0x03 ///< Typically a tape device +#define USB_MASS_STORE_UFI 0x04 ///< Typically a floppy disk driver device +#define USB_MASS_STORE_8070I 0x05 ///< SFF-8070i, typically a floppy disk driver device. +#define USB_MASS_STORE_SCSI 0x06 ///< SCSI transparent command set + +// +// Usb mass storage protocol code, specify the transport protocol +// +#define USB_MASS_STORE_CBI0 0x00 ///< CBI protocol with command completion interrupt +#define USB_MASS_STORE_CBI1 0x01 ///< CBI protocol without command completion interrupt +#define USB_MASS_STORE_BOT 0x50 ///< Bulk-Only Transport + +// +// Standard device request and request type +// USB 2.0 spec, Section 9.4 +// +#define USB_DEV_GET_STATUS 0x00 +#define USB_DEV_GET_STATUS_REQ_TYPE_D 0x80 // Receiver : Device +#define USB_DEV_GET_STATUS_REQ_TYPE_I 0x81 // Receiver : Interface +#define USB_DEV_GET_STATUS_REQ_TYPE_E 0x82 // Receiver : Endpoint + +#define USB_DEV_CLEAR_FEATURE 0x01 +#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_D 0x00 // Receiver : Device +#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_I 0x01 // Receiver : Interface +#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_E 0x02 // Receiver : Endpoint + +#define USB_DEV_SET_FEATURE 0x03 +#define USB_DEV_SET_FEATURE_REQ_TYPE_D 0x00 // Receiver : Device +#define USB_DEV_SET_FEATURE_REQ_TYPE_I 0x01 // Receiver : Interface +#define USB_DEV_SET_FEATURE_REQ_TYPE_E 0x02 // Receiver : Endpoint + +#define USB_DEV_SET_ADDRESS 0x05 +#define USB_DEV_SET_ADDRESS_REQ_TYPE 0x00 + +#define USB_DEV_GET_DESCRIPTOR 0x06 +#define USB_DEV_GET_DESCRIPTOR_REQ_TYPE 0x80 + +#define USB_DEV_SET_DESCRIPTOR 0x07 +#define USB_DEV_SET_DESCRIPTOR_REQ_TYPE 0x00 + +#define USB_DEV_GET_CONFIGURATION 0x08 +#define USB_DEV_GET_CONFIGURATION_REQ_TYPE 0x80 + +#define USB_DEV_SET_CONFIGURATION 0x09 +#define USB_DEV_SET_CONFIGURATION_REQ_TYPE 0x00 + +#define USB_DEV_GET_INTERFACE 0x0A +#define USB_DEV_GET_INTERFACE_REQ_TYPE 0x81 + +#define USB_DEV_SET_INTERFACE 0x0B +#define USB_DEV_SET_INTERFACE_REQ_TYPE 0x01 + +#define USB_DEV_SYNCH_FRAME 0x0C +#define USB_DEV_SYNCH_FRAME_REQ_TYPE 0x82 + +// +// USB standard descriptors and reqeust +// +#pragma pack(1) + +/// +/// Format of Setup Data for USB Device Requests +/// USB 2.0 spec, Section 9.3 +/// +typedef struct { + UINT8 RequestType; + UINT8 Request; + UINT16 Value; + UINT16 Index; + UINT16 Length; +} USB_DEVICE_REQUEST; + +/// +/// Standard Device Descriptor +/// USB 2.0 spec, Section 9.6.1 +/// +typedef struct { + UINT8 Length; + UINT8 DescriptorType; + UINT16 BcdUSB; + UINT8 DeviceClass; + UINT8 DeviceSubClass; + UINT8 DeviceProtocol; + UINT8 MaxPacketSize0; + UINT16 IdVendor; + UINT16 IdProduct; + UINT16 BcdDevice; + UINT8 StrManufacturer; + UINT8 StrProduct; + UINT8 StrSerialNumber; + UINT8 NumConfigurations; +} USB_DEVICE_DESCRIPTOR; + +/// +/// Standard Configuration Descriptor +/// USB 2.0 spec, Section 9.6.3 +/// +typedef struct { + UINT8 Length; + UINT8 DescriptorType; + UINT16 TotalLength; + UINT8 NumInterfaces; + UINT8 ConfigurationValue; + UINT8 Configuration; + UINT8 Attributes; + UINT8 MaxPower; +} USB_CONFIG_DESCRIPTOR; + +/// +/// Standard Interface Association Descriptor +/// USB 3.0 spec, Section 9.6.4 +/// +typedef struct { + UINT8 Length; + UINT8 DescriptorType; + UINT8 FirstInterface; + UINT8 InterfaceCount; + UINT8 FunctionClass; + UINT8 FunctionSubclass; + UINT8 FunctionProtocol; + UINT8 FunctionDescriptionStringIndex; +} USB_INTERFACE_ASSOCIATION_DESCRIPTOR; + +/// +/// Standard Interface Descriptor +/// USB 2.0 spec, Section 9.6.5 +/// +typedef struct { + UINT8 Length; + UINT8 DescriptorType; + UINT8 InterfaceNumber; + UINT8 AlternateSetting; + UINT8 NumEndpoints; + UINT8 InterfaceClass; + UINT8 InterfaceSubClass; + UINT8 InterfaceProtocol; + UINT8 Interface; +} USB_INTERFACE_DESCRIPTOR; + +/// +/// Standard Endpoint Descriptor +/// USB 2.0 spec, Section 9.6.6 +/// +typedef struct { + UINT8 Length; + UINT8 DescriptorType; + UINT8 EndpointAddress; + UINT8 Attributes; + UINT16 MaxPacketSize; + UINT8 Interval; +} USB_ENDPOINT_DESCRIPTOR; + +/// +/// UNICODE String Descriptor +/// USB 2.0 spec, Section 9.6.7 +/// +typedef struct { + UINT8 Length; + UINT8 DescriptorType; + CHAR16 String[1]; +} EFI_USB_STRING_DESCRIPTOR; + +#pragma pack() + +typedef enum { + // + // USB request type + // + USB_REQ_TYPE_STANDARD = (0x00 << 5), + USB_REQ_TYPE_CLASS = (0x01 << 5), + USB_REQ_TYPE_VENDOR = (0x02 << 5), + + // + // Standard control transfer request type, or the value + // to fill in EFI_USB_DEVICE_REQUEST.Request + // + USB_REQ_GET_STATUS = 0x00, + USB_REQ_CLEAR_FEATURE = 0x01, + USB_REQ_SET_FEATURE = 0x03, + USB_REQ_SET_ADDRESS = 0x05, + USB_REQ_GET_DESCRIPTOR = 0x06, + USB_REQ_SET_DESCRIPTOR = 0x07, + USB_REQ_GET_CONFIG = 0x08, + USB_REQ_SET_CONFIG = 0x09, + USB_REQ_GET_INTERFACE = 0x0A, + USB_REQ_SET_INTERFACE = 0x0B, + USB_REQ_SYNCH_FRAME = 0x0C, + + // + // Usb control transfer target + // + USB_TARGET_DEVICE = 0, + USB_TARGET_INTERFACE = 0x01, + USB_TARGET_ENDPOINT = 0x02, + USB_TARGET_OTHER = 0x03, + + // + // USB Descriptor types + // + USB_DESC_TYPE_DEVICE = 0x01, + USB_DESC_TYPE_CONFIG = 0x02, + USB_DESC_TYPE_STRING = 0x03, + USB_DESC_TYPE_INTERFACE = 0x04, + USB_DESC_TYPE_ENDPOINT = 0x05, + USB_DESC_TYPE_INTERFACE_ASSOCIATION = 0x0b, + USB_DESC_TYPE_HID = 0x21, + USB_DESC_TYPE_REPORT = 0x22, + USB_DESC_TYPE_CS_INTERFACE = 0x24, + USB_DESC_TYPE_CS_ENDPOINT = 0x25, + + // + // Features to be cleared by CLEAR_FEATURE requests + // + USB_FEATURE_ENDPOINT_HALT = 0, + + // + // USB endpoint types: 00: control, 01: isochronous, 10: bulk, 11: interrupt + // + USB_ENDPOINT_CONTROL = 0x00, + USB_ENDPOINT_ISO = 0x01, + USB_ENDPOINT_BULK = 0x02, + USB_ENDPOINT_INTERRUPT = 0x03, + + USB_ENDPOINT_TYPE_MASK = 0x03, + USB_ENDPOINT_DIR_IN = 0x80, + + // + // Use 200 ms to increase the error handling response time + // + EFI_USB_INTERRUPT_DELAY = 2000000 +} USB_TYPES_DEFINITION; + +// +// HID constants definition, see Device Class Definition +// for Human Interface Devices (HID) rev1.11 +// + +// +// HID standard GET_DESCRIPTOR request. +// +#define USB_HID_GET_DESCRIPTOR_REQ_TYPE 0x81 + +// +// HID specific requests. +// +#define USB_HID_CLASS_GET_REQ_TYPE 0xa1 +#define USB_HID_CLASS_SET_REQ_TYPE 0x21 + +// +// HID report item format +// +#define HID_ITEM_FORMAT_SHORT 0 +#define HID_ITEM_FORMAT_LONG 1 + +// +// Special tag indicating long items +// +#define HID_ITEM_TAG_LONG 15 + +// +// HID report descriptor item type (prefix bit 2,3) +// +#define HID_ITEM_TYPE_MAIN 0 +#define HID_ITEM_TYPE_GLOBAL 1 +#define HID_ITEM_TYPE_LOCAL 2 +#define HID_ITEM_TYPE_RESERVED 3 + +// +// HID report descriptor main item tags +// +#define HID_MAIN_ITEM_TAG_INPUT 8 +#define HID_MAIN_ITEM_TAG_OUTPUT 9 +#define HID_MAIN_ITEM_TAG_FEATURE 11 +#define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10 +#define HID_MAIN_ITEM_TAG_END_COLLECTION 12 + +// +// HID report descriptor main item contents +// +#define HID_MAIN_ITEM_CONSTANT 0x001 +#define HID_MAIN_ITEM_VARIABLE 0x002 +#define HID_MAIN_ITEM_RELATIVE 0x004 +#define HID_MAIN_ITEM_WRAP 0x008 +#define HID_MAIN_ITEM_NONLINEAR 0x010 +#define HID_MAIN_ITEM_NO_PREFERRED 0x020 +#define HID_MAIN_ITEM_NULL_STATE 0x040 +#define HID_MAIN_ITEM_VOLATILE 0x080 +#define HID_MAIN_ITEM_BUFFERED_BYTE 0x100 + +// +// HID report descriptor collection item types +// +#define HID_COLLECTION_PHYSICAL 0 +#define HID_COLLECTION_APPLICATION 1 +#define HID_COLLECTION_LOGICAL 2 + +// +// HID report descriptor global item tags +// +#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0 +#define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1 +#define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2 +#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3 +#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4 +#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5 +#define HID_GLOBAL_ITEM_TAG_UNIT 6 +#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7 +#define HID_GLOBAL_ITEM_TAG_REPORT_ID 8 +#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9 +#define HID_GLOBAL_ITEM_TAG_PUSH 10 +#define HID_GLOBAL_ITEM_TAG_POP 11 + +// +// HID report descriptor local item tags +// +#define HID_LOCAL_ITEM_TAG_USAGE 0 +#define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1 +#define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2 +#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3 +#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4 +#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5 +#define HID_LOCAL_ITEM_TAG_STRING_INDEX 7 +#define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8 +#define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9 +#define HID_LOCAL_ITEM_TAG_DELIMITER 10 + +// +// HID report types +// +#define HID_INPUT_REPORT 1 +#define HID_OUTPUT_REPORT 2 +#define HID_FEATURE_REPORT 3 + +// +// HID class protocol request +// +#define EFI_USB_GET_REPORT_REQUEST 0x01 +#define EFI_USB_GET_IDLE_REQUEST 0x02 +#define EFI_USB_GET_PROTOCOL_REQUEST 0x03 +#define EFI_USB_SET_REPORT_REQUEST 0x09 +#define EFI_USB_SET_IDLE_REQUEST 0x0a +#define EFI_USB_SET_PROTOCOL_REQUEST 0x0b + +#pragma pack(1) +/// +/// Descriptor header for Report/Physical Descriptors +/// HID 1.1, section 6.2.1 +/// +typedef struct hid_class_descriptor { + UINT8 DescriptorType; + UINT16 DescriptorLength; +} EFI_USB_HID_CLASS_DESCRIPTOR; + +/// +/// The HID descriptor identifies the length and type +/// of subordinate descriptors for a device. +/// HID 1.1, section 6.2.1 +/// +typedef struct hid_descriptor { + UINT8 Length; + UINT8 DescriptorType; + UINT16 BcdHID; + UINT8 CountryCode; + UINT8 NumDescriptors; + EFI_USB_HID_CLASS_DESCRIPTOR HidClassDesc[1]; +} EFI_USB_HID_DESCRIPTOR; + +#pragma pack() + +#endif diff --git a/sys/contrib/edk2/Include/Pi/PiBootMode.h b/sys/contrib/edk2/Include/Pi/PiBootMode.h new file mode 100644 index 000000000000..8a4fab51197f --- /dev/null +++ b/sys/contrib/edk2/Include/Pi/PiBootMode.h @@ -0,0 +1,36 @@ +/** @file
+ Present the boot mode values in PI.
+
+ Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ PI Version 1.2.1A
+
+**/
+
+#ifndef __PI_BOOT_MODE_H__
+#define __PI_BOOT_MODE_H__
+
+///
+/// EFI boot mode
+///
+typedef UINT32 EFI_BOOT_MODE;
+
+//
+// 0x21 - 0xf..f are reserved.
+//
+#define BOOT_WITH_FULL_CONFIGURATION 0x00
+#define BOOT_WITH_MINIMAL_CONFIGURATION 0x01
+#define BOOT_ASSUMING_NO_CONFIGURATION_CHANGES 0x02
+#define BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS 0x03
+#define BOOT_WITH_DEFAULT_SETTINGS 0x04
+#define BOOT_ON_S4_RESUME 0x05
+#define BOOT_ON_S5_RESUME 0x06
+#define BOOT_WITH_MFG_MODE_SETTINGS 0x07
+#define BOOT_ON_S2_RESUME 0x10
+#define BOOT_ON_S3_RESUME 0x11
+#define BOOT_ON_FLASH_UPDATE 0x12
+#define BOOT_IN_RECOVERY_MODE 0x20
+
+#endif
diff --git a/sys/contrib/edk2/Include/Pi/PiDependency.h b/sys/contrib/edk2/Include/Pi/PiDependency.h new file mode 100644 index 000000000000..021a0bd31cd7 --- /dev/null +++ b/sys/contrib/edk2/Include/Pi/PiDependency.h @@ -0,0 +1,41 @@ +/** @file
+ Present the dependency expression values in PI.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ PI Version 1.0
+
+**/
+
+#ifndef __PI_DEPENDENCY_H__
+#define __PI_DEPENDENCY_H__
+
+///
+/// If present, this must be the first and only opcode,
+/// EFI_DEP_BEFORE may be used by DXE and SMM drivers.
+///
+#define EFI_DEP_BEFORE 0x00
+
+///
+/// If present, this must be the first and only opcode,
+/// EFI_DEP_AFTER may be used by DXE and SMM drivers.
+///
+#define EFI_DEP_AFTER 0x01
+
+#define EFI_DEP_PUSH 0x02
+#define EFI_DEP_AND 0x03
+#define EFI_DEP_OR 0x04
+#define EFI_DEP_NOT 0x05
+#define EFI_DEP_TRUE 0x06
+#define EFI_DEP_FALSE 0x07
+#define EFI_DEP_END 0x08
+
+///
+/// If present, this must be the first opcode,
+/// EFI_DEP_SOR is only used by DXE driver.
+///
+#define EFI_DEP_SOR 0x09
+
+#endif
diff --git a/sys/contrib/edk2/Include/Pi/PiFirmwareFile.h b/sys/contrib/edk2/Include/Pi/PiFirmwareFile.h new file mode 100644 index 000000000000..58d6ebf9aa31 --- /dev/null +++ b/sys/contrib/edk2/Include/Pi/PiFirmwareFile.h @@ -0,0 +1,506 @@ +/** @file + The firmware file related definitions in PI. + +Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + PI Version 1.6. + +**/ + +#ifndef __PI_FIRMWARE_FILE_H__ +#define __PI_FIRMWARE_FILE_H__ + +#pragma pack(1) +/// +/// Used to verify the integrity of the file. +/// +typedef union { + struct { + /// + /// The IntegrityCheck.Checksum.Header field is an 8-bit checksum of the file + /// header. The State and IntegrityCheck.Checksum.File fields are assumed + /// to be zero and the checksum is calculated such that the entire header sums to zero. + /// + UINT8 Header; + /// + /// If the FFS_ATTRIB_CHECKSUM (see definition below) bit of the Attributes + /// field is set to one, the IntegrityCheck.Checksum.File field is an 8-bit + /// checksum of the file data. + /// If the FFS_ATTRIB_CHECKSUM bit of the Attributes field is cleared to zero, + /// the IntegrityCheck.Checksum.File field must be initialized with a value of + /// 0xAA. The IntegrityCheck.Checksum.File field is valid any time the + /// EFI_FILE_DATA_VALID bit is set in the State field. + /// + UINT8 File; + } Checksum; + /// + /// This is the full 16 bits of the IntegrityCheck field. + /// + UINT16 Checksum16; +} EFI_FFS_INTEGRITY_CHECK; + +/// +/// FFS_FIXED_CHECKSUM is the checksum value used when the +/// FFS_ATTRIB_CHECKSUM attribute bit is clear. +/// +#define FFS_FIXED_CHECKSUM 0xAA + +typedef UINT8 EFI_FV_FILETYPE; +typedef UINT8 EFI_FFS_FILE_ATTRIBUTES; +typedef UINT8 EFI_FFS_FILE_STATE; + +/// +/// File Types Definitions +/// +#define EFI_FV_FILETYPE_ALL 0x00 +#define EFI_FV_FILETYPE_RAW 0x01 +#define EFI_FV_FILETYPE_FREEFORM 0x02 +#define EFI_FV_FILETYPE_SECURITY_CORE 0x03 +#define EFI_FV_FILETYPE_PEI_CORE 0x04 +#define EFI_FV_FILETYPE_DXE_CORE 0x05 +#define EFI_FV_FILETYPE_PEIM 0x06 +#define EFI_FV_FILETYPE_DRIVER 0x07 +#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08 +#define EFI_FV_FILETYPE_APPLICATION 0x09 +#define EFI_FV_FILETYPE_MM 0x0A +#define EFI_FV_FILETYPE_SMM EFI_FV_FILETYPE_MM +#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B +#define EFI_FV_FILETYPE_COMBINED_MM_DXE 0x0C +#define EFI_FV_FILETYPE_COMBINED_SMM_DXE EFI_FV_FILETYPE_COMBINED_MM_DXE +#define EFI_FV_FILETYPE_MM_CORE 0x0D +#define EFI_FV_FILETYPE_SMM_CORE EFI_FV_FILETYPE_MM_CORE +#define EFI_FV_FILETYPE_MM_STANDALONE 0x0E +#define EFI_FV_FILETYPE_MM_CORE_STANDALONE 0x0F +#define EFI_FV_FILETYPE_OEM_MIN 0xc0 +#define EFI_FV_FILETYPE_OEM_MAX 0xdf +#define EFI_FV_FILETYPE_DEBUG_MIN 0xe0 +#define EFI_FV_FILETYPE_DEBUG_MAX 0xef +#define EFI_FV_FILETYPE_FFS_MIN 0xf0 +#define EFI_FV_FILETYPE_FFS_MAX 0xff +#define EFI_FV_FILETYPE_FFS_PAD 0xf0 +/// +/// FFS File Attributes. +/// +#define FFS_ATTRIB_LARGE_FILE 0x01 +#define FFS_ATTRIB_DATA_ALIGNMENT_2 0x02 +#define FFS_ATTRIB_FIXED 0x04 +#define FFS_ATTRIB_DATA_ALIGNMENT 0x38 +#define FFS_ATTRIB_CHECKSUM 0x40 + +/// +/// FFS File State Bits. +/// +#define EFI_FILE_HEADER_CONSTRUCTION 0x01 +#define EFI_FILE_HEADER_VALID 0x02 +#define EFI_FILE_DATA_VALID 0x04 +#define EFI_FILE_MARKED_FOR_UPDATE 0x08 +#define EFI_FILE_DELETED 0x10 +#define EFI_FILE_HEADER_INVALID 0x20 + +/// +/// Each file begins with the header that describe the +/// contents and state of the files. +/// +typedef struct { + /// + /// This GUID is the file name. It is used to uniquely identify the file. + /// + EFI_GUID Name; + /// + /// Used to verify the integrity of the file. + /// + EFI_FFS_INTEGRITY_CHECK IntegrityCheck; + /// + /// Identifies the type of file. + /// + EFI_FV_FILETYPE Type; + /// + /// Declares various file attribute bits. + /// + EFI_FFS_FILE_ATTRIBUTES Attributes; + /// + /// The length of the file in bytes, including the FFS header. + /// + UINT8 Size[3]; + /// + /// Used to track the state of the file throughout the life of the file from creation to deletion. + /// + EFI_FFS_FILE_STATE State; +} EFI_FFS_FILE_HEADER; + +typedef struct { + /// + /// This GUID is the file name. It is used to uniquely identify the file. There may be only + /// one instance of a file with the file name GUID of Name in any given firmware + /// volume, except if the file type is EFI_FV_FILETYPE_FFS_PAD. + /// + EFI_GUID Name; + + /// + /// Used to verify the integrity of the file. + /// + EFI_FFS_INTEGRITY_CHECK IntegrityCheck; + + /// + /// Identifies the type of file. + /// + EFI_FV_FILETYPE Type; + + /// + /// Declares various file attribute bits. + /// + EFI_FFS_FILE_ATTRIBUTES Attributes; + + /// + /// The length of the file in bytes, including the FFS header. + /// The length of the file data is either (Size - sizeof(EFI_FFS_FILE_HEADER)). This calculation means a + /// zero-length file has a Size of 24 bytes, which is sizeof(EFI_FFS_FILE_HEADER). + /// Size is not required to be a multiple of 8 bytes. Given a file F, the next file header is + /// located at the next 8-byte aligned firmware volume offset following the last byte of the file F. + /// + UINT8 Size[3]; + + /// + /// Used to track the state of the file throughout the life of the file from creation to deletion. + /// + EFI_FFS_FILE_STATE State; + + /// + /// If FFS_ATTRIB_LARGE_FILE is set in Attributes, then ExtendedSize exists and Size must be set to zero. + /// If FFS_ATTRIB_LARGE_FILE is not set then EFI_FFS_FILE_HEADER is used. + /// + UINT64 ExtendedSize; +} EFI_FFS_FILE_HEADER2; + +#define IS_FFS_FILE2(FfsFileHeaderPtr) \ + (((((EFI_FFS_FILE_HEADER *) (UINTN) FfsFileHeaderPtr)->Attributes) & FFS_ATTRIB_LARGE_FILE) == FFS_ATTRIB_LARGE_FILE) + +/// +/// The argument passed as the FfsFileHeaderPtr parameter to the +/// FFS_FILE_SIZE() function-like macro below must not have side effects: +/// FfsFileHeaderPtr is evaluated multiple times. +/// +#define FFS_FILE_SIZE(FfsFileHeaderPtr) ((UINT32) (\ + (((EFI_FFS_FILE_HEADER *) (UINTN) (FfsFileHeaderPtr))->Size[0] ) | \ + (((EFI_FFS_FILE_HEADER *) (UINTN) (FfsFileHeaderPtr))->Size[1] << 8) | \ + (((EFI_FFS_FILE_HEADER *) (UINTN) (FfsFileHeaderPtr))->Size[2] << 16))) + +#define FFS_FILE2_SIZE(FfsFileHeaderPtr) \ + ((UINT32) (((EFI_FFS_FILE_HEADER2 *) (UINTN) FfsFileHeaderPtr)->ExtendedSize)) + +typedef UINT8 EFI_SECTION_TYPE; + +/// +/// Pseudo type. It is used as a wild card when retrieving sections. +/// The section type EFI_SECTION_ALL matches all section types. +/// +#define EFI_SECTION_ALL 0x00 + +/// +/// Encapsulation section Type values. +/// +#define EFI_SECTION_COMPRESSION 0x01 + +#define EFI_SECTION_GUID_DEFINED 0x02 + +#define EFI_SECTION_DISPOSABLE 0x03 + +/// +/// Leaf section Type values. +/// +#define EFI_SECTION_PE32 0x10 +#define EFI_SECTION_PIC 0x11 +#define EFI_SECTION_TE 0x12 +#define EFI_SECTION_DXE_DEPEX 0x13 +#define EFI_SECTION_VERSION 0x14 +#define EFI_SECTION_USER_INTERFACE 0x15 +#define EFI_SECTION_COMPATIBILITY16 0x16 +#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17 +#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 +#define EFI_SECTION_RAW 0x19 +#define EFI_SECTION_PEI_DEPEX 0x1B +#define EFI_SECTION_MM_DEPEX 0x1C +#define EFI_SECTION_SMM_DEPEX EFI_SECTION_MM_DEPEX + +/// +/// Common section header. +/// +typedef struct { + /// + /// A 24-bit unsigned integer that contains the total size of the section in bytes, + /// including the EFI_COMMON_SECTION_HEADER. + /// + UINT8 Size[3]; + EFI_SECTION_TYPE Type; + /// + /// Declares the section type. + /// +} EFI_COMMON_SECTION_HEADER; + +typedef struct { + /// + /// A 24-bit unsigned integer that contains the total size of the section in bytes, + /// including the EFI_COMMON_SECTION_HEADER. + /// + UINT8 Size[3]; + + EFI_SECTION_TYPE Type; + + /// + /// If Size is 0xFFFFFF, then ExtendedSize contains the size of the section. If + /// Size is not equal to 0xFFFFFF, then this field does not exist. + /// + UINT32 ExtendedSize; +} EFI_COMMON_SECTION_HEADER2; + +/// +/// Leaf section type that contains an +/// IA-32 16-bit executable image. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2; + +/// +/// CompressionType of EFI_COMPRESSION_SECTION. +/// +#define EFI_NOT_COMPRESSED 0x00 +#define EFI_STANDARD_COMPRESSION 0x01 +/// +/// An encapsulation section type in which the +/// section data is compressed. +/// +typedef struct { + /// + /// Usual common section header. CommonHeader.Type = EFI_SECTION_COMPRESSION. + /// + EFI_COMMON_SECTION_HEADER CommonHeader; + /// + /// The UINT32 that indicates the size of the section data after decompression. + /// + UINT32 UncompressedLength; + /// + /// Indicates which compression algorithm is used. + /// + UINT8 CompressionType; +} EFI_COMPRESSION_SECTION; + +typedef struct { + /// + /// Usual common section header. CommonHeader.Type = EFI_SECTION_COMPRESSION. + /// + EFI_COMMON_SECTION_HEADER2 CommonHeader; + /// + /// UINT32 that indicates the size of the section data after decompression. + /// + UINT32 UncompressedLength; + /// + /// Indicates which compression algorithm is used. + /// + UINT8 CompressionType; +} EFI_COMPRESSION_SECTION2; + +/// +/// An encapsulation section type in which the section data is disposable. +/// A disposable section is an encapsulation section in which the section data may be disposed of during +/// the process of creating or updating a firmware image without significant impact on the usefulness of +/// the file. The Type field in the section header is set to EFI_SECTION_DISPOSABLE. This +/// allows optional or descriptive data to be included with the firmware file which can be removed in +/// order to conserve space. The contents of this section are implementation specific, but might contain +/// debug data or detailed integration instructions. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_DISPOSABLE_SECTION2; + +/// +/// The leaf section which could be used to determine the dispatch order of DXEs. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2; + +/// +/// The leaf section which contains a PI FV. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2; + +/// +/// The leaf section which contains a single GUID. +/// +typedef struct { + /// + /// Common section header. CommonHeader.Type = EFI_SECTION_FREEFORM_SUBTYPE_GUID. + /// + EFI_COMMON_SECTION_HEADER CommonHeader; + /// + /// This GUID is defined by the creator of the file. It is a vendor-defined file type. + /// + EFI_GUID SubTypeGuid; +} EFI_FREEFORM_SUBTYPE_GUID_SECTION; + +typedef struct { + /// + /// The common section header. CommonHeader.Type = EFI_SECTION_FREEFORM_SUBTYPE_GUID. + /// + EFI_COMMON_SECTION_HEADER2 CommonHeader; + /// + /// This GUID is defined by the creator of the file. It is a vendor-defined file type. + /// + EFI_GUID SubTypeGuid; +} EFI_FREEFORM_SUBTYPE_GUID_SECTION2; + +/// +/// Attributes of EFI_GUID_DEFINED_SECTION. +/// +#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01 +#define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02 +/// +/// The leaf section which is encapsulation defined by specific GUID. +/// +typedef struct { + /// + /// The common section header. CommonHeader.Type = EFI_SECTION_GUID_DEFINED. + /// + EFI_COMMON_SECTION_HEADER CommonHeader; + /// + /// The GUID that defines the format of the data that follows. It is a vendor-defined section type. + /// + EFI_GUID SectionDefinitionGuid; + /// + /// Contains the offset in bytes from the beginning of the common header to the first byte of the data. + /// + UINT16 DataOffset; + /// + /// The bit field that declares some specific characteristics of the section contents. + /// + UINT16 Attributes; +} EFI_GUID_DEFINED_SECTION; + +typedef struct { + /// + /// The common section header. CommonHeader.Type = EFI_SECTION_GUID_DEFINED. + /// + EFI_COMMON_SECTION_HEADER2 CommonHeader; + /// + /// The GUID that defines the format of the data that follows. It is a vendor-defined section type. + /// + EFI_GUID SectionDefinitionGuid; + /// + /// Contains the offset in bytes from the beginning of the common header to the first byte of the data. + /// + UINT16 DataOffset; + /// + /// The bit field that declares some specific characteristics of the section contents. + /// + UINT16 Attributes; +} EFI_GUID_DEFINED_SECTION2; + +/// +/// The leaf section which contains PE32+ image. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2; + +/// +/// The leaf section used to determine the dispatch order of PEIMs. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2; + +/// +/// A leaf section type that contains a position-independent-code (PIC) image. +/// A PIC image section is a leaf section that contains a position-independent-code (PIC) image. +/// In addition to normal PE32+ images that contain relocation information, PEIM executables may be +/// PIC and are referred to as PIC images. A PIC image is the same as a PE32+ image except that all +/// relocation information has been stripped from the image and the image can be moved and will +/// execute correctly without performing any relocation or other fix-ups. EFI_PIC_SECTION2 must +/// be used if the section is 16MB or larger. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2; + +/// +/// The leaf section which constains the position-independent-code image. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2; + +/// +/// The leaf section which contains an array of zero or more bytes. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2; + +/// +/// The SMM dependency expression section is a leaf section that contains a dependency expression that +/// is used to determine the dispatch order for SMM drivers. Before the SMRAM invocation of the +/// SMM driver's entry point, this dependency expression must evaluate to TRUE. See the Platform +/// Initialization Specification, Volume 2, for details regarding the format of the dependency expression. +/// The dependency expression may refer to protocols installed in either the UEFI or the SMM protocol +/// database. EFI_SMM_DEPEX_SECTION2 must be used if the section is 16MB or larger. +/// +typedef EFI_COMMON_SECTION_HEADER EFI_SMM_DEPEX_SECTION; +typedef EFI_COMMON_SECTION_HEADER2 EFI_SMM_DEPEX_SECTION2; + +/// +/// The leaf section which contains a unicode string that +/// is human readable file name. +/// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; + + /// + /// Array of unicode string. + /// + CHAR16 FileNameString[1]; +} EFI_USER_INTERFACE_SECTION; + +typedef struct { + EFI_COMMON_SECTION_HEADER2 CommonHeader; + CHAR16 FileNameString[1]; +} EFI_USER_INTERFACE_SECTION2; + +/// +/// The leaf section which contains a numeric build number and +/// an optional unicode string that represents the file revision. +/// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; + UINT16 BuildNumber; + + /// + /// Array of unicode string. + /// + CHAR16 VersionString[1]; +} EFI_VERSION_SECTION; + +typedef struct { + EFI_COMMON_SECTION_HEADER2 CommonHeader; + /// + /// A UINT16 that represents a particular build. Subsequent builds have monotonically + /// increasing build numbers relative to earlier builds. + /// + UINT16 BuildNumber; + CHAR16 VersionString[1]; +} EFI_VERSION_SECTION2; + +/// +/// The argument passed as the SectionHeaderPtr parameter to the SECTION_SIZE() +/// and IS_SECTION2() function-like macros below must not have side effects: +/// SectionHeaderPtr is evaluated multiple times. +/// +#define SECTION_SIZE(SectionHeaderPtr) ((UINT32) (\ + (((EFI_COMMON_SECTION_HEADER *) (UINTN) (SectionHeaderPtr))->Size[0] ) | \ + (((EFI_COMMON_SECTION_HEADER *) (UINTN) (SectionHeaderPtr))->Size[1] << 8) | \ + (((EFI_COMMON_SECTION_HEADER *) (UINTN) (SectionHeaderPtr))->Size[2] << 16))) + +#define IS_SECTION2(SectionHeaderPtr) \ + (SECTION_SIZE (SectionHeaderPtr) == 0x00ffffff) + +#define SECTION2_SIZE(SectionHeaderPtr) \ + (((EFI_COMMON_SECTION_HEADER2 *) (UINTN) SectionHeaderPtr)->ExtendedSize) + +#pragma pack() + +#endif diff --git a/sys/contrib/edk2/Include/Pi/PiFirmwareVolume.h b/sys/contrib/edk2/Include/Pi/PiFirmwareVolume.h new file mode 100644 index 000000000000..0b0382671cc1 --- /dev/null +++ b/sys/contrib/edk2/Include/Pi/PiFirmwareVolume.h @@ -0,0 +1,247 @@ +/** @file + The firmware volume related definitions in PI. + + Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + PI Version 1.6 + +**/ + +#ifndef __PI_FIRMWAREVOLUME_H__ +#define __PI_FIRMWAREVOLUME_H__ + +/// +/// EFI_FV_FILE_ATTRIBUTES +/// +typedef UINT32 EFI_FV_FILE_ATTRIBUTES; + +// +// Value of EFI_FV_FILE_ATTRIBUTES. +// +#define EFI_FV_FILE_ATTRIB_ALIGNMENT 0x0000001F +#define EFI_FV_FILE_ATTRIB_FIXED 0x00000100 +#define EFI_FV_FILE_ATTRIB_MEMORY_MAPPED 0x00000200 + +/// +/// type of EFI FVB attribute +/// +typedef UINT32 EFI_FVB_ATTRIBUTES_2; + +// +// Attributes bit definitions +// +#define EFI_FVB2_READ_DISABLED_CAP 0x00000001 +#define EFI_FVB2_READ_ENABLED_CAP 0x00000002 +#define EFI_FVB2_READ_STATUS 0x00000004 +#define EFI_FVB2_WRITE_DISABLED_CAP 0x00000008 +#define EFI_FVB2_WRITE_ENABLED_CAP 0x00000010 +#define EFI_FVB2_WRITE_STATUS 0x00000020 +#define EFI_FVB2_LOCK_CAP 0x00000040 +#define EFI_FVB2_LOCK_STATUS 0x00000080 +#define EFI_FVB2_STICKY_WRITE 0x00000200 +#define EFI_FVB2_MEMORY_MAPPED 0x00000400 +#define EFI_FVB2_ERASE_POLARITY 0x00000800 +#define EFI_FVB2_READ_LOCK_CAP 0x00001000 +#define EFI_FVB2_READ_LOCK_STATUS 0x00002000 +#define EFI_FVB2_WRITE_LOCK_CAP 0x00004000 +#define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000 +#define EFI_FVB2_ALIGNMENT 0x001F0000 +#define EFI_FVB2_ALIGNMENT_1 0x00000000 +#define EFI_FVB2_ALIGNMENT_2 0x00010000 +#define EFI_FVB2_ALIGNMENT_4 0x00020000 +#define EFI_FVB2_ALIGNMENT_8 0x00030000 +#define EFI_FVB2_ALIGNMENT_16 0x00040000 +#define EFI_FVB2_ALIGNMENT_32 0x00050000 +#define EFI_FVB2_ALIGNMENT_64 0x00060000 +#define EFI_FVB2_ALIGNMENT_128 0x00070000 +#define EFI_FVB2_ALIGNMENT_256 0x00080000 +#define EFI_FVB2_ALIGNMENT_512 0x00090000 +#define EFI_FVB2_ALIGNMENT_1K 0x000A0000 +#define EFI_FVB2_ALIGNMENT_2K 0x000B0000 +#define EFI_FVB2_ALIGNMENT_4K 0x000C0000 +#define EFI_FVB2_ALIGNMENT_8K 0x000D0000 +#define EFI_FVB2_ALIGNMENT_16K 0x000E0000 +#define EFI_FVB2_ALIGNMENT_32K 0x000F0000 +#define EFI_FVB2_ALIGNMENT_64K 0x00100000 +#define EFI_FVB2_ALIGNMENT_128K 0x00110000 +#define EFI_FVB2_ALIGNMENT_256K 0x00120000 +#define EFI_FVB2_ALIGNMENT_512K 0x00130000 +#define EFI_FVB2_ALIGNMENT_1M 0x00140000 +#define EFI_FVB2_ALIGNMENT_2M 0x00150000 +#define EFI_FVB2_ALIGNMENT_4M 0x00160000 +#define EFI_FVB2_ALIGNMENT_8M 0x00170000 +#define EFI_FVB2_ALIGNMENT_16M 0x00180000 +#define EFI_FVB2_ALIGNMENT_32M 0x00190000 +#define EFI_FVB2_ALIGNMENT_64M 0x001A0000 +#define EFI_FVB2_ALIGNMENT_128M 0x001B0000 +#define EFI_FVB2_ALIGNMENT_256M 0x001C0000 +#define EFI_FVB2_ALIGNMENT_512M 0x001D0000 +#define EFI_FVB2_ALIGNMENT_1G 0x001E0000 +#define EFI_FVB2_ALIGNMENT_2G 0x001F0000 +#define EFI_FVB2_WEAK_ALIGNMENT 0x80000000 + +typedef struct { + /// + /// The number of sequential blocks which are of the same size. + /// + UINT32 NumBlocks; + /// + /// The size of the blocks. + /// + UINT32 Length; +} EFI_FV_BLOCK_MAP_ENTRY; + +/// +/// Describes the features and layout of the firmware volume. +/// +typedef struct { + /// + /// The first 16 bytes are reserved to allow for the reset vector of + /// processors whose reset vector is at address 0. + /// + UINT8 ZeroVector[16]; + /// + /// Declares the file system with which the firmware volume is formatted. + /// + EFI_GUID FileSystemGuid; + /// + /// Length in bytes of the complete firmware volume, including the header. + /// + UINT64 FvLength; + /// + /// Set to EFI_FVH_SIGNATURE + /// + UINT32 Signature; + /// + /// Declares capabilities and power-on defaults for the firmware volume. + /// + EFI_FVB_ATTRIBUTES_2 Attributes; + /// + /// Length in bytes of the complete firmware volume header. + /// + UINT16 HeaderLength; + /// + /// A 16-bit checksum of the firmware volume header. A valid header sums to zero. + /// + UINT16 Checksum; + /// + /// Offset, relative to the start of the header, of the extended header + /// (EFI_FIRMWARE_VOLUME_EXT_HEADER) or zero if there is no extended header. + /// + UINT16 ExtHeaderOffset; + /// + /// This field must always be set to zero. + /// + UINT8 Reserved[1]; + /// + /// Set to 2. Future versions of this specification may define new header fields and will + /// increment the Revision field accordingly. + /// + UINT8 Revision; + /// + /// An array of run-length encoded FvBlockMapEntry structures. The array is + /// terminated with an entry of {0,0}. + /// + EFI_FV_BLOCK_MAP_ENTRY BlockMap[1]; +} EFI_FIRMWARE_VOLUME_HEADER; + +#define EFI_FVH_SIGNATURE SIGNATURE_32 ('_', 'F', 'V', 'H') + +/// +/// Firmware Volume Header Revision definition +/// +#define EFI_FVH_REVISION 0x02 + +/// +/// Extension header pointed by ExtHeaderOffset of volume header. +/// +typedef struct { + /// + /// Firmware volume name. + /// + EFI_GUID FvName; + /// + /// Size of the rest of the extension header, including this structure. + /// + UINT32 ExtHeaderSize; +} EFI_FIRMWARE_VOLUME_EXT_HEADER; + +/// +/// Entry struture for describing FV extension header +/// +typedef struct { + /// + /// Size of this header extension. + /// + UINT16 ExtEntrySize; + /// + /// Type of the header. + /// + UINT16 ExtEntryType; +} EFI_FIRMWARE_VOLUME_EXT_ENTRY; + +#define EFI_FV_EXT_TYPE_OEM_TYPE 0x01 +/// +/// This extension header provides a mapping between a GUID and an OEM file type. +/// +typedef struct { + /// + /// Standard extension entry, with the type EFI_FV_EXT_TYPE_OEM_TYPE. + /// + EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr; + /// + /// A bit mask, one bit for each file type between 0xC0 (bit 0) and 0xDF (bit 31). If a bit + /// is '1', then the GUID entry exists in Types. If a bit is '0' then no GUID entry exists in Types. + /// + UINT32 TypeMask; + /// + /// An array of GUIDs, each GUID representing an OEM file type. + /// + /// EFI_GUID Types[1]; + /// +} EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE; + +#define EFI_FV_EXT_TYPE_GUID_TYPE 0x0002 + +/// +/// This extension header EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE provides a vendor specific +/// GUID FormatType type which includes a length and a successive series of data bytes. +/// +typedef struct { + /// + /// Standard extension entry, with the type EFI_FV_EXT_TYPE_OEM_TYPE. + /// + EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr; + /// + /// Vendor-specific GUID. + /// + EFI_GUID FormatType; + /// + /// An arry of bytes of length Length. + /// + /// UINT8 Data[1]; + /// +} EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE; + +#define EFI_FV_EXT_TYPE_USED_SIZE_TYPE 0x03 + +/// +/// The EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE can be used to find +/// out how many EFI_FVB2_ERASE_POLARITY bytes are at the end of the FV. +/// +typedef struct { + /// + /// Standard extension entry, with the type EFI_FV_EXT_TYPE_USED_SIZE_TYPE. + /// + EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr; + /// + /// The number of bytes of the FV that are in uses. The remaining + /// EFI_FIRMWARE_VOLUME_HEADER FvLength minus UsedSize bytes in + /// the FV must contain the value implied by EFI_FVB2_ERASE_POLARITY. + /// + UINT32 UsedSize; +} EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE; + +#endif diff --git a/sys/contrib/edk2/Include/Pi/PiHob.h b/sys/contrib/edk2/Include/Pi/PiHob.h new file mode 100644 index 000000000000..824f1c380bb2 --- /dev/null +++ b/sys/contrib/edk2/Include/Pi/PiHob.h @@ -0,0 +1,512 @@ +/** @file
+ HOB related definitions in PI.
+
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ PI Version 1.9
+
+**/
+
+#ifndef __PI_HOB_H__
+#define __PI_HOB_H__
+
+//
+// HobType of EFI_HOB_GENERIC_HEADER.
+//
+#define EFI_HOB_TYPE_HANDOFF 0x0001
+#define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002
+#define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003
+#define EFI_HOB_TYPE_GUID_EXTENSION 0x0004
+#define EFI_HOB_TYPE_FV 0x0005
+#define EFI_HOB_TYPE_CPU 0x0006
+#define EFI_HOB_TYPE_MEMORY_POOL 0x0007
+#define EFI_HOB_TYPE_FV2 0x0009
+#define EFI_HOB_TYPE_LOAD_PEIM_UNUSED 0x000A
+#define EFI_HOB_TYPE_UEFI_CAPSULE 0x000B
+#define EFI_HOB_TYPE_FV3 0x000C
+#define EFI_HOB_TYPE_UNUSED 0xFFFE
+#define EFI_HOB_TYPE_END_OF_HOB_LIST 0xFFFF
+
+///
+/// Describes the format and size of the data inside the HOB.
+/// All HOBs must contain this generic HOB header.
+///
+typedef struct {
+ ///
+ /// Identifies the HOB data structure type.
+ ///
+ UINT16 HobType;
+ ///
+ /// The length in bytes of the HOB.
+ ///
+ UINT16 HobLength;
+ ///
+ /// This field must always be set to zero.
+ ///
+ UINT32 Reserved;
+} EFI_HOB_GENERIC_HEADER;
+
+///
+/// Value of version in EFI_HOB_HANDOFF_INFO_TABLE.
+///
+#define EFI_HOB_HANDOFF_TABLE_VERSION 0x0009
+
+///
+/// Contains general state information used by the HOB producer phase.
+/// This HOB must be the first one in the HOB list.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_HANDOFF.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+ ///
+ /// The version number pertaining to the PHIT HOB definition.
+ /// This value is four bytes in length to provide an 8-byte aligned entry
+ /// when it is combined with the 4-byte BootMode.
+ ///
+ UINT32 Version;
+ ///
+ /// The system boot mode as determined during the HOB producer phase.
+ ///
+ EFI_BOOT_MODE BootMode;
+ ///
+ /// The highest address location of memory that is allocated for use by the HOB producer
+ /// phase. This address must be 4-KB aligned to meet page restrictions of UEFI.
+ ///
+ EFI_PHYSICAL_ADDRESS EfiMemoryTop;
+ ///
+ /// The lowest address location of memory that is allocated for use by the HOB producer phase.
+ ///
+ EFI_PHYSICAL_ADDRESS EfiMemoryBottom;
+ ///
+ /// The highest address location of free memory that is currently available
+ /// for use by the HOB producer phase.
+ ///
+ EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop;
+ ///
+ /// The lowest address location of free memory that is available for use by the HOB producer phase.
+ ///
+ EFI_PHYSICAL_ADDRESS EfiFreeMemoryBottom;
+ ///
+ /// The end of the HOB list.
+ ///
+ EFI_PHYSICAL_ADDRESS EfiEndOfHobList;
+} EFI_HOB_HANDOFF_INFO_TABLE;
+
+///
+/// EFI_HOB_MEMORY_ALLOCATION_HEADER describes the
+/// various attributes of the logical memory allocation. The type field will be used for
+/// subsequent inclusion in the UEFI memory map.
+///
+typedef struct {
+ ///
+ /// A GUID that defines the memory allocation region's type and purpose, as well as
+ /// other fields within the memory allocation HOB. This GUID is used to define the
+ /// additional data within the HOB that may be present for the memory allocation HOB.
+ /// Type EFI_GUID is defined in InstallProtocolInterface() in the UEFI 2.0
+ /// specification.
+ ///
+ EFI_GUID Name;
+
+ ///
+ /// The base address of memory allocated by this HOB. Type
+ /// EFI_PHYSICAL_ADDRESS is defined in AllocatePages() in the UEFI 2.0
+ /// specification.
+ ///
+ EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
+
+ ///
+ /// The length in bytes of memory allocated by this HOB.
+ ///
+ UINT64 MemoryLength;
+
+ ///
+ /// Defines the type of memory allocated by this HOB. The memory type definition
+ /// follows the EFI_MEMORY_TYPE definition. Type EFI_MEMORY_TYPE is defined
+ /// in AllocatePages() in the UEFI 2.0 specification.
+ ///
+ EFI_MEMORY_TYPE MemoryType;
+
+ ///
+ /// Padding for Itanium processor family
+ ///
+ UINT8 Reserved[4];
+} EFI_HOB_MEMORY_ALLOCATION_HEADER;
+
+///
+/// Describes all memory ranges used during the HOB producer
+/// phase that exist outside the HOB list. This HOB type
+/// describes how memory is used, not the physical attributes of memory.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+ ///
+ /// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the
+ /// various attributes of the logical memory allocation.
+ ///
+ EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor;
+ //
+ // Additional data pertaining to the "Name" Guid memory
+ // may go here.
+ //
+} EFI_HOB_MEMORY_ALLOCATION;
+
+///
+/// Describes the memory stack that is produced by the HOB producer
+/// phase and upon which all post-memory-installed executable
+/// content in the HOB producer phase is executing.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+ ///
+ /// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the
+ /// various attributes of the logical memory allocation.
+ ///
+ EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor;
+} EFI_HOB_MEMORY_ALLOCATION_STACK;
+
+///
+/// Defines the location of the boot-strap
+/// processor (BSP) BSPStore ("Backing Store Pointer Store").
+/// This HOB is valid for the Itanium processor family only
+/// register overflow store.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+ ///
+ /// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the
+ /// various attributes of the logical memory allocation.
+ ///
+ EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor;
+} EFI_HOB_MEMORY_ALLOCATION_BSP_STORE;
+
+///
+/// Defines the location and entry point of the HOB consumer phase.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+ ///
+ /// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the
+ /// various attributes of the logical memory allocation.
+ ///
+ EFI_HOB_MEMORY_ALLOCATION_HEADER MemoryAllocationHeader;
+ ///
+ /// The GUID specifying the values of the firmware file system name
+ /// that contains the HOB consumer phase component.
+ ///
+ EFI_GUID ModuleName;
+ ///
+ /// The address of the memory-mapped firmware volume
+ /// that contains the HOB consumer phase firmware file.
+ ///
+ EFI_PHYSICAL_ADDRESS EntryPoint;
+} EFI_HOB_MEMORY_ALLOCATION_MODULE;
+
+///
+/// The resource type.
+///
+typedef UINT32 EFI_RESOURCE_TYPE;
+
+//
+// Value of ResourceType in EFI_HOB_RESOURCE_DESCRIPTOR.
+//
+#define EFI_RESOURCE_SYSTEM_MEMORY 0x00000000
+#define EFI_RESOURCE_MEMORY_MAPPED_IO 0x00000001
+#define EFI_RESOURCE_IO 0x00000002
+#define EFI_RESOURCE_FIRMWARE_DEVICE 0x00000003
+#define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT 0x00000004
+#define EFI_RESOURCE_MEMORY_RESERVED 0x00000005
+#define EFI_RESOURCE_IO_RESERVED 0x00000006
+#define EFI_RESOURCE_MEMORY_UNACCEPTED 0x00000007
+#define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000008
+
+///
+/// A type of recount attribute type.
+///
+typedef UINT32 EFI_RESOURCE_ATTRIBUTE_TYPE;
+
+//
+// These types can be ORed together as needed.
+//
+// The following attributes are used to describe settings
+//
+#define EFI_RESOURCE_ATTRIBUTE_PRESENT 0x00000001
+#define EFI_RESOURCE_ATTRIBUTE_INITIALIZED 0x00000002
+#define EFI_RESOURCE_ATTRIBUTE_TESTED 0x00000004
+#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED 0x00000080
+//
+// This is typically used as memory cacheability attribute today.
+// NOTE: Since PI spec 1.4, please use EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED
+// as Physical write protected attribute, and EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED
+// means Memory cacheability attribute: The memory supports being programmed with
+// a writeprotected cacheable attribute.
+//
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED 0x00000100
+#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED 0x00000200
+#define EFI_RESOURCE_ATTRIBUTE_PERSISTENT 0x00800000
+//
+// The rest of the attributes are used to describe capabilities
+//
+#define EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC 0x00000008
+#define EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC 0x00000010
+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 0x00000020
+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 0x00000040
+#define EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE 0x00000400
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE 0x00000800
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE 0x00001000
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE 0x00002000
+#define EFI_RESOURCE_ATTRIBUTE_16_BIT_IO 0x00004000
+#define EFI_RESOURCE_ATTRIBUTE_32_BIT_IO 0x00008000
+#define EFI_RESOURCE_ATTRIBUTE_64_BIT_IO 0x00010000
+#define EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED 0x00020000
+#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE 0x00100000
+//
+// This is typically used as memory cacheability attribute today.
+// NOTE: Since PI spec 1.4, please use EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE
+// as Memory capability attribute: The memory supports being protected from processor
+// writes, and EFI_RESOURCE_ATTRIBUTE_WRITE_PROTEC TABLE means Memory cacheability attribute:
+// The memory supports being programmed with a writeprotected cacheable attribute.
+//
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE 0x00200000
+#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE 0x00400000
+#define EFI_RESOURCE_ATTRIBUTE_PERSISTABLE 0x01000000
+
+#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED 0x00040000
+#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE 0x00080000
+
+#define EFI_RESOURCE_ATTRIBUTE_ENCRYPTED 0x04000000
+#define EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE 0x08000000
+#define EFI_RESOURCE_ATTRIBUTE_HOT_PLUGGABLE 0x10000000
+//
+// Physical memory relative reliability attribute. This
+// memory provides higher reliability relative to other
+// memory in the system. If all memory has the same
+// reliability, then this bit is not used.
+//
+#define EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE 0x02000000
+
+///
+/// Describes the resource properties of all fixed,
+/// nonrelocatable resource ranges found on the processor
+/// host bus during the HOB producer phase.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_RESOURCE_DESCRIPTOR.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+ ///
+ /// A GUID representing the owner of the resource. This GUID is used by HOB
+ /// consumer phase components to correlate device ownership of a resource.
+ ///
+ EFI_GUID Owner;
+ ///
+ /// The resource type enumeration as defined by EFI_RESOURCE_TYPE.
+ ///
+ EFI_RESOURCE_TYPE ResourceType;
+ ///
+ /// Resource attributes as defined by EFI_RESOURCE_ATTRIBUTE_TYPE.
+ ///
+ EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;
+ ///
+ /// The physical start address of the resource region.
+ ///
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ ///
+ /// The number of bytes of the resource region.
+ ///
+ UINT64 ResourceLength;
+} EFI_HOB_RESOURCE_DESCRIPTOR;
+
+///
+/// Allows writers of executable content in the HOB producer phase to
+/// maintain and manage HOBs with specific GUID.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_GUID_EXTENSION.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+ ///
+ /// A GUID that defines the contents of this HOB.
+ ///
+ EFI_GUID Name;
+ //
+ // Guid specific data goes here
+ //
+} EFI_HOB_GUID_TYPE;
+
+///
+/// Details the location of firmware volumes that contain firmware files.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_FV.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+ ///
+ /// The physical memory-mapped base address of the firmware volume.
+ ///
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ ///
+ /// The length in bytes of the firmware volume.
+ ///
+ UINT64 Length;
+} EFI_HOB_FIRMWARE_VOLUME;
+
+///
+/// Details the location of a firmware volume that was extracted
+/// from a file within another firmware volume.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_FV2.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+ ///
+ /// The physical memory-mapped base address of the firmware volume.
+ ///
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ ///
+ /// The length in bytes of the firmware volume.
+ ///
+ UINT64 Length;
+ ///
+ /// The name of the firmware volume.
+ ///
+ EFI_GUID FvName;
+ ///
+ /// The name of the firmware file that contained this firmware volume.
+ ///
+ EFI_GUID FileName;
+} EFI_HOB_FIRMWARE_VOLUME2;
+
+///
+/// Details the location of a firmware volume that was extracted
+/// from a file within another firmware volume.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_FV3.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+ ///
+ /// The physical memory-mapped base address of the firmware volume.
+ ///
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ ///
+ /// The length in bytes of the firmware volume.
+ ///
+ UINT64 Length;
+ ///
+ /// The authentication status.
+ ///
+ UINT32 AuthenticationStatus;
+ ///
+ /// TRUE if the FV was extracted as a file within another firmware volume.
+ /// FALSE otherwise.
+ ///
+ BOOLEAN ExtractedFv;
+ ///
+ /// The name of the firmware volume.
+ /// Valid only if IsExtractedFv is TRUE.
+ ///
+ EFI_GUID FvName;
+ ///
+ /// The name of the firmware file that contained this firmware volume.
+ /// Valid only if IsExtractedFv is TRUE.
+ ///
+ EFI_GUID FileName;
+} EFI_HOB_FIRMWARE_VOLUME3;
+
+///
+/// Describes processor information, such as address space and I/O space capabilities.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_CPU.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+ ///
+ /// Identifies the maximum physical memory addressability of the processor.
+ ///
+ UINT8 SizeOfMemorySpace;
+ ///
+ /// Identifies the maximum physical I/O addressability of the processor.
+ ///
+ UINT8 SizeOfIoSpace;
+ ///
+ /// This field will always be set to zero.
+ ///
+ UINT8 Reserved[6];
+} EFI_HOB_CPU;
+
+///
+/// Describes pool memory allocations.
+///
+typedef struct {
+ ///
+ /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_POOL.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+} EFI_HOB_MEMORY_POOL;
+
+///
+/// Each UEFI capsule HOB details the location of a UEFI capsule. It includes a base address and length
+/// which is based upon memory blocks with a EFI_CAPSULE_HEADER and the associated
+/// CapsuleImageSize-based payloads. These HOB's shall be created by the PEI PI firmware
+/// sometime after the UEFI UpdateCapsule service invocation with the
+/// CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag set in the EFI_CAPSULE_HEADER.
+///
+typedef struct {
+ ///
+ /// The HOB generic header where Header.HobType = EFI_HOB_TYPE_UEFI_CAPSULE.
+ ///
+ EFI_HOB_GENERIC_HEADER Header;
+
+ ///
+ /// The physical memory-mapped base address of an UEFI capsule. This value is set to
+ /// point to the base of the contiguous memory of the UEFI capsule.
+ /// The length of the contiguous memory in bytes.
+ ///
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 Length;
+} EFI_HOB_UEFI_CAPSULE;
+
+///
+/// Union of all the possible HOB Types.
+///
+typedef union {
+ EFI_HOB_GENERIC_HEADER *Header;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable;
+ EFI_HOB_MEMORY_ALLOCATION *MemoryAllocation;
+ EFI_HOB_MEMORY_ALLOCATION_BSP_STORE *MemoryAllocationBspStore;
+ EFI_HOB_MEMORY_ALLOCATION_STACK *MemoryAllocationStack;
+ EFI_HOB_MEMORY_ALLOCATION_MODULE *MemoryAllocationModule;
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceDescriptor;
+ EFI_HOB_GUID_TYPE *Guid;
+ EFI_HOB_FIRMWARE_VOLUME *FirmwareVolume;
+ EFI_HOB_FIRMWARE_VOLUME2 *FirmwareVolume2;
+ EFI_HOB_FIRMWARE_VOLUME3 *FirmwareVolume3;
+ EFI_HOB_CPU *Cpu;
+ EFI_HOB_MEMORY_POOL *Pool;
+ EFI_HOB_UEFI_CAPSULE *Capsule;
+ UINT8 *Raw;
+} EFI_PEI_HOB_POINTERS;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Pi/PiMultiPhase.h b/sys/contrib/edk2/Include/Pi/PiMultiPhase.h new file mode 100644 index 000000000000..1c7332e7332c --- /dev/null +++ b/sys/contrib/edk2/Include/Pi/PiMultiPhase.h @@ -0,0 +1,218 @@ +/** @file
+ Include file matches things in PI for multiple module types.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ These elements are defined in UEFI Platform Initialization Specification 1.8.A
+
+**/
+
+#ifndef __PI_MULTIPHASE_H__
+#define __PI_MULTIPHASE_H__
+
+#include <Pi/PiFirmwareVolume.h>
+#include <Pi/PiFirmwareFile.h>
+#include <Pi/PiBootMode.h>
+#include <Pi/PiHob.h>
+#include <Pi/PiDependency.h>
+#include <Pi/PiStatusCode.h>
+#include <Pi/PiS3BootScript.h>
+
+//
+// PI Specification Version Information
+//
+#define PI_SPECIFICATION_MAJOR_REVISION 1
+#define PI_SPECIFICATION_MINOR_REVISION 80
+#define PI_SPECIFICATION_VERSION ((PI_SPECIFICATION_MAJOR_REVISION << 16) | (PI_SPECIFICATION_MINOR_REVISION))
+
+/**
+ Produces an error code in the range reserved for use by the Platform Initialization
+ Architecture Specification.
+
+ The supported 32-bit range is 0xA0000000-0xBFFFFFFF
+ The supported 64-bit range is 0xA000000000000000-0xBFFFFFFFFFFFFFFF
+
+ @param StatusCode The status code value to convert into a warning code.
+ StatusCode must be in the range 0x00000000..0x1FFFFFFF.
+
+ @return The value specified by StatusCode in the PI reserved range.
+
+**/
+#define DXE_ERROR(StatusCode) (MAX_BIT | (MAX_BIT >> 2) | StatusCode)
+
+///
+/// If this value is returned by an EFI image, then the image should be unloaded.
+///
+#define EFI_REQUEST_UNLOAD_IMAGE DXE_ERROR (1)
+
+///
+/// If this value is returned by an API, it means the capability is not yet
+/// installed/available/ready to use.
+///
+#define EFI_NOT_AVAILABLE_YET DXE_ERROR (2)
+
+///
+/// Success and warning codes reserved for use by PI.
+/// Supported 32-bit range is 0x20000000-0x3fffffff.
+/// Supported 64-bit range is 0x2000000000000000-0x3fffffffffffffff.
+///
+#define PI_ENCODE_WARNING(a) ((MAX_BIT >> 2) | (a))
+
+///
+/// Error codes reserved for use by PI.
+/// Supported 32-bit range is 0xa0000000-0xbfffffff.
+/// Supported 64-bit range is 0xa000000000000000-0xbfffffffffffffff.
+///
+#define PI_ENCODE_ERROR(a) (MAX_BIT | (MAX_BIT >> 2) | (a))
+
+///
+/// Return status codes defined in SMM CIS.
+///
+#define EFI_INTERRUPT_PENDING PI_ENCODE_ERROR (0)
+
+#define EFI_WARN_INTERRUPT_SOURCE_PENDING PI_ENCODE_WARNING (0)
+#define EFI_WARN_INTERRUPT_SOURCE_QUIESCED PI_ENCODE_WARNING (1)
+
+///
+/// Bitmask of values for Authentication Status.
+/// Authentication Status is returned from EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL
+/// and the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
+///
+/// xx00 Image was not signed.
+/// xxx1 Platform security policy override. Assumes the same meaning as 0010 (the image was signed, the
+/// signature was tested, and the signature passed authentication test).
+/// 0010 Image was signed, the signature was tested, and the signature passed authentication test.
+/// 0110 Image was signed and the signature was not tested.
+/// 1010 Image was signed, the signature was tested, and the signature failed the authentication test.
+///
+///@{
+#define EFI_AUTH_STATUS_PLATFORM_OVERRIDE 0x01
+#define EFI_AUTH_STATUS_IMAGE_SIGNED 0x02
+#define EFI_AUTH_STATUS_NOT_TESTED 0x04
+#define EFI_AUTH_STATUS_TEST_FAILED 0x08
+#define EFI_AUTH_STATUS_ALL 0x0f
+///@}
+
+///
+/// MMRAM states and capabilities
+///
+#define EFI_MMRAM_OPEN 0x00000001
+#define EFI_MMRAM_CLOSED 0x00000002
+#define EFI_MMRAM_LOCKED 0x00000004
+#define EFI_CACHEABLE 0x00000008
+#define EFI_ALLOCATED 0x00000010
+#define EFI_NEEDS_TESTING 0x00000020
+#define EFI_NEEDS_ECC_INITIALIZATION 0x00000040
+
+#define EFI_SMRAM_OPEN EFI_MMRAM_OPEN
+#define EFI_SMRAM_CLOSED EFI_MMRAM_CLOSED
+#define EFI_SMRAM_LOCKED EFI_MMRAM_LOCKED
+
+///
+/// Structure describing a MMRAM region and its accessibility attributes.
+///
+typedef struct {
+ ///
+ /// Designates the physical address of the MMRAM in memory. This view of memory is
+ /// the same as seen by I/O-based agents, for example, but it may not be the address seen
+ /// by the processors.
+ ///
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ ///
+ /// Designates the address of the MMRAM, as seen by software executing on the
+ /// processors. This address may or may not match PhysicalStart.
+ ///
+ EFI_PHYSICAL_ADDRESS CpuStart;
+ ///
+ /// Describes the number of bytes in the MMRAM region.
+ ///
+ UINT64 PhysicalSize;
+ ///
+ /// Describes the accessibility attributes of the MMRAM. These attributes include the
+ /// hardware state (e.g., Open/Closed/Locked), capability (e.g., cacheable), logical
+ /// allocation (e.g., allocated), and pre-use initialization (e.g., needs testing/ECC
+ /// initialization).
+ ///
+ UINT64 RegionState;
+} EFI_MMRAM_DESCRIPTOR;
+
+typedef EFI_MMRAM_DESCRIPTOR EFI_SMRAM_DESCRIPTOR;
+
+///
+/// Structure describing a MMRAM region which cannot be used for the MMRAM heap.
+///
+typedef struct _EFI_MM_RESERVED_MMRAM_REGION {
+ ///
+ /// Starting address of the reserved MMRAM area, as it appears while MMRAM is open.
+ /// Ignored if MmramReservedSize is 0.
+ ///
+ EFI_PHYSICAL_ADDRESS MmramReservedStart;
+ ///
+ /// Number of bytes occupied by the reserved MMRAM area. A size of zero indicates the
+ /// last MMRAM area.
+ ///
+ UINT64 MmramReservedSize;
+} EFI_MM_RESERVED_MMRAM_REGION;
+
+typedef enum {
+ EFI_PCD_TYPE_8,
+ EFI_PCD_TYPE_16,
+ EFI_PCD_TYPE_32,
+ EFI_PCD_TYPE_64,
+ EFI_PCD_TYPE_BOOL,
+ EFI_PCD_TYPE_PTR
+} EFI_PCD_TYPE;
+
+typedef struct {
+ ///
+ /// The returned information associated with the requested TokenNumber. If
+ /// TokenNumber is 0, then PcdType is set to EFI_PCD_TYPE_8.
+ ///
+ EFI_PCD_TYPE PcdType;
+ ///
+ /// The size of the data in bytes associated with the TokenNumber specified. If
+ /// TokenNumber is 0, then PcdSize is set 0.
+ ///
+ UINTN PcdSize;
+ ///
+ /// The null-terminated ASCII string associated with a given token. If the
+ /// TokenNumber specified was 0, then this field corresponds to the null-terminated
+ /// ASCII string associated with the token's namespace Guid. If NULL, there is no
+ /// name associated with this request.
+ ///
+ CHAR8 *PcdName;
+} EFI_PCD_INFO;
+
+/**
+ The function prototype for invoking a function on an Application Processor.
+
+ This definition is used by the UEFI MP Serices Protocol, and the
+ PI SMM System Table.
+
+ @param[in,out] Buffer The pointer to private data buffer.
+**/
+typedef
+VOID
+(EFIAPI *EFI_AP_PROCEDURE)(
+ IN OUT VOID *Buffer
+ );
+
+/**
+ The function prototype for invoking a function on an Application Processor.
+
+ This definition is used by the UEFI MM MP Serices Protocol.
+
+ @param[in] ProcedureArgument The pointer to private data buffer.
+
+ @retval EFI_SUCCESS Excutive the procedure successfully
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_AP_PROCEDURE2)(
+ IN VOID *ProcedureArgument
+ );
+
+#endif
diff --git a/sys/contrib/edk2/Include/Pi/PiS3BootScript.h b/sys/contrib/edk2/Include/Pi/PiS3BootScript.h new file mode 100644 index 000000000000..5803ec4a1eff --- /dev/null +++ b/sys/contrib/edk2/Include/Pi/PiS3BootScript.h @@ -0,0 +1,53 @@ +/** @file
+ This file contains the boot script defintions that are shared between the
+ Boot Script Executor PPI and the Boot Script Save Protocol.
+
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PI_S3_BOOT_SCRIPT_H_
+#define _PI_S3_BOOT_SCRIPT_H_
+
+// *******************************************
+// EFI Boot Script Opcode definitions
+// *******************************************
+#define EFI_BOOT_SCRIPT_IO_WRITE_OPCODE 0x00
+#define EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE 0x01
+#define EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE 0x02
+#define EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE 0x03
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE 0x04
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE 0x05
+#define EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE 0x06
+#define EFI_BOOT_SCRIPT_STALL_OPCODE 0x07
+#define EFI_BOOT_SCRIPT_DISPATCH_OPCODE 0x08
+#define EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE 0x09
+#define EFI_BOOT_SCRIPT_INFORMATION_OPCODE 0x0A
+#define EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE 0x0B
+#define EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE 0x0C
+#define EFI_BOOT_SCRIPT_IO_POLL_OPCODE 0x0D
+#define EFI_BOOT_SCRIPT_MEM_POLL_OPCODE 0x0E
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE 0x0F
+#define EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE 0x10
+
+// *******************************************
+// EFI_BOOT_SCRIPT_WIDTH
+// *******************************************
+typedef enum {
+ EfiBootScriptWidthUint8,
+ EfiBootScriptWidthUint16,
+ EfiBootScriptWidthUint32,
+ EfiBootScriptWidthUint64,
+ EfiBootScriptWidthFifoUint8,
+ EfiBootScriptWidthFifoUint16,
+ EfiBootScriptWidthFifoUint32,
+ EfiBootScriptWidthFifoUint64,
+ EfiBootScriptWidthFillUint8,
+ EfiBootScriptWidthFillUint16,
+ EfiBootScriptWidthFillUint32,
+ EfiBootScriptWidthFillUint64,
+ EfiBootScriptWidthMaximum
+} EFI_BOOT_SCRIPT_WIDTH;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Pi/PiStatusCode.h b/sys/contrib/edk2/Include/Pi/PiStatusCode.h new file mode 100644 index 000000000000..c083a1bb5224 --- /dev/null +++ b/sys/contrib/edk2/Include/Pi/PiStatusCode.h @@ -0,0 +1,1220 @@ +/** @file
+ StatusCode related definitions in PI.
+
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ These status codes are defined in UEFI Platform Initialization Specification 1.2,
+ Volume 3: Shared Architectural Elements.
+
+**/
+
+#ifndef __PI_STATUS_CODE_H__
+#define __PI_STATUS_CODE_H__
+
+//
+// Required for IA32, X64, IPF, ARM and EBC defines for CPU exception types
+//
+#include <Protocol/DebugSupport.h>
+
+///
+/// Status Code Type Definition.
+///
+typedef UINT32 EFI_STATUS_CODE_TYPE;
+
+///
+/// A Status Code Type is made up of the code type and severity.
+/// All values masked by EFI_STATUS_CODE_RESERVED_MASK are
+/// reserved for use by this specification.
+///
+///@{
+#define EFI_STATUS_CODE_TYPE_MASK 0x000000FF
+#define EFI_STATUS_CODE_SEVERITY_MASK 0xFF000000
+#define EFI_STATUS_CODE_RESERVED_MASK 0x00FFFF00
+///@}
+
+///
+/// Definition of code types. All other values masked by
+/// EFI_STATUS_CODE_TYPE_MASK are reserved for use by
+/// this specification.
+///
+///@{
+#define EFI_PROGRESS_CODE 0x00000001
+#define EFI_ERROR_CODE 0x00000002
+#define EFI_DEBUG_CODE 0x00000003
+///@}
+
+///
+/// Definitions of severities, all other values masked by
+/// EFI_STATUS_CODE_SEVERITY_MASK are reserved for use by
+/// this specification.
+/// Uncontained errors are major errors that could not contained
+/// to the specific component that is reporting the error.
+/// For example, if a memory error was not detected early enough,
+/// the bad data could be consumed by other drivers.
+///
+///@{
+#define EFI_ERROR_MINOR 0x40000000
+#define EFI_ERROR_MAJOR 0x80000000
+#define EFI_ERROR_UNRECOVERED 0x90000000
+#define EFI_ERROR_UNCONTAINED 0xa0000000
+///@}
+
+///
+/// Status Code Value Definition.
+///
+typedef UINT32 EFI_STATUS_CODE_VALUE;
+
+///
+/// A Status Code Value is made up of the class, subclass, and
+/// an operation.
+///
+///@{
+#define EFI_STATUS_CODE_CLASS_MASK 0xFF000000
+#define EFI_STATUS_CODE_SUBCLASS_MASK 0x00FF0000
+#define EFI_STATUS_CODE_OPERATION_MASK 0x0000FFFF
+///@}
+
+///
+/// Definition of Status Code extended data header.
+/// The data will follow HeaderSize bytes from the beginning of
+/// the structure and is Size bytes long.
+///
+typedef struct {
+ ///
+ /// The size of the structure. This is specified to enable future expansion.
+ ///
+ UINT16 HeaderSize;
+ ///
+ /// The size of the data in bytes. This does not include the size of the header structure.
+ ///
+ UINT16 Size;
+ ///
+ /// The GUID defining the type of the data.
+ ///
+ EFI_GUID Type;
+} EFI_STATUS_CODE_DATA;
+
+///
+/// General partitioning scheme for Progress and Error Codes are:
+/// - 0x0000-0x0FFF Shared by all sub-classes in a given class.
+/// - 0x1000-0x7FFF Subclass Specific.
+/// - 0x8000-0xFFFF OEM specific.
+///@{
+#define EFI_SUBCLASS_SPECIFIC 0x1000
+#define EFI_OEM_SPECIFIC 0x8000
+///@}
+
+///
+/// Debug Code definitions for all classes and subclass.
+/// Only one debug code is defined at this point and should
+/// be used for anything that is sent to the debug stream.
+///
+///@{
+#define EFI_DC_UNSPECIFIED 0x0
+///@}
+
+///
+/// Class definitions.
+/// Values of 4-127 are reserved for future use by this specification.
+/// Values in the range 127-255 are reserved for OEM use.
+///
+///@{
+#define EFI_COMPUTING_UNIT 0x00000000
+#define EFI_PERIPHERAL 0x01000000
+#define EFI_IO_BUS 0x02000000
+#define EFI_SOFTWARE 0x03000000
+///@}
+
+///
+/// Computing Unit Subclass definitions.
+/// Values of 8-127 are reserved for future use by this specification.
+/// Values of 128-255 are reserved for OEM use.
+///
+///@{
+#define EFI_COMPUTING_UNIT_UNSPECIFIED (EFI_COMPUTING_UNIT | 0x00000000)
+#define EFI_COMPUTING_UNIT_HOST_PROCESSOR (EFI_COMPUTING_UNIT | 0x00010000)
+#define EFI_COMPUTING_UNIT_FIRMWARE_PROCESSOR (EFI_COMPUTING_UNIT | 0x00020000)
+#define EFI_COMPUTING_UNIT_IO_PROCESSOR (EFI_COMPUTING_UNIT | 0x00030000)
+#define EFI_COMPUTING_UNIT_CACHE (EFI_COMPUTING_UNIT | 0x00040000)
+#define EFI_COMPUTING_UNIT_MEMORY (EFI_COMPUTING_UNIT | 0x00050000)
+#define EFI_COMPUTING_UNIT_CHIPSET (EFI_COMPUTING_UNIT | 0x00060000)
+#define EFI_COMPUTING_UNIT_MANAGEABILITY (EFI_COMPUTING_UNIT | 0x00070000)
+///@}
+
+///
+/// Computing Unit Class Progress Code definitions.
+/// These are shared by all subclasses.
+///
+///@{
+#define EFI_CU_PC_INIT_BEGIN 0x00000000
+#define EFI_CU_PC_INIT_END 0x00000001
+///@}
+
+//
+// Computing Unit Unspecified Subclass Progress Code definitions.
+//
+
+///
+/// Computing Unit Host Processor Subclass Progress Code definitions.
+///@{
+#define EFI_CU_HP_PC_POWER_ON_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_CU_HP_PC_CACHE_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_CU_HP_PC_RAM_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_CU_HP_PC_MEMORY_CONTROLLER_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_CU_HP_PC_IO_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_CU_HP_PC_BSP_SELECT (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_CU_HP_PC_BSP_RESELECT (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+#define EFI_CU_HP_PC_AP_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000007)
+#define EFI_CU_HP_PC_SMM_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000008)
+///@}
+
+//
+// Computing Unit Firmware Processor Subclass Progress Code definitions.
+//
+
+//
+// Computing Unit IO Processor Subclass Progress Code definitions.
+//
+
+///
+/// Computing Unit Cache Subclass Progress Code definitions.
+///
+///@{
+#define EFI_CU_CACHE_PC_PRESENCE_DETECT (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_CU_CACHE_PC_CONFIGURATION (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+///@}
+
+///
+/// Computing Unit Memory Subclass Progress Code definitions.
+///
+///@{
+#define EFI_CU_MEMORY_PC_SPD_READ (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_CU_MEMORY_PC_PRESENCE_DETECT (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_CU_MEMORY_PC_TIMING (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_CU_MEMORY_PC_CONFIGURING (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_CU_MEMORY_PC_OPTIMIZING (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_CU_MEMORY_PC_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_CU_MEMORY_PC_TEST (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+///@}
+
+//
+// Computing Unit Chipset Subclass Progress Code definitions.
+//
+
+///
+/// South Bridge initialization prior to memory detection.
+///
+#define EFI_CHIPSET_PC_PEI_CAR_SB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000000)
+
+///
+/// North Bridge initialization prior to memory detection.
+///
+#define EFI_CHIPSET_PC_PEI_CAR_NB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000001)
+
+///
+/// South Bridge initialization after memory detection.
+///
+#define EFI_CHIPSET_PC_PEI_MEM_SB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000002)
+
+///
+/// North Bridge initialization after memory detection.
+///
+#define EFI_CHIPSET_PC_PEI_MEM_NB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000003)
+
+///
+/// PCI Host Bridge DXE initialization.
+///
+#define EFI_CHIPSET_PC_DXE_HB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000004)
+
+///
+/// North Bridge DXE initialization.
+///
+#define EFI_CHIPSET_PC_DXE_NB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000005)
+
+///
+/// North Bridge specific SMM initialization in DXE.
+///
+#define EFI_CHIPSET_PC_DXE_NB_SMM_INIT (EFI_SUBCLASS_SPECIFIC|0x00000006)
+
+///
+/// Initialization of the South Bridge specific UEFI Runtime Services.
+///
+#define EFI_CHIPSET_PC_DXE_SB_RT_INIT (EFI_SUBCLASS_SPECIFIC|0x00000007)
+
+///
+/// South Bridge DXE initialization
+///
+#define EFI_CHIPSET_PC_DXE_SB_INIT (EFI_SUBCLASS_SPECIFIC|0x00000008)
+
+///
+/// South Bridge specific SMM initialization in DXE.
+///
+#define EFI_CHIPSET_PC_DXE_SB_SMM_INIT (EFI_SUBCLASS_SPECIFIC|0x00000009)
+
+///
+/// Initialization of the South Bridge devices.
+///
+#define EFI_CHIPSET_PC_DXE_SB_DEVICES_INIT (EFI_SUBCLASS_SPECIFIC|0x0000000a)
+
+///
+/// Computing Unit Class Error Code definitions.
+/// These are shared by all subclasses.
+///
+///@{
+#define EFI_CU_EC_NON_SPECIFIC 0x00000000
+#define EFI_CU_EC_DISABLED 0x00000001
+#define EFI_CU_EC_NOT_SUPPORTED 0x00000002
+#define EFI_CU_EC_NOT_DETECTED 0x00000003
+#define EFI_CU_EC_NOT_CONFIGURED 0x00000004
+///@}
+
+//
+// Computing Unit Unspecified Subclass Error Code definitions.
+//
+
+///
+/// Computing Unit Host Processor Subclass Error Code definitions.
+///
+///@{
+#define EFI_CU_HP_EC_INVALID_TYPE (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_CU_HP_EC_INVALID_SPEED (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_CU_HP_EC_MISMATCH (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_CU_HP_EC_TIMER_EXPIRED (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_CU_HP_EC_SELF_TEST (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_CU_HP_EC_INTERNAL (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_CU_HP_EC_THERMAL (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+#define EFI_CU_HP_EC_LOW_VOLTAGE (EFI_SUBCLASS_SPECIFIC | 0x00000007)
+#define EFI_CU_HP_EC_HIGH_VOLTAGE (EFI_SUBCLASS_SPECIFIC | 0x00000008)
+#define EFI_CU_HP_EC_CACHE (EFI_SUBCLASS_SPECIFIC | 0x00000009)
+#define EFI_CU_HP_EC_MICROCODE_UPDATE (EFI_SUBCLASS_SPECIFIC | 0x0000000A)
+#define EFI_CU_HP_EC_CORRECTABLE (EFI_SUBCLASS_SPECIFIC | 0x0000000B)
+#define EFI_CU_HP_EC_UNCORRECTABLE (EFI_SUBCLASS_SPECIFIC | 0x0000000C)
+#define EFI_CU_HP_EC_NO_MICROCODE_UPDATE (EFI_SUBCLASS_SPECIFIC | 0x0000000D)
+///@}
+
+///
+/// Computing Unit Firmware Processor Subclass Error Code definitions.
+///
+///@{
+#define EFI_CU_FP_EC_HARD_FAIL (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_CU_FP_EC_SOFT_FAIL (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_CU_FP_EC_COMM_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+///@}
+
+//
+// Computing Unit IO Processor Subclass Error Code definitions.
+//
+
+///
+/// Computing Unit Cache Subclass Error Code definitions.
+///
+///@{
+#define EFI_CU_CACHE_EC_INVALID_TYPE (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_CU_CACHE_EC_INVALID_SPEED (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_CU_CACHE_EC_INVALID_SIZE (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_CU_CACHE_EC_MISMATCH (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+///@}
+
+///
+/// Computing Unit Memory Subclass Error Code definitions.
+///
+///@{
+#define EFI_CU_MEMORY_EC_INVALID_TYPE (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_CU_MEMORY_EC_INVALID_SPEED (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_CU_MEMORY_EC_CORRECTABLE (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_CU_MEMORY_EC_UNCORRECTABLE (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_CU_MEMORY_EC_SPD_FAIL (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_CU_MEMORY_EC_INVALID_SIZE (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_CU_MEMORY_EC_MISMATCH (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+#define EFI_CU_MEMORY_EC_S3_RESUME_FAIL (EFI_SUBCLASS_SPECIFIC | 0x00000007)
+#define EFI_CU_MEMORY_EC_UPDATE_FAIL (EFI_SUBCLASS_SPECIFIC | 0x00000008)
+#define EFI_CU_MEMORY_EC_NONE_DETECTED (EFI_SUBCLASS_SPECIFIC | 0x00000009)
+#define EFI_CU_MEMORY_EC_NONE_USEFUL (EFI_SUBCLASS_SPECIFIC | 0x0000000A)
+///@}
+
+///
+/// Computing Unit Chipset Subclass Error Code definitions.
+///
+///@{
+#define EFI_CHIPSET_EC_BAD_BATTERY (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_CHIPSET_EC_DXE_NB_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_CHIPSET_EC_DXE_SB_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_CHIPSET_EC_INTRUDER_DETECT (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+///@}
+
+///
+/// Computing Unit Manageability Subclass Error Code definitions.
+/// The detail information is reported by REPORT_STATUS_CODE_WITH_EXTENDED_DATA
+// with ASCII string in EFI_STATUS_CODE_STRING_DATA.
+///@{
+#define EFI_MANAGEABILITY_EC_REDFISH_COMMUNICATION_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_MANAGEABILITY_EC_REDFISH_HOST_INTERFACE_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_MANAGEABILITY_EC_REDFISH_BOOTSTRAP_CREDENTIAL_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+///@}
+
+///
+/// Peripheral Subclass definitions.
+/// Values of 12-127 are reserved for future use by this specification.
+/// Values of 128-255 are reserved for OEM use.
+///
+///@{
+#define EFI_PERIPHERAL_UNSPECIFIED (EFI_PERIPHERAL | 0x00000000)
+#define EFI_PERIPHERAL_KEYBOARD (EFI_PERIPHERAL | 0x00010000)
+#define EFI_PERIPHERAL_MOUSE (EFI_PERIPHERAL | 0x00020000)
+#define EFI_PERIPHERAL_LOCAL_CONSOLE (EFI_PERIPHERAL | 0x00030000)
+#define EFI_PERIPHERAL_REMOTE_CONSOLE (EFI_PERIPHERAL | 0x00040000)
+#define EFI_PERIPHERAL_SERIAL_PORT (EFI_PERIPHERAL | 0x00050000)
+#define EFI_PERIPHERAL_PARALLEL_PORT (EFI_PERIPHERAL | 0x00060000)
+#define EFI_PERIPHERAL_FIXED_MEDIA (EFI_PERIPHERAL | 0x00070000)
+#define EFI_PERIPHERAL_REMOVABLE_MEDIA (EFI_PERIPHERAL | 0x00080000)
+#define EFI_PERIPHERAL_AUDIO_INPUT (EFI_PERIPHERAL | 0x00090000)
+#define EFI_PERIPHERAL_AUDIO_OUTPUT (EFI_PERIPHERAL | 0x000A0000)
+#define EFI_PERIPHERAL_LCD_DEVICE (EFI_PERIPHERAL | 0x000B0000)
+#define EFI_PERIPHERAL_NETWORK (EFI_PERIPHERAL | 0x000C0000)
+#define EFI_PERIPHERAL_DOCKING (EFI_PERIPHERAL | 0x000D0000)
+#define EFI_PERIPHERAL_TPM (EFI_PERIPHERAL | 0x000E0000)
+///@}
+
+///
+/// Peripheral Class Progress Code definitions.
+/// These are shared by all subclasses.
+///
+///@{
+#define EFI_P_PC_INIT 0x00000000
+#define EFI_P_PC_RESET 0x00000001
+#define EFI_P_PC_DISABLE 0x00000002
+#define EFI_P_PC_PRESENCE_DETECT 0x00000003
+#define EFI_P_PC_ENABLE 0x00000004
+#define EFI_P_PC_RECONFIG 0x00000005
+#define EFI_P_PC_DETECTED 0x00000006
+#define EFI_P_PC_REMOVED 0x00000007
+///@}
+
+//
+// Peripheral Class Unspecified Subclass Progress Code definitions.
+//
+
+///
+/// Peripheral Class Keyboard Subclass Progress Code definitions.
+///
+///@{
+#define EFI_P_KEYBOARD_PC_CLEAR_BUFFER (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_P_KEYBOARD_PC_SELF_TEST (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+///@}
+
+///
+/// Peripheral Class Mouse Subclass Progress Code definitions.
+///
+///@{
+#define EFI_P_MOUSE_PC_SELF_TEST (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+///@}
+
+//
+// Peripheral Class Local Console Subclass Progress Code definitions.
+//
+
+//
+// Peripheral Class Remote Console Subclass Progress Code definitions.
+//
+
+///
+/// Peripheral Class Serial Port Subclass Progress Code definitions.
+///
+///@{
+#define EFI_P_SERIAL_PORT_PC_CLEAR_BUFFER (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+///@}
+
+//
+// Peripheral Class Parallel Port Subclass Progress Code definitions.
+//
+
+//
+// Peripheral Class Fixed Media Subclass Progress Code definitions.
+//
+
+//
+// Peripheral Class Removable Media Subclass Progress Code definitions.
+//
+
+//
+// Peripheral Class Audio Input Subclass Progress Code definitions.
+//
+
+//
+// Peripheral Class Audio Output Subclass Progress Code definitions.
+//
+
+//
+// Peripheral Class LCD Device Subclass Progress Code definitions.
+//
+
+//
+// Peripheral Class Network Subclass Progress Code definitions.
+//
+
+///
+/// Peripheral Class Error Code definitions.
+/// These are shared by all subclasses.
+///
+///@{
+#define EFI_P_EC_NON_SPECIFIC 0x00000000
+#define EFI_P_EC_DISABLED 0x00000001
+#define EFI_P_EC_NOT_SUPPORTED 0x00000002
+#define EFI_P_EC_NOT_DETECTED 0x00000003
+#define EFI_P_EC_NOT_CONFIGURED 0x00000004
+#define EFI_P_EC_INTERFACE_ERROR 0x00000005
+#define EFI_P_EC_CONTROLLER_ERROR 0x00000006
+#define EFI_P_EC_INPUT_ERROR 0x00000007
+#define EFI_P_EC_OUTPUT_ERROR 0x00000008
+#define EFI_P_EC_RESOURCE_CONFLICT 0x00000009
+///@}
+
+//
+// Peripheral Class Unspecified Subclass Error Code definitions.
+//
+
+///
+/// Peripheral Class Keyboard Subclass Error Code definitions.
+///
+///@{
+#define EFI_P_KEYBOARD_EC_LOCKED (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_P_KEYBOARD_EC_STUCK_KEY (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_P_KEYBOARD_EC_BUFFER_FULL (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+///@}
+
+///
+/// Peripheral Class Mouse Subclass Error Code definitions.
+///
+///@{
+#define EFI_P_MOUSE_EC_LOCKED (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+///@}
+
+//
+// Peripheral Class Local Console Subclass Error Code definitions.
+//
+
+//
+// Peripheral Class Remote Console Subclass Error Code definitions.
+//
+
+//
+// Peripheral Class Serial Port Subclass Error Code definitions.
+//
+
+//
+// Peripheral Class Parallel Port Subclass Error Code definitions.
+//
+
+//
+// Peripheral Class Fixed Media Subclass Error Code definitions.
+//
+
+//
+// Peripheral Class Removable Media Subclass Error Code definitions.
+//
+
+//
+// Peripheral Class Audio Input Subclass Error Code definitions.
+//
+
+//
+// Peripheral Class Audio Output Subclass Error Code definitions.
+//
+
+//
+// Peripheral Class LCD Device Subclass Error Code definitions.
+//
+
+//
+// Peripheral Class Network Subclass Error Code definitions.
+//
+
+///
+/// IO Bus Subclass definitions.
+/// Values of 14-127 are reserved for future use by this specification.
+/// Values of 128-255 are reserved for OEM use.
+///
+///@{
+#define EFI_IO_BUS_UNSPECIFIED (EFI_IO_BUS | 0x00000000)
+#define EFI_IO_BUS_PCI (EFI_IO_BUS | 0x00010000)
+#define EFI_IO_BUS_USB (EFI_IO_BUS | 0x00020000)
+#define EFI_IO_BUS_IBA (EFI_IO_BUS | 0x00030000)
+#define EFI_IO_BUS_AGP (EFI_IO_BUS | 0x00040000)
+#define EFI_IO_BUS_PC_CARD (EFI_IO_BUS | 0x00050000)
+#define EFI_IO_BUS_LPC (EFI_IO_BUS | 0x00060000)
+#define EFI_IO_BUS_SCSI (EFI_IO_BUS | 0x00070000)
+#define EFI_IO_BUS_ATA_ATAPI (EFI_IO_BUS | 0x00080000)
+#define EFI_IO_BUS_FC (EFI_IO_BUS | 0x00090000)
+#define EFI_IO_BUS_IP_NETWORK (EFI_IO_BUS | 0x000A0000)
+#define EFI_IO_BUS_SMBUS (EFI_IO_BUS | 0x000B0000)
+#define EFI_IO_BUS_I2C (EFI_IO_BUS | 0x000C0000)
+///@}
+
+///
+/// IO Bus Class Progress Code definitions.
+/// These are shared by all subclasses.
+///
+///@{
+#define EFI_IOB_PC_INIT 0x00000000
+#define EFI_IOB_PC_RESET 0x00000001
+#define EFI_IOB_PC_DISABLE 0x00000002
+#define EFI_IOB_PC_DETECT 0x00000003
+#define EFI_IOB_PC_ENABLE 0x00000004
+#define EFI_IOB_PC_RECONFIG 0x00000005
+#define EFI_IOB_PC_HOTPLUG 0x00000006
+///@}
+
+//
+// IO Bus Class Unspecified Subclass Progress Code definitions.
+//
+
+///
+/// IO Bus Class PCI Subclass Progress Code definitions.
+///
+///@{
+#define EFI_IOB_PCI_BUS_ENUM (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_IOB_PCI_RES_ALLOC (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_IOB_PCI_HPC_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+///@}
+
+//
+// IO Bus Class USB Subclass Progress Code definitions.
+//
+
+//
+// IO Bus Class IBA Subclass Progress Code definitions.
+//
+
+//
+// IO Bus Class AGP Subclass Progress Code definitions.
+//
+
+//
+// IO Bus Class PC Card Subclass Progress Code definitions.
+//
+
+//
+// IO Bus Class LPC Subclass Progress Code definitions.
+//
+
+//
+// IO Bus Class SCSI Subclass Progress Code definitions.
+//
+
+//
+// IO Bus Class ATA/ATAPI Subclass Progress Code definitions.
+//
+#define EFI_IOB_ATA_BUS_SMART_ENABLE (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_IOB_ATA_BUS_SMART_DISABLE (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+//
+// IO Bus Class FC Subclass Progress Code definitions.
+//
+
+//
+// IO Bus Class IP Network Subclass Progress Code definitions.
+//
+
+//
+// IO Bus Class SMBUS Subclass Progress Code definitions.
+//
+
+//
+// IO Bus Class I2C Subclass Progress Code definitions.
+//
+
+///
+/// IO Bus Class Error Code definitions.
+/// These are shared by all subclasses.
+///
+///@{
+#define EFI_IOB_EC_NON_SPECIFIC 0x00000000
+#define EFI_IOB_EC_DISABLED 0x00000001
+#define EFI_IOB_EC_NOT_SUPPORTED 0x00000002
+#define EFI_IOB_EC_NOT_DETECTED 0x00000003
+#define EFI_IOB_EC_NOT_CONFIGURED 0x00000004
+#define EFI_IOB_EC_INTERFACE_ERROR 0x00000005
+#define EFI_IOB_EC_CONTROLLER_ERROR 0x00000006
+#define EFI_IOB_EC_READ_ERROR 0x00000007
+#define EFI_IOB_EC_WRITE_ERROR 0x00000008
+#define EFI_IOB_EC_RESOURCE_CONFLICT 0x00000009
+///@}
+
+//
+// IO Bus Class Unspecified Subclass Error Code definitions.
+//
+
+///
+/// IO Bus Class PCI Subclass Error Code definitions.
+///
+///@{
+#define EFI_IOB_PCI_EC_PERR (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_IOB_PCI_EC_SERR (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+///@}
+
+//
+// IO Bus Class USB Subclass Error Code definitions.
+//
+
+//
+// IO Bus Class IBA Subclass Error Code definitions.
+//
+
+//
+// IO Bus Class AGP Subclass Error Code definitions.
+//
+
+//
+// IO Bus Class PC Card Subclass Error Code definitions.
+//
+
+//
+// IO Bus Class LPC Subclass Error Code definitions.
+//
+
+//
+// IO Bus Class SCSI Subclass Error Code definitions.
+//
+
+//
+// IO Bus Class ATA/ATAPI Subclass Error Code definitions.
+//
+#define EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_IOB_ATA_BUS_SMART_DISABLED (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+
+//
+// IO Bus Class FC Subclass Error Code definitions.
+//
+
+//
+// IO Bus Class IP Network Subclass Error Code definitions.
+//
+
+//
+// IO Bus Class SMBUS Subclass Error Code definitions.
+//
+
+//
+// IO Bus Class I2C Subclass Error Code definitions.
+//
+
+///
+/// Software Subclass definitions.
+/// Values of 14-127 are reserved for future use by this specification.
+/// Values of 128-255 are reserved for OEM use.
+///
+///@{
+#define EFI_SOFTWARE_UNSPECIFIED (EFI_SOFTWARE | 0x00000000)
+#define EFI_SOFTWARE_SEC (EFI_SOFTWARE | 0x00010000)
+#define EFI_SOFTWARE_PEI_CORE (EFI_SOFTWARE | 0x00020000)
+#define EFI_SOFTWARE_PEI_MODULE (EFI_SOFTWARE | 0x00030000)
+#define EFI_SOFTWARE_DXE_CORE (EFI_SOFTWARE | 0x00040000)
+#define EFI_SOFTWARE_DXE_BS_DRIVER (EFI_SOFTWARE | 0x00050000)
+#define EFI_SOFTWARE_DXE_RT_DRIVER (EFI_SOFTWARE | 0x00060000)
+#define EFI_SOFTWARE_SMM_DRIVER (EFI_SOFTWARE | 0x00070000)
+#define EFI_SOFTWARE_EFI_APPLICATION (EFI_SOFTWARE | 0x00080000)
+#define EFI_SOFTWARE_EFI_OS_LOADER (EFI_SOFTWARE | 0x00090000)
+#define EFI_SOFTWARE_RT (EFI_SOFTWARE | 0x000A0000)
+#define EFI_SOFTWARE_AL (EFI_SOFTWARE | 0x000B0000)
+#define EFI_SOFTWARE_EBC_EXCEPTION (EFI_SOFTWARE | 0x000C0000)
+#define EFI_SOFTWARE_IA32_EXCEPTION (EFI_SOFTWARE | 0x000D0000)
+#define EFI_SOFTWARE_IPF_EXCEPTION (EFI_SOFTWARE | 0x000E0000)
+#define EFI_SOFTWARE_PEI_SERVICE (EFI_SOFTWARE | 0x000F0000)
+#define EFI_SOFTWARE_EFI_BOOT_SERVICE (EFI_SOFTWARE | 0x00100000)
+#define EFI_SOFTWARE_EFI_RUNTIME_SERVICE (EFI_SOFTWARE | 0x00110000)
+#define EFI_SOFTWARE_EFI_DXE_SERVICE (EFI_SOFTWARE | 0x00120000)
+#define EFI_SOFTWARE_X64_EXCEPTION (EFI_SOFTWARE | 0x00130000)
+#define EFI_SOFTWARE_ARM_EXCEPTION (EFI_SOFTWARE | 0x00140000)
+
+///@}
+
+///
+/// Software Class Progress Code definitions.
+/// These are shared by all subclasses.
+///
+///@{
+#define EFI_SW_PC_INIT 0x00000000
+#define EFI_SW_PC_LOAD 0x00000001
+#define EFI_SW_PC_INIT_BEGIN 0x00000002
+#define EFI_SW_PC_INIT_END 0x00000003
+#define EFI_SW_PC_AUTHENTICATE_BEGIN 0x00000004
+#define EFI_SW_PC_AUTHENTICATE_END 0x00000005
+#define EFI_SW_PC_INPUT_WAIT 0x00000006
+#define EFI_SW_PC_USER_SETUP 0x00000007
+///@}
+
+//
+// Software Class Unspecified Subclass Progress Code definitions.
+//
+
+///
+/// Software Class SEC Subclass Progress Code definitions.
+///
+///@{
+#define EFI_SW_SEC_PC_ENTRY_POINT (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_SEC_PC_HANDOFF_TO_NEXT (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+///@}
+
+///
+/// Software Class PEI Core Subclass Progress Code definitions.
+///
+///@{
+#define EFI_SW_PEI_CORE_PC_ENTRY_POINT (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_PEI_CORE_PC_RETURN_TO_LAST (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+///@}
+
+///
+/// Software Class PEI Module Subclass Progress Code definitions.
+///
+///@{
+#define EFI_SW_PEI_PC_RECOVERY_BEGIN (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_PEI_PC_CAPSULE_LOAD (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_PEI_PC_CAPSULE_START (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_SW_PEI_PC_RECOVERY_USER (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_SW_PEI_PC_RECOVERY_AUTO (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_SW_PEI_PC_S3_BOOT_SCRIPT (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_SW_PEI_PC_OS_WAKE (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+#define EFI_SW_PEI_PC_S3_STARTED (EFI_SUBCLASS_SPECIFIC | 0x00000007)
+///@}
+
+///
+/// Software Class DXE Core Subclass Progress Code definitions.
+///
+///@{
+#define EFI_SW_DXE_CORE_PC_ENTRY_POINT (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_DXE_CORE_PC_RETURN_TO_LAST (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_SW_DXE_CORE_PC_START_DRIVER (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_SW_DXE_CORE_PC_ARCH_READY (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+///@}
+
+///
+/// Software Class DXE BS Driver Subclass Progress Code definitions.
+///
+///@{
+#define EFI_SW_DXE_BS_PC_LEGACY_OPROM_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_SW_DXE_BS_PC_EXIT_BOOT_SERVICES_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_SW_DXE_BS_PC_VIRTUAL_ADDRESS_CHANGE_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_SW_DXE_BS_PC_VARIABLE_SERVICES_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_SW_DXE_BS_PC_VARIABLE_RECLAIM (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+#define EFI_SW_DXE_BS_PC_ATTEMPT_BOOT_ORDER_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000007)
+#define EFI_SW_DXE_BS_PC_CONFIG_RESET (EFI_SUBCLASS_SPECIFIC | 0x00000008)
+#define EFI_SW_DXE_BS_PC_CSM_INIT (EFI_SUBCLASS_SPECIFIC | 0x00000009)
+///@}
+
+//
+// Software Class SMM Driver Subclass Progress Code definitions.
+//
+
+//
+// Software Class EFI Application Subclass Progress Code definitions.
+//
+
+//
+// Software Class EFI OS Loader Subclass Progress Code definitions.
+//
+
+///
+/// Software Class EFI RT Subclass Progress Code definitions.
+///
+///@{
+#define EFI_SW_RT_PC_ENTRY_POINT (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_RT_PC_HANDOFF_TO_NEXT (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_RT_PC_RETURN_TO_LAST (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+///@}
+
+//
+// Software Class X64 Exception Subclass Progress Code definitions.
+//
+
+//
+// Software Class ARM Exception Subclass Progress Code definitions.
+//
+
+//
+// Software Class EBC Exception Subclass Progress Code definitions.
+//
+
+//
+// Software Class IA32 Exception Subclass Progress Code definitions.
+//
+
+//
+// Software Class X64 Exception Subclass Progress Code definitions.
+//
+
+//
+// Software Class IPF Exception Subclass Progress Code definitions.
+//
+
+///
+/// Software Class PEI Services Subclass Progress Code definitions.
+///
+///@{
+#define EFI_SW_PS_PC_INSTALL_PPI (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_PS_PC_REINSTALL_PPI (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_PS_PC_LOCATE_PPI (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_SW_PS_PC_NOTIFY_PPI (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_SW_PS_PC_GET_BOOT_MODE (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_SW_PS_PC_SET_BOOT_MODE (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_SW_PS_PC_GET_HOB_LIST (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+#define EFI_SW_PS_PC_CREATE_HOB (EFI_SUBCLASS_SPECIFIC | 0x00000007)
+#define EFI_SW_PS_PC_FFS_FIND_NEXT_VOLUME (EFI_SUBCLASS_SPECIFIC | 0x00000008)
+#define EFI_SW_PS_PC_FFS_FIND_NEXT_FILE (EFI_SUBCLASS_SPECIFIC | 0x00000009)
+#define EFI_SW_PS_PC_FFS_FIND_SECTION_DATA (EFI_SUBCLASS_SPECIFIC | 0x0000000A)
+#define EFI_SW_PS_PC_INSTALL_PEI_MEMORY (EFI_SUBCLASS_SPECIFIC | 0x0000000B)
+#define EFI_SW_PS_PC_ALLOCATE_PAGES (EFI_SUBCLASS_SPECIFIC | 0x0000000C)
+#define EFI_SW_PS_PC_ALLOCATE_POOL (EFI_SUBCLASS_SPECIFIC | 0x0000000D)
+#define EFI_SW_PS_PC_COPY_MEM (EFI_SUBCLASS_SPECIFIC | 0x0000000E)
+#define EFI_SW_PS_PC_SET_MEM (EFI_SUBCLASS_SPECIFIC | 0x0000000F)
+#define EFI_SW_PS_PC_RESET_SYSTEM (EFI_SUBCLASS_SPECIFIC | 0x00000010)
+#define EFI_SW_PS_PC_FFS_FIND_FILE_BY_NAME (EFI_SUBCLASS_SPECIFIC | 0x00000013)
+#define EFI_SW_PS_PC_FFS_GET_FILE_INFO (EFI_SUBCLASS_SPECIFIC | 0x00000014)
+#define EFI_SW_PS_PC_FFS_GET_VOLUME_INFO (EFI_SUBCLASS_SPECIFIC | 0x00000015)
+#define EFI_SW_PS_PC_FFS_REGISTER_FOR_SHADOW (EFI_SUBCLASS_SPECIFIC | 0x00000016)
+///@}
+
+///
+/// Software Class EFI Boot Services Subclass Progress Code definitions.
+///
+///@{
+#define EFI_SW_BS_PC_RAISE_TPL (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_BS_PC_RESTORE_TPL (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_BS_PC_ALLOCATE_PAGES (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_SW_BS_PC_FREE_PAGES (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_SW_BS_PC_GET_MEMORY_MAP (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_SW_BS_PC_ALLOCATE_POOL (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_SW_BS_PC_FREE_POOL (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+#define EFI_SW_BS_PC_CREATE_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000007)
+#define EFI_SW_BS_PC_SET_TIMER (EFI_SUBCLASS_SPECIFIC | 0x00000008)
+#define EFI_SW_BS_PC_WAIT_FOR_EVENT (EFI_SUBCLASS_SPECIFIC | 0x00000009)
+#define EFI_SW_BS_PC_SIGNAL_EVENT (EFI_SUBCLASS_SPECIFIC | 0x0000000A)
+#define EFI_SW_BS_PC_CLOSE_EVENT (EFI_SUBCLASS_SPECIFIC | 0x0000000B)
+#define EFI_SW_BS_PC_CHECK_EVENT (EFI_SUBCLASS_SPECIFIC | 0x0000000C)
+#define EFI_SW_BS_PC_INSTALL_PROTOCOL_INTERFACE (EFI_SUBCLASS_SPECIFIC | 0x0000000D)
+#define EFI_SW_BS_PC_REINSTALL_PROTOCOL_INTERFACE (EFI_SUBCLASS_SPECIFIC | 0x0000000E)
+#define EFI_SW_BS_PC_UNINSTALL_PROTOCOL_INTERFACE (EFI_SUBCLASS_SPECIFIC | 0x0000000F)
+#define EFI_SW_BS_PC_HANDLE_PROTOCOL (EFI_SUBCLASS_SPECIFIC | 0x00000010)
+#define EFI_SW_BS_PC_PC_HANDLE_PROTOCOL (EFI_SUBCLASS_SPECIFIC | 0x00000011)
+#define EFI_SW_BS_PC_REGISTER_PROTOCOL_NOTIFY (EFI_SUBCLASS_SPECIFIC | 0x00000012)
+#define EFI_SW_BS_PC_LOCATE_HANDLE (EFI_SUBCLASS_SPECIFIC | 0x00000013)
+#define EFI_SW_BS_PC_INSTALL_CONFIGURATION_TABLE (EFI_SUBCLASS_SPECIFIC | 0x00000014)
+#define EFI_SW_BS_PC_LOAD_IMAGE (EFI_SUBCLASS_SPECIFIC | 0x00000015)
+#define EFI_SW_BS_PC_START_IMAGE (EFI_SUBCLASS_SPECIFIC | 0x00000016)
+#define EFI_SW_BS_PC_EXIT (EFI_SUBCLASS_SPECIFIC | 0x00000017)
+#define EFI_SW_BS_PC_UNLOAD_IMAGE (EFI_SUBCLASS_SPECIFIC | 0x00000018)
+#define EFI_SW_BS_PC_EXIT_BOOT_SERVICES (EFI_SUBCLASS_SPECIFIC | 0x00000019)
+#define EFI_SW_BS_PC_GET_NEXT_MONOTONIC_COUNT (EFI_SUBCLASS_SPECIFIC | 0x0000001A)
+#define EFI_SW_BS_PC_STALL (EFI_SUBCLASS_SPECIFIC | 0x0000001B)
+#define EFI_SW_BS_PC_SET_WATCHDOG_TIMER (EFI_SUBCLASS_SPECIFIC | 0x0000001C)
+#define EFI_SW_BS_PC_CONNECT_CONTROLLER (EFI_SUBCLASS_SPECIFIC | 0x0000001D)
+#define EFI_SW_BS_PC_DISCONNECT_CONTROLLER (EFI_SUBCLASS_SPECIFIC | 0x0000001E)
+#define EFI_SW_BS_PC_OPEN_PROTOCOL (EFI_SUBCLASS_SPECIFIC | 0x0000001F)
+#define EFI_SW_BS_PC_CLOSE_PROTOCOL (EFI_SUBCLASS_SPECIFIC | 0x00000020)
+#define EFI_SW_BS_PC_OPEN_PROTOCOL_INFORMATION (EFI_SUBCLASS_SPECIFIC | 0x00000021)
+#define EFI_SW_BS_PC_PROTOCOLS_PER_HANDLE (EFI_SUBCLASS_SPECIFIC | 0x00000022)
+#define EFI_SW_BS_PC_LOCATE_HANDLE_BUFFER (EFI_SUBCLASS_SPECIFIC | 0x00000023)
+#define EFI_SW_BS_PC_LOCATE_PROTOCOL (EFI_SUBCLASS_SPECIFIC | 0x00000024)
+#define EFI_SW_BS_PC_INSTALL_MULTIPLE_INTERFACES (EFI_SUBCLASS_SPECIFIC | 0x00000025)
+#define EFI_SW_BS_PC_UNINSTALL_MULTIPLE_INTERFACES (EFI_SUBCLASS_SPECIFIC | 0x00000026)
+#define EFI_SW_BS_PC_CALCULATE_CRC_32 (EFI_SUBCLASS_SPECIFIC | 0x00000027)
+#define EFI_SW_BS_PC_COPY_MEM (EFI_SUBCLASS_SPECIFIC | 0x00000028)
+#define EFI_SW_BS_PC_SET_MEM (EFI_SUBCLASS_SPECIFIC | 0x00000029)
+#define EFI_SW_BS_PC_CREATE_EVENT_EX (EFI_SUBCLASS_SPECIFIC | 0x0000002A)
+///@}
+
+///
+/// Software Class EFI Runtime Services Subclass Progress Code definitions.
+///
+///@{
+#define EFI_SW_RS_PC_GET_TIME (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_RS_PC_SET_TIME (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_RS_PC_GET_WAKEUP_TIME (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_SW_RS_PC_SET_WAKEUP_TIME (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_SW_RS_PC_CONVERT_POINTER (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_SW_RS_PC_GET_VARIABLE (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+#define EFI_SW_RS_PC_GET_NEXT_VARIABLE_NAME (EFI_SUBCLASS_SPECIFIC | 0x00000007)
+#define EFI_SW_RS_PC_SET_VARIABLE (EFI_SUBCLASS_SPECIFIC | 0x00000008)
+#define EFI_SW_RS_PC_GET_NEXT_HIGH_MONOTONIC_COUNT (EFI_SUBCLASS_SPECIFIC | 0x00000009)
+#define EFI_SW_RS_PC_RESET_SYSTEM (EFI_SUBCLASS_SPECIFIC | 0x0000000A)
+#define EFI_SW_RS_PC_UPDATE_CAPSULE (EFI_SUBCLASS_SPECIFIC | 0x0000000B)
+#define EFI_SW_RS_PC_QUERY_CAPSULE_CAPABILITIES (EFI_SUBCLASS_SPECIFIC | 0x0000000C)
+#define EFI_SW_RS_PC_QUERY_VARIABLE_INFO (EFI_SUBCLASS_SPECIFIC | 0x0000000D)
+///@}
+
+///
+/// Software Class EFI DXE Services Subclass Progress Code definitions
+///
+///@{
+#define EFI_SW_DS_PC_ADD_MEMORY_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_DS_PC_ALLOCATE_MEMORY_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_DS_PC_FREE_MEMORY_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_SW_DS_PC_REMOVE_MEMORY_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_SW_DS_PC_GET_MEMORY_SPACE_DESCRIPTOR (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_SW_DS_PC_SET_MEMORY_SPACE_ATTRIBUTES (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_SW_DS_PC_GET_MEMORY_SPACE_MAP (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+#define EFI_SW_DS_PC_ADD_IO_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000007)
+#define EFI_SW_DS_PC_ALLOCATE_IO_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000008)
+#define EFI_SW_DS_PC_FREE_IO_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000009)
+#define EFI_SW_DS_PC_REMOVE_IO_SPACE (EFI_SUBCLASS_SPECIFIC | 0x0000000A)
+#define EFI_SW_DS_PC_GET_IO_SPACE_DESCRIPTOR (EFI_SUBCLASS_SPECIFIC | 0x0000000B)
+#define EFI_SW_DS_PC_GET_IO_SPACE_MAP (EFI_SUBCLASS_SPECIFIC | 0x0000000C)
+#define EFI_SW_DS_PC_DISPATCH (EFI_SUBCLASS_SPECIFIC | 0x0000000D)
+#define EFI_SW_DS_PC_SCHEDULE (EFI_SUBCLASS_SPECIFIC | 0x0000000E)
+#define EFI_SW_DS_PC_TRUST (EFI_SUBCLASS_SPECIFIC | 0x0000000F)
+#define EFI_SW_DS_PC_PROCESS_FIRMWARE_VOLUME (EFI_SUBCLASS_SPECIFIC | 0x00000010)
+///@}
+
+///
+/// Software Class Error Code definitions.
+/// These are shared by all subclasses.
+///
+///@{
+#define EFI_SW_EC_NON_SPECIFIC 0x00000000
+#define EFI_SW_EC_LOAD_ERROR 0x00000001
+#define EFI_SW_EC_INVALID_PARAMETER 0x00000002
+#define EFI_SW_EC_UNSUPPORTED 0x00000003
+#define EFI_SW_EC_INVALID_BUFFER 0x00000004
+#define EFI_SW_EC_OUT_OF_RESOURCES 0x00000005
+#define EFI_SW_EC_ABORTED 0x00000006
+#define EFI_SW_EC_ILLEGAL_SOFTWARE_STATE 0x00000007
+#define EFI_SW_EC_ILLEGAL_HARDWARE_STATE 0x00000008
+#define EFI_SW_EC_START_ERROR 0x00000009
+#define EFI_SW_EC_BAD_DATE_TIME 0x0000000A
+#define EFI_SW_EC_CFG_INVALID 0x0000000B
+#define EFI_SW_EC_CFG_CLR_REQUEST 0x0000000C
+#define EFI_SW_EC_CFG_DEFAULT 0x0000000D
+#define EFI_SW_EC_PWD_INVALID 0x0000000E
+#define EFI_SW_EC_PWD_CLR_REQUEST 0x0000000F
+#define EFI_SW_EC_PWD_CLEARED 0x00000010
+#define EFI_SW_EC_EVENT_LOG_FULL 0x00000011
+#define EFI_SW_EC_WRITE_PROTECTED 0x00000012
+#define EFI_SW_EC_FV_CORRUPTED 0x00000013
+#define EFI_SW_EC_INCONSISTENT_MEMORY_MAP 0x00000014
+///@}
+
+//
+// Software Class Unspecified Subclass Error Code definitions.
+//
+
+//
+// Software Class SEC Subclass Error Code definitions.
+//
+
+///
+/// Software Class PEI Core Subclass Error Code definitions.
+///
+///@{
+#define EFI_SW_PEI_CORE_EC_DXE_CORRUPT (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_PEI_CORE_EC_DXEIPL_NOT_FOUND (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_PEI_CORE_EC_MEMORY_NOT_INSTALLED (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+///@}
+
+///
+/// Software Class PEI Module Subclass Error Code definitions.
+///
+///@{
+#define EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_PEI_EC_INVALID_CAPSULE_DESCRIPTOR (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_SW_PEI_EC_S3_OS_WAKE_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_SW_PEI_EC_S3_RESUME_FAILED (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+#define EFI_SW_PEI_EC_RECOVERY_FAILED (EFI_SUBCLASS_SPECIFIC | 0x00000007)
+#define EFI_SW_PEI_EC_S3_RESUME_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000008)
+#define EFI_SW_PEI_EC_INVALID_CAPSULE (EFI_SUBCLASS_SPECIFIC | 0x00000009)
+///@}
+
+///
+/// Software Class DXE Foundation Subclass Error Code definitions.
+///
+///@{
+#define EFI_SW_DXE_CORE_EC_NO_ARCH (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+///@}
+
+///
+/// Software Class DXE Boot Service Driver Subclass Error Code definitions.
+///
+///@{
+#define EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_DXE_BS_EC_INVALID_PASSWORD (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_SW_DXE_BS_EC_INVALID_IDE_PASSWORD (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+///@}
+
+//
+// Software Class DXE Runtime Service Driver Subclass Error Code definitions.
+//
+
+//
+// Software Class SMM Driver Subclass Error Code definitions.
+//
+
+//
+// Software Class EFI Application Subclass Error Code definitions.
+//
+
+//
+// Software Class EFI OS Loader Subclass Error Code definitions.
+//
+
+//
+// Software Class EFI RT Subclass Error Code definitions.
+//
+
+//
+// Software Class EFI AL Subclass Error Code definitions.
+//
+
+///
+/// Software Class EBC Exception Subclass Error Code definitions.
+/// These exceptions are derived from the debug protocol definitions in the EFI
+/// specification.
+///
+///@{
+#define EFI_SW_EC_EBC_UNDEFINED 0x00000000
+#define EFI_SW_EC_EBC_DIVIDE_ERROR EXCEPT_EBC_DIVIDE_ERROR
+#define EFI_SW_EC_EBC_DEBUG EXCEPT_EBC_DEBUG
+#define EFI_SW_EC_EBC_BREAKPOINT EXCEPT_EBC_BREAKPOINT
+#define EFI_SW_EC_EBC_OVERFLOW EXCEPT_EBC_OVERFLOW
+#define EFI_SW_EC_EBC_INVALID_OPCODE EXCEPT_EBC_INVALID_OPCODE
+#define EFI_SW_EC_EBC_STACK_FAULT EXCEPT_EBC_STACK_FAULT
+#define EFI_SW_EC_EBC_ALIGNMENT_CHECK EXCEPT_EBC_ALIGNMENT_CHECK
+#define EFI_SW_EC_EBC_INSTRUCTION_ENCODING EXCEPT_EBC_INSTRUCTION_ENCODING
+#define EFI_SW_EC_EBC_BAD_BREAK EXCEPT_EBC_BAD_BREAK
+#define EFI_SW_EC_EBC_STEP EXCEPT_EBC_STEP
+///@}
+
+///
+/// Software Class IA32 Exception Subclass Error Code definitions.
+/// These exceptions are derived from the debug protocol definitions in the EFI
+/// specification.
+///
+///@{
+#define EFI_SW_EC_IA32_DIVIDE_ERROR EXCEPT_IA32_DIVIDE_ERROR
+#define EFI_SW_EC_IA32_DEBUG EXCEPT_IA32_DEBUG
+#define EFI_SW_EC_IA32_NMI EXCEPT_IA32_NMI
+#define EFI_SW_EC_IA32_BREAKPOINT EXCEPT_IA32_BREAKPOINT
+#define EFI_SW_EC_IA32_OVERFLOW EXCEPT_IA32_OVERFLOW
+#define EFI_SW_EC_IA32_BOUND EXCEPT_IA32_BOUND
+#define EFI_SW_EC_IA32_INVALID_OPCODE EXCEPT_IA32_INVALID_OPCODE
+#define EFI_SW_EC_IA32_DOUBLE_FAULT EXCEPT_IA32_DOUBLE_FAULT
+#define EFI_SW_EC_IA32_INVALID_TSS EXCEPT_IA32_INVALID_TSS
+#define EFI_SW_EC_IA32_SEG_NOT_PRESENT EXCEPT_IA32_SEG_NOT_PRESENT
+#define EFI_SW_EC_IA32_STACK_FAULT EXCEPT_IA32_STACK_FAULT
+#define EFI_SW_EC_IA32_GP_FAULT EXCEPT_IA32_GP_FAULT
+#define EFI_SW_EC_IA32_PAGE_FAULT EXCEPT_IA32_PAGE_FAULT
+#define EFI_SW_EC_IA32_FP_ERROR EXCEPT_IA32_FP_ERROR
+#define EFI_SW_EC_IA32_ALIGNMENT_CHECK EXCEPT_IA32_ALIGNMENT_CHECK
+#define EFI_SW_EC_IA32_MACHINE_CHECK EXCEPT_IA32_MACHINE_CHECK
+#define EFI_SW_EC_IA32_SIMD EXCEPT_IA32_SIMD
+///@}
+
+///
+/// Software Class IPF Exception Subclass Error Code definitions.
+/// These exceptions are derived from the debug protocol definitions in the EFI
+/// specification.
+///
+///@{
+#define EFI_SW_EC_IPF_ALT_DTLB EXCEPT_IPF_ALT_DTLB
+#define EFI_SW_EC_IPF_DNESTED_TLB EXCEPT_IPF_DNESTED_TLB
+#define EFI_SW_EC_IPF_BREAKPOINT EXCEPT_IPF_BREAKPOINT
+#define EFI_SW_EC_IPF_EXTERNAL_INTERRUPT EXCEPT_IPF_EXTERNAL_INTERRUPT
+#define EFI_SW_EC_IPF_GEN_EXCEPT EXCEPT_IPF_GEN_EXCEPT
+#define EFI_SW_EC_IPF_NAT_CONSUMPTION EXCEPT_IPF_NAT_CONSUMPTION
+#define EFI_SW_EC_IPF_DEBUG_EXCEPT EXCEPT_IPF_DEBUG_EXCEPT
+#define EFI_SW_EC_IPF_UNALIGNED_ACCESS EXCEPT_IPF_UNALIGNED_ACCESS
+#define EFI_SW_EC_IPF_FP_FAULT EXCEPT_IPF_FP_FAULT
+#define EFI_SW_EC_IPF_FP_TRAP EXCEPT_IPF_FP_TRAP
+#define EFI_SW_EC_IPF_TAKEN_BRANCH EXCEPT_IPF_TAKEN_BRANCH
+#define EFI_SW_EC_IPF_SINGLE_STEP EXCEPT_IPF_SINGLE_STEP
+///@}
+
+///
+/// Software Class PEI Service Subclass Error Code definitions.
+///
+///@{
+#define EFI_SW_PS_EC_RESET_NOT_AVAILABLE (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_PS_EC_MEMORY_INSTALLED_TWICE (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+///@}
+
+//
+// Software Class EFI Boot Service Subclass Error Code definitions.
+//
+
+//
+// Software Class EFI Runtime Service Subclass Error Code definitions.
+//
+
+///
+/// Software Class EFI DXE Service Subclass Error Code definitions.
+///
+///@{
+#define EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+#define EFI_SW_DXE_BS_PC_VERIFYING_PASSWORD (EFI_SUBCLASS_SPECIFIC | 0x00000006)
+///@}
+
+///
+/// Software Class DXE RT Driver Subclass Progress Code definitions.
+///
+///@{
+#define EFI_SW_DXE_RT_PC_S0 (EFI_SUBCLASS_SPECIFIC | 0x00000000)
+#define EFI_SW_DXE_RT_PC_S1 (EFI_SUBCLASS_SPECIFIC | 0x00000001)
+#define EFI_SW_DXE_RT_PC_S2 (EFI_SUBCLASS_SPECIFIC | 0x00000002)
+#define EFI_SW_DXE_RT_PC_S3 (EFI_SUBCLASS_SPECIFIC | 0x00000003)
+#define EFI_SW_DXE_RT_PC_S4 (EFI_SUBCLASS_SPECIFIC | 0x00000004)
+#define EFI_SW_DXE_RT_PC_S5 (EFI_SUBCLASS_SPECIFIC | 0x00000005)
+///@}
+
+///
+/// Software Class X64 Exception Subclass Error Code definitions.
+/// These exceptions are derived from the debug protocol
+/// definitions in the EFI specification.
+///
+///@{
+#define EFI_SW_EC_X64_DIVIDE_ERROR EXCEPT_X64_DIVIDE_ERROR
+#define EFI_SW_EC_X64_DEBUG EXCEPT_X64_DEBUG
+#define EFI_SW_EC_X64_NMI EXCEPT_X64_NMI
+#define EFI_SW_EC_X64_BREAKPOINT EXCEPT_X64_BREAKPOINT
+#define EFI_SW_EC_X64_OVERFLOW EXCEPT_X64_OVERFLOW
+#define EFI_SW_EC_X64_BOUND EXCEPT_X64_BOUND
+#define EFI_SW_EC_X64_INVALID_OPCODE EXCEPT_X64_INVALID_OPCODE
+#define EFI_SW_EC_X64_DOUBLE_FAULT EXCEPT_X64_DOUBLE_FAULT
+#define EFI_SW_EC_X64_INVALID_TSS EXCEPT_X64_INVALID_TSS
+#define EFI_SW_EC_X64_SEG_NOT_PRESENT EXCEPT_X64_SEG_NOT_PRESENT
+#define EFI_SW_EC_X64_STACK_FAULT EXCEPT_X64_STACK_FAULT
+#define EFI_SW_EC_X64_GP_FAULT EXCEPT_X64_GP_FAULT
+#define EFI_SW_EC_X64_PAGE_FAULT EXCEPT_X64_PAGE_FAULT
+#define EFI_SW_EC_X64_FP_ERROR EXCEPT_X64_FP_ERROR
+#define EFI_SW_EC_X64_ALIGNMENT_CHECK EXCEPT_X64_ALIGNMENT_CHECK
+#define EFI_SW_EC_X64_MACHINE_CHECK EXCEPT_X64_MACHINE_CHECK
+#define EFI_SW_EC_X64_SIMD EXCEPT_X64_SIMD
+///@}
+
+///
+/// Software Class ARM Exception Subclass Error Code definitions.
+/// These exceptions are derived from the debug protocol
+/// definitions in the EFI specification.
+///
+///@{
+#define EFI_SW_EC_ARM_RESET EXCEPT_ARM_RESET
+#define EFI_SW_EC_ARM_UNDEFINED_INSTRUCTION EXCEPT_ARM_UNDEFINED_INSTRUCTION
+#define EFI_SW_EC_ARM_SOFTWARE_INTERRUPT EXCEPT_ARM_SOFTWARE_INTERRUPT
+#define EFI_SW_EC_ARM_PREFETCH_ABORT EXCEPT_ARM_PREFETCH_ABORT
+#define EFI_SW_EC_ARM_DATA_ABORT EXCEPT_ARM_DATA_ABORT
+#define EFI_SW_EC_ARM_RESERVED EXCEPT_ARM_RESERVED
+#define EFI_SW_EC_ARM_IRQ EXCEPT_ARM_IRQ
+#define EFI_SW_EC_ARM_FIQ EXCEPT_ARM_FIQ
+///@}
+
+#endif
diff --git a/sys/contrib/edk2/Include/ProcessorBind.h b/sys/contrib/edk2/Include/ProcessorBind.h new file mode 100644 index 000000000000..d67c4aa99b19 --- /dev/null +++ b/sys/contrib/edk2/Include/ProcessorBind.h @@ -0,0 +1,11 @@ +/* + * Copyright 2025 Netflix, Inc + * + * SPDX-License-Idnetifier: BSD-2-Clause + */ +/* These three will be redefined -- well MAC is an option that collides */ +#undef TRUE +#undef FALSE +#undef MAC +#include <sys/efi-edk2.h> + diff --git a/sys/contrib/edk2/Include/Protocol/AbsolutePointer.h b/sys/contrib/edk2/Include/Protocol/AbsolutePointer.h new file mode 100644 index 000000000000..fbbba9ab32c0 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/AbsolutePointer.h @@ -0,0 +1,192 @@ +/** @file + The file provides services that allow information about an + absolute pointer device to be retrieved. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol was introduced in UEFI Specification 2.3. + +**/ + +#ifndef __ABSOLUTE_POINTER_H__ +#define __ABSOLUTE_POINTER_H__ + +#define EFI_ABSOLUTE_POINTER_PROTOCOL_GUID \ + { 0x8D59D32B, 0xC655, 0x4AE9, { 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } } + +typedef struct _EFI_ABSOLUTE_POINTER_PROTOCOL EFI_ABSOLUTE_POINTER_PROTOCOL; + +// ******************************************************* +// EFI_ABSOLUTE_POINTER_MODE +// ******************************************************* + +/** + The following data values in the EFI_ABSOLUTE_POINTER_MODE + interface are read-only and are changed by using the appropriate + interface functions. +**/ +typedef struct { + UINT64 AbsoluteMinX; ///< The Absolute Minimum of the device on the x-axis + UINT64 AbsoluteMinY; ///< The Absolute Minimum of the device on the y axis. + UINT64 AbsoluteMinZ; ///< The Absolute Minimum of the device on the z-axis + UINT64 AbsoluteMaxX; ///< The Absolute Maximum of the device on the x-axis. If 0, and the + ///< AbsoluteMinX is 0, then the pointer device does not support a xaxis + UINT64 AbsoluteMaxY; ///< The Absolute Maximum of the device on the y -axis. If 0, and the + ///< AbsoluteMinX is 0, then the pointer device does not support a yaxis. + UINT64 AbsoluteMaxZ; ///< The Absolute Maximum of the device on the z-axis. If 0 , and the + ///< AbsoluteMinX is 0, then the pointer device does not support a zaxis + UINT32 Attributes; ///< The following bits are set as needed (or'd together) to indicate the + ///< capabilities of the device supported. The remaining bits are undefined + ///< and should be 0 +} EFI_ABSOLUTE_POINTER_MODE; + +/// +/// If set, indicates this device supports an alternate button input. +/// +#define EFI_ABSP_SupportsAltActive 0x00000001 + +/// +/// If set, indicates this device returns pressure data in parameter CurrentZ. +/// +#define EFI_ABSP_SupportsPressureAsZ 0x00000002 + +/** + This function resets the pointer device hardware. As part of + initialization process, the firmware/device will make a quick + but reasonable attempt to verify that the device is + functioning. If the ExtendedVerification flag is TRUE the + firmware may take an extended amount of time to verify the + device is operating on reset. Otherwise the reset operation is + to occur as quickly as possible. The hardware verification + process is not defined by this specification and is left up to + the platform firmware or driver to implement. + + @param This A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL + instance. + + @param ExtendedVerification Indicates that the driver may + perform a more exhaustive + verification operation of the + device during reset. + + @retval EFI_SUCCESS The device was reset. + + @retval EFI_DEVICE_ERROR The device is not functioning + correctly and could not be reset. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ABSOLUTE_POINTER_RESET)( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +/// +/// This bit is set if the touch sensor is active. +/// +#define EFI_ABSP_TouchActive 0x00000001 + +/// +/// This bit is set if the alt sensor, such as pen-side button, is active +/// +#define EFI_ABS_AltActive 0x00000002 + +/** + Definition of EFI_ABSOLUTE_POINTER_STATE. +**/ +typedef struct { + /// + /// The unsigned position of the activation on the x axis. If the AboluteMinX + /// and the AboluteMaxX fields of the EFI_ABSOLUTE_POINTER_MODE structure are + /// both 0, then this pointer device does not support an x-axis, and this field + /// must be ignored. + /// + UINT64 CurrentX; + + /// + /// The unsigned position of the activation on the y axis. If the AboluteMinY + /// and the AboluteMaxY fields of the EFI_ABSOLUTE_POINTER_MODE structure are + /// both 0, then this pointer device does not support an y-axis, and this field + /// must be ignored. + /// + UINT64 CurrentY; + + /// + /// The unsigned position of the activation on the z axis, or the pressure + /// measurement. If the AboluteMinZ and the AboluteMaxZ fields of the + /// EFI_ABSOLUTE_POINTER_MODE structure are both 0, then this pointer device + /// does not support an z-axis, and this field must be ignored. + /// + UINT64 CurrentZ; + + /// + /// Bits are set to 1 in this structure item to indicate that device buttons are + /// active. + /// + UINT32 ActiveButtons; +} EFI_ABSOLUTE_POINTER_STATE; + +/** + The GetState() function retrieves the current state of a pointer + device. This includes information on the active state associated + with the pointer device and the current position of the axes + associated with the pointer device. If the state of the pointer + device has not changed since the last call to GetState(), then + EFI_NOT_READY is returned. If the state of the pointer device + has changed since the last call to GetState(), then the state + information is placed in State, and EFI_SUCCESS is returned. If + a device error occurs while attempting to retrieve the state + information, then EFI_DEVICE_ERROR is returned. + + + @param This A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL + instance. + + @param State A pointer to the state information on the + pointer device. + + @retval EFI_SUCCESS The state of the pointer device was + returned in State. + + @retval EFI_NOT_READY The state of the pointer device has not + changed since the last call to GetState(). + + @retval EFI_DEVICE_ERROR A device error occurred while + attempting to retrieve the pointer + device's current state. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ABSOLUTE_POINTER_GET_STATE)( + IN EFI_ABSOLUTE_POINTER_PROTOCOL *This, + OUT EFI_ABSOLUTE_POINTER_STATE *State + ); + +/// +/// The EFI_ABSOLUTE_POINTER_PROTOCOL provides a set of services +/// for a pointer device that can be used as an input device from an +/// application written to this specification. The services include +/// the ability to: reset the pointer device, retrieve the state of +/// the pointer device, and retrieve the capabilities of the pointer +/// device. The service also provides certain data items describing the device. +/// +struct _EFI_ABSOLUTE_POINTER_PROTOCOL { + EFI_ABSOLUTE_POINTER_RESET Reset; + EFI_ABSOLUTE_POINTER_GET_STATE GetState; + /// + /// Event to use with WaitForEvent() to wait for input from the pointer device. + /// + EFI_EVENT WaitForInput; + /// + /// Pointer to EFI_ABSOLUTE_POINTER_MODE data. + /// + EFI_ABSOLUTE_POINTER_MODE *Mode; +}; + +extern EFI_GUID gEfiAbsolutePointerProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Arp.h b/sys/contrib/edk2/Include/Protocol/Arp.h new file mode 100644 index 000000000000..b250a6f42e92 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Arp.h @@ -0,0 +1,376 @@ +/** @file + EFI ARP Protocol Definition + + The EFI ARP Service Binding Protocol is used to locate EFI + ARP Protocol drivers to create and destroy child of the + driver to communicate with other host using ARP protocol. + The EFI ARP Protocol provides services to map IP network + address to hardware address used by a data link protocol. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol was introduced in UEFI Specification 2.0. + +**/ + +#ifndef __EFI_ARP_PROTOCOL_H__ +#define __EFI_ARP_PROTOCOL_H__ + +#define EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0xf44c00ee, 0x1f2c, 0x4a00, {0xaa, 0x9, 0x1c, 0x9f, 0x3e, 0x8, 0x0, 0xa3 } \ + } + +#define EFI_ARP_PROTOCOL_GUID \ + { \ + 0xf4b427bb, 0xba21, 0x4f16, {0xbc, 0x4e, 0x43, 0xe4, 0x16, 0xab, 0x61, 0x9c } \ + } + +typedef struct _EFI_ARP_PROTOCOL EFI_ARP_PROTOCOL; + +typedef struct { + /// + /// Length in bytes of this entry. + /// + UINT32 Size; + + /// + /// Set to TRUE if this entry is a "deny" entry. + /// Set to FALSE if this entry is a "normal" entry. + /// + BOOLEAN DenyFlag; + + /// + /// Set to TRUE if this entry will not time out. + /// Set to FALSE if this entry will time out. + /// + BOOLEAN StaticFlag; + + /// + /// 16-bit ARP hardware identifier number. + /// + UINT16 HwAddressType; + + /// + /// 16-bit protocol type number. + /// + UINT16 SwAddressType; + + /// + /// The length of the hardware address. + /// + UINT8 HwAddressLength; + + /// + /// The length of the protocol address. + /// + UINT8 SwAddressLength; +} EFI_ARP_FIND_DATA; + +typedef struct { + /// + /// 16-bit protocol type number in host byte order. + /// + UINT16 SwAddressType; + + /// + /// The length in bytes of the station's protocol address to register. + /// + UINT8 SwAddressLength; + + /// + /// The pointer to the first byte of the protocol address to register. For + /// example, if SwAddressType is 0x0800 (IP), then + /// StationAddress points to the first byte of this station's IP + /// address stored in network byte order. + /// + VOID *StationAddress; + + /// + /// The timeout value in 100-ns units that is associated with each + /// new dynamic ARP cache entry. If it is set to zero, the value is + /// implementation-specific. + /// + UINT32 EntryTimeOut; + + /// + /// The number of retries before a MAC address is resolved. If it is + /// set to zero, the value is implementation-specific. + /// + UINT32 RetryCount; + + /// + /// The timeout value in 100-ns units that is used to wait for the ARP + /// reply packet or the timeout value between two retries. Set to zero + /// to use implementation-specific value. + /// + UINT32 RetryTimeOut; +} EFI_ARP_CONFIG_DATA; + +/** + This function is used to assign a station address to the ARP cache for this instance + of the ARP driver. + + Each ARP instance has one station address. The EFI_ARP_PROTOCOL driver will + respond to ARP requests that match this registered station address. A call to + this function with the ConfigData field set to NULL will reset this ARP instance. + + Once a protocol type and station address have been assigned to this ARP instance, + all the following ARP functions will use this information. Attempting to change + the protocol type or station address to a configured ARP instance will result in errors. + + @param This The pointer to the EFI_ARP_PROTOCOL instance. + @param ConfigData The pointer to the EFI_ARP_CONFIG_DATA structure. + + @retval EFI_SUCCESS The new station address was successfully + registered. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + * This is NULL. + * SwAddressLength is zero when ConfigData is not NULL. + * StationAddress is NULL when ConfigData is not NULL. + @retval EFI_ACCESS_DENIED The SwAddressType, SwAddressLength, or + StationAddress is different from the one that is + already registered. + @retval EFI_OUT_OF_RESOURCES Storage for the new StationAddress could not be + allocated. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ARP_CONFIGURE)( + IN EFI_ARP_PROTOCOL *This, + IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL + ); + +/** + This function is used to insert entries into the ARP cache. + + ARP cache entries are typically inserted and updated by network protocol drivers + as network traffic is processed. Most ARP cache entries will time out and be + deleted if the network traffic stops. ARP cache entries that were inserted + by the Add() function may be static (will not time out) or dynamic (will time out). + Default ARP cache timeout values are not covered in most network protocol + specifications (although RFC 1122 comes pretty close) and will only be + discussed in general terms in this specification. The timeout values that are + used in the EFI Sample Implementation should be used only as a guideline. + Final product implementations of the EFI network stack should be tuned for + their expected network environments. + + @param This Pointer to the EFI_ARP_PROTOCOL instance. + @param DenyFlag Set to TRUE if this entry is a deny entry. Set to + FALSE if this entry is a normal entry. + @param TargetSwAddress Pointer to a protocol address to add (or deny). + May be set to NULL if DenyFlag is TRUE. + @param TargetHwAddress Pointer to a hardware address to add (or deny). + May be set to NULL if DenyFlag is TRUE. + @param TimeoutValue Time in 100-ns units that this entry will remain + in the ARP cache. A value of zero means that the + entry is permanent. A nonzero value will override + the one given by Configure() if the entry to be + added is a dynamic entry. + @param Overwrite If TRUE, the matching cache entry will be + overwritten with the supplied parameters. If + FALSE, EFI_ACCESS_DENIED is returned if the + corresponding cache entry already exists. + + @retval EFI_SUCCESS The entry has been added or updated. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + * This is NULL. + * DenyFlag is FALSE and TargetHwAddress is NULL. + * DenyFlag is FALSE and TargetSwAddress is NULL. + * TargetHwAddress is NULL and TargetSwAddress is NULL. + * Neither TargetSwAddress nor TargetHwAddress are NULL when DenyFlag is + TRUE. + @retval EFI_OUT_OF_RESOURCES The new ARP cache entry could not be allocated. + @retval EFI_ACCESS_DENIED The ARP cache entry already exists and Overwrite + is not true. + @retval EFI_NOT_STARTED The ARP driver instance has not been configured. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ARP_ADD)( + IN EFI_ARP_PROTOCOL *This, + IN BOOLEAN DenyFlag, + IN VOID *TargetSwAddress OPTIONAL, + IN VOID *TargetHwAddress OPTIONAL, + IN UINT32 TimeoutValue, + IN BOOLEAN Overwrite + ); + +/** + This function searches the ARP cache for matching entries and allocates a buffer into + which those entries are copied. + + The first part of the allocated buffer is EFI_ARP_FIND_DATA, following which + are protocol address pairs and hardware address pairs. + When finding a specific protocol address (BySwAddress is TRUE and AddressBuffer + is not NULL), the ARP cache timeout for the found entry is reset if Refresh is + set to TRUE. If the found ARP cache entry is a permanent entry, it is not + affected by Refresh. + + @param This The pointer to the EFI_ARP_PROTOCOL instance. + @param BySwAddress Set to TRUE to look for matching software protocol + addresses. Set to FALSE to look for matching + hardware protocol addresses. + @param AddressBuffer The pointer to the address buffer. Set to NULL + to match all addresses. + @param EntryLength The size of an entry in the entries buffer. + @param EntryCount The number of ARP cache entries that are found by + the specified criteria. + @param Entries The pointer to the buffer that will receive the ARP + cache entries. + @param Refresh Set to TRUE to refresh the timeout value of the + matching ARP cache entry. + + @retval EFI_SUCCESS The requested ARP cache entries were copied into + the buffer. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. Both EntryCount and EntryLength are + NULL, when Refresh is FALSE. + @retval EFI_NOT_FOUND No matching entries were found. + @retval EFI_NOT_STARTED The ARP driver instance has not been configured. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ARP_FIND)( + IN EFI_ARP_PROTOCOL *This, + IN BOOLEAN BySwAddress, + IN VOID *AddressBuffer OPTIONAL, + OUT UINT32 *EntryLength OPTIONAL, + OUT UINT32 *EntryCount OPTIONAL, + OUT EFI_ARP_FIND_DATA **Entries OPTIONAL, + IN BOOLEAN Refresh + ); + +/** + This function removes specified ARP cache entries. + + @param This The pointer to the EFI_ARP_PROTOCOL instance. + @param BySwAddress Set to TRUE to delete matching protocol addresses. + Set to FALSE to delete matching hardware + addresses. + @param AddressBuffer The pointer to the address buffer that is used as a + key to look for the cache entry. Set to NULL to + delete all entries. + + @retval EFI_SUCCESS The entry was removed from the ARP cache. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_FOUND The specified deletion key was not found. + @retval EFI_NOT_STARTED The ARP driver instance has not been configured. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ARP_DELETE)( + IN EFI_ARP_PROTOCOL *This, + IN BOOLEAN BySwAddress, + IN VOID *AddressBuffer OPTIONAL + ); + +/** + This function delete all dynamic entries from the ARP cache that match the specified + software protocol type. + + @param This The pointer to the EFI_ARP_PROTOCOL instance. + + @retval EFI_SUCCESS The cache has been flushed. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_FOUND There are no matching dynamic cache entries. + @retval EFI_NOT_STARTED The ARP driver instance has not been configured. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ARP_FLUSH)( + IN EFI_ARP_PROTOCOL *This + ); + +/** + This function tries to resolve the TargetSwAddress and optionally returns a + TargetHwAddress if it already exists in the ARP cache. + + @param This The pointer to the EFI_ARP_PROTOCOL instance. + @param TargetSwAddress The pointer to the protocol address to resolve. + @param ResolvedEvent The pointer to the event that will be signaled when + the address is resolved or some error occurs. + @param TargetHwAddress The pointer to the buffer for the resolved hardware + address in network byte order. + + @retval EFI_SUCCESS The data is copied from the ARP cache into the + TargetHwAddress buffer. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. TargetHwAddress is NULL. + @retval EFI_ACCESS_DENIED The requested address is not present in the normal + ARP cache but is present in the deny address list. + Outgoing traffic to that address is forbidden. + @retval EFI_NOT_STARTED The ARP driver instance has not been configured. + @retval EFI_NOT_READY The request has been started and is not finished. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ARP_REQUEST)( + IN EFI_ARP_PROTOCOL *This, + IN VOID *TargetSwAddress OPTIONAL, + IN EFI_EVENT ResolvedEvent OPTIONAL, + OUT VOID *TargetHwAddress + ); + +/** + This function aborts the previous ARP request (identified by This, TargetSwAddress + and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request(). + + If the request is in the internal ARP request queue, the request is aborted + immediately and its ResolvedEvent is signaled. Only an asynchronous address + request needs to be canceled. If TargeSwAddress and ResolveEvent are both + NULL, all the pending asynchronous requests that have been issued by This + instance will be cancelled and their corresponding events will be signaled. + + @param This The pointer to the EFI_ARP_PROTOCOL instance. + @param TargetSwAddress The pointer to the protocol address in previous + request session. + @param ResolvedEvent Pointer to the event that is used as the + notification event in previous request session. + + @retval EFI_SUCCESS The pending request session(s) is/are aborted and + corresponding event(s) is/are signaled. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. TargetSwAddress is not NULL and + ResolvedEvent is NULL. TargetSwAddress is NULL and + ResolvedEvent is not NULL. + @retval EFI_NOT_STARTED The ARP driver instance has not been configured. + @retval EFI_NOT_FOUND The request is not issued by + EFI_ARP_PROTOCOL.Request(). + + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ARP_CANCEL)( + IN EFI_ARP_PROTOCOL *This, + IN VOID *TargetSwAddress OPTIONAL, + IN EFI_EVENT ResolvedEvent OPTIONAL + ); + +/// +/// ARP is used to resolve local network protocol addresses into +/// network hardware addresses. +/// +struct _EFI_ARP_PROTOCOL { + EFI_ARP_CONFIGURE Configure; + EFI_ARP_ADD Add; + EFI_ARP_FIND Find; + EFI_ARP_DELETE Delete; + EFI_ARP_FLUSH Flush; + EFI_ARP_REQUEST Request; + EFI_ARP_CANCEL Cancel; +}; + +extern EFI_GUID gEfiArpServiceBindingProtocolGuid; +extern EFI_GUID gEfiArpProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Bds.h b/sys/contrib/edk2/Include/Protocol/Bds.h new file mode 100644 index 000000000000..d0b973e9b819 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Bds.h @@ -0,0 +1,66 @@ +/** @file + Boot Device Selection Architectural Protocol as defined in PI spec Volume 2 DXE + + When the DXE core is done it calls the BDS via this protocol. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_BDS_H__ +#define __ARCH_PROTOCOL_BDS_H__ + +/// +/// Global ID for the BDS Architectural Protocol +/// +#define EFI_BDS_ARCH_PROTOCOL_GUID \ + { 0x665E3FF6, 0x46CC, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } } + +/// +/// Declare forward reference for the BDS Architectural Protocol +/// +typedef struct _EFI_BDS_ARCH_PROTOCOL EFI_BDS_ARCH_PROTOCOL; + +/** + This function uses policy data from the platform to determine what operating + system or system utility should be loaded and invoked. This function call + also optionally make the use of user input to determine the operating system + or system utility to be loaded and invoked. When the DXE Core has dispatched + all the drivers on the dispatch queue, this function is called. This + function will attempt to connect the boot devices required to load and invoke + the selected operating system or system utility. During this process, + additional firmware volumes may be discovered that may contain addition DXE + drivers that can be dispatched by the DXE Core. If a boot device cannot be + fully connected, this function calls the DXE Service Dispatch() to allow the + DXE drivers from any newly discovered firmware volumes to be dispatched. + Then the boot device connection can be attempted again. If the same boot + device connection operation fails twice in a row, then that boot device has + failed, and should be skipped. This function should never return. + + @param This The EFI_BDS_ARCH_PROTOCOL instance. + + @return None. + +**/ +typedef +VOID +(EFIAPI *EFI_BDS_ENTRY)( + IN EFI_BDS_ARCH_PROTOCOL *This + ); + +/// +/// The EFI_BDS_ARCH_PROTOCOL transfers control from DXE to an operating +/// system or a system utility. If there are not enough drivers initialized +/// when this protocol is used to access the required boot device(s), then +/// this protocol should add drivers to the dispatch queue and return control +/// back to the dispatcher. Once the required boot devices are available, then +/// the boot device can be used to load and invoke an OS or a system utility. +/// +struct _EFI_BDS_ARCH_PROTOCOL { + EFI_BDS_ENTRY Entry; +}; + +extern EFI_GUID gEfiBdsArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/BlockIo.h b/sys/contrib/edk2/Include/Protocol/BlockIo.h new file mode 100644 index 000000000000..d8fe6c2ff054 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/BlockIo.h @@ -0,0 +1,234 @@ +/** @file + Block IO protocol as defined in the UEFI 2.0 specification. + + The Block IO protocol is used to abstract block devices like hard drives, + DVD-ROMs and floppy drives. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __BLOCK_IO_H__ +#define __BLOCK_IO_H__ + +#define EFI_BLOCK_IO_PROTOCOL_GUID \ + { \ + 0x964e5b21, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +typedef struct _EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL; + +/// +/// Protocol GUID name defined in EFI1.1. +/// +#define BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL_GUID + +/// +/// Protocol defined in EFI1.1. +/// +typedef EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO; + +/** + Reset the Block Device. + + @param This Indicates a pointer to the calling context. + @param ExtendedVerification Driver may perform diagnostics on reset. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The device is not functioning properly and could + not be reset. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_RESET)( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +/** + Read BufferSize bytes from Lba into Buffer. + + @param This Indicates a pointer to the calling context. + @param MediaId Id of the media, changes every time the media is replaced. + @param Lba The starting Logical Block Address to read from + @param BufferSize Size of Buffer, must be a multiple of device block size. + @param Buffer A pointer to the destination buffer for the data. The caller is + responsible for either having implicit or explicit ownership of the buffer. + + @retval EFI_SUCCESS The data was read correctly from the device. + @retval EFI_DEVICE_ERROR The device reported an error while performing the read. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. + @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. + @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, + or the buffer is not on proper alignment. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_READ)( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +/** + Write BufferSize bytes from Lba into Buffer. + + @param This Indicates a pointer to the calling context. + @param MediaId The media ID that the write request is for. + @param Lba The starting logical block address to be written. The caller is + responsible for writing to only legitimate locations. + @param BufferSize Size of Buffer, must be a multiple of device block size. + @param Buffer A pointer to the source buffer for the data. + + @retval EFI_SUCCESS The data was written correctly to the device. + @retval EFI_WRITE_PROTECTED The device can not be written to. + @retval EFI_DEVICE_ERROR The device reported an error while performing the write. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. + @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, + or the buffer is not on proper alignment. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_WRITE)( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +/** + Flush the Block Device. + + @param This Indicates a pointer to the calling context. + + @retval EFI_SUCCESS All outstanding data was written to the device + @retval EFI_DEVICE_ERROR The device reported an error while writting back the data + @retval EFI_NO_MEDIA There is no media in the device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_FLUSH)( + IN EFI_BLOCK_IO_PROTOCOL *This + ); + +/** + Block IO read only mode data and updated only via members of BlockIO +**/ +typedef struct { + /// + /// The curent media Id. If the media changes, this value is changed. + /// + UINT32 MediaId; + + /// + /// TRUE if the media is removable; otherwise, FALSE. + /// + BOOLEAN RemovableMedia; + + /// + /// TRUE if there is a media currently present in the device; + /// othersise, FALSE. THis field shows the media present status + /// as of the most recent ReadBlocks() or WriteBlocks() call. + /// + BOOLEAN MediaPresent; + + /// + /// TRUE if LBA 0 is the first block of a partition; otherwise + /// FALSE. For media with only one partition this would be TRUE. + /// + BOOLEAN LogicalPartition; + + /// + /// TRUE if the media is marked read-only otherwise, FALSE. + /// This field shows the read-only status as of the most recent WriteBlocks () call. + /// + BOOLEAN ReadOnly; + + /// + /// TRUE if the WriteBlock () function caches write data. + /// + BOOLEAN WriteCaching; + + /// + /// The intrinsic block size of the device. If the media changes, then + /// this field is updated. + /// + UINT32 BlockSize; + + /// + /// Supplies the alignment requirement for any buffer to read or write block(s). + /// + UINT32 IoAlign; + + /// + /// The last logical block address on the device. + /// If the media changes, then this field is updated. + /// + EFI_LBA LastBlock; + + /// + /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to + /// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the first LBA is aligned to + /// a physical block boundary. + /// + EFI_LBA LowestAlignedLba; + + /// + /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to + /// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the number of logical blocks + /// per physical block. + /// + UINT32 LogicalBlocksPerPhysicalBlock; + + /// + /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to + /// EFI_BLOCK_IO_PROTOCOL_REVISION3. Returns the optimal transfer length + /// granularity as a number of logical blocks. + /// + UINT32 OptimalTransferLengthGranularity; +} EFI_BLOCK_IO_MEDIA; + +#define EFI_BLOCK_IO_PROTOCOL_REVISION 0x00010000 +#define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001 +#define EFI_BLOCK_IO_PROTOCOL_REVISION3 0x0002001F + +/// +/// Revision defined in EFI1.1. +/// +#define EFI_BLOCK_IO_INTERFACE_REVISION EFI_BLOCK_IO_PROTOCOL_REVISION + +/// +/// This protocol provides control over block devices. +/// +struct _EFI_BLOCK_IO_PROTOCOL { + /// + /// The revision to which the block IO interface adheres. All future + /// revisions must be backwards compatible. If a future version is not + /// back wards compatible, it is not the same GUID. + /// + UINT64 Revision; + /// + /// Pointer to the EFI_BLOCK_IO_MEDIA data for this device. + /// + EFI_BLOCK_IO_MEDIA *Media; + + EFI_BLOCK_RESET Reset; + EFI_BLOCK_READ ReadBlocks; + EFI_BLOCK_WRITE WriteBlocks; + EFI_BLOCK_FLUSH FlushBlocks; +}; + +extern EFI_GUID gEfiBlockIoProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Capsule.h b/sys/contrib/edk2/Include/Protocol/Capsule.h new file mode 100644 index 000000000000..bc1c85ea3974 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Capsule.h @@ -0,0 +1,29 @@ +/** @file + Capsule Architectural Protocol as defined in PI1.0a Specification VOLUME 2 DXE + + The DXE Driver that produces this protocol must be a runtime driver. + The driver is responsible for initializing the CapsuleUpdate() and + QueryCapsuleCapabilities() fields of the UEFI Runtime Services Table. + After the two fields of the UEFI Runtime Services Table have been initialized, + the driver must install the EFI_CAPSULE_ARCH_PROTOCOL_GUID on a new handle + with a NULL interface pointer. The installation of this protocol informs + the DXE Foundation that the Capsule related services are now available and + that the DXE Foundation must update the 32-bit CRC of the UEFI Runtime Services Table. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_CAPSULE_ARCH_H__ +#define __ARCH_PROTOCOL_CAPSULE_ARCH_H__ + +// +// Global ID for the Capsule Architectural Protocol +// +#define EFI_CAPSULE_ARCH_PROTOCOL_GUID \ + { 0x5053697e, 0x2cbc, 0x4819, {0x90, 0xd9, 0x05, 0x80, 0xde, 0xee, 0x57, 0x54 }} + +extern EFI_GUID gEfiCapsuleArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/ComponentName.h b/sys/contrib/edk2/Include/Protocol/ComponentName.h new file mode 100644 index 000000000000..89d203c201e7 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/ComponentName.h @@ -0,0 +1,121 @@ +/** @file + EFI Component Name Protocol as defined in the EFI 1.1 specification. + This protocol is used to retrieve user readable names of EFI Drivers + and controllers managed by EFI Drivers. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_COMPONENT_NAME_H__ +#define __EFI_COMPONENT_NAME_H__ + +/// +/// The global ID for the Component Name Protocol. +/// +#define EFI_COMPONENT_NAME_PROTOCOL_GUID \ + { \ + 0x107a772c, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +typedef struct _EFI_COMPONENT_NAME_PROTOCOL EFI_COMPONENT_NAME_PROTOCOL; + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_COMPONENT_NAME_GET_DRIVER_NAME)( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_COMPONENT_NAME_GET_CONTROLLER_NAME)( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +/// +/// This protocol is used to retrieve user readable names of drivers +/// and controllers managed by UEFI Drivers. +/// +struct _EFI_COMPONENT_NAME_PROTOCOL { + EFI_COMPONENT_NAME_GET_DRIVER_NAME GetDriverName; + EFI_COMPONENT_NAME_GET_CONTROLLER_NAME GetControllerName; + /// + /// A Null-terminated ASCII string that contains one or more + /// ISO 639-2 language codes. This is the list of language codes + /// that this protocol supports. + /// + CHAR8 *SupportedLanguages; +}; + +extern EFI_GUID gEfiComponentNameProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Cpu.h b/sys/contrib/edk2/Include/Protocol/Cpu.h new file mode 100644 index 000000000000..a618bb9723a5 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Cpu.h @@ -0,0 +1,286 @@ +/** @file + CPU Architectural Protocol as defined in PI spec Volume 2 DXE + + This code abstracts the DXE core from processor implementation details. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_CPU_H__ +#define __ARCH_PROTOCOL_CPU_H__ + +#include <Protocol/DebugSupport.h> + +#define EFI_CPU_ARCH_PROTOCOL_GUID \ + { 0x26baccb1, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +typedef struct _EFI_CPU_ARCH_PROTOCOL EFI_CPU_ARCH_PROTOCOL; + +/// +/// The type of flush operation +/// +typedef enum { + EfiCpuFlushTypeWriteBackInvalidate, + EfiCpuFlushTypeWriteBack, + EfiCpuFlushTypeInvalidate, + EfiCpuMaxFlushType +} EFI_CPU_FLUSH_TYPE; + +/// +/// The type of processor INIT. +/// +typedef enum { + EfiCpuInit, + EfiCpuMaxInitType +} EFI_CPU_INIT_TYPE; + +/** + EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs. + + @param InterruptType Defines the type of interrupt or exception that + occurred on the processor.This parameter is processor architecture specific. + @param SystemContext A pointer to the processor context when + the interrupt occurred on the processor. + + @return None + +**/ +typedef +VOID +(EFIAPI *EFI_CPU_INTERRUPT_HANDLER)( + IN CONST EFI_EXCEPTION_TYPE InterruptType, + IN CONST EFI_SYSTEM_CONTEXT SystemContext + ); + +/** + This function flushes the range of addresses from Start to Start+Length + from the processor's data cache. If Start is not aligned to a cache line + boundary, then the bytes before Start to the preceding cache line boundary + are also flushed. If Start+Length is not aligned to a cache line boundary, + then the bytes past Start+Length to the end of the next cache line boundary + are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be + supported. If the data cache is fully coherent with all DMA operations, then + this function can just return EFI_SUCCESS. If the processor does not support + flushing a range of the data cache, then the entire data cache can be flushed. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + @param Start The beginning physical address to flush from the processor's data + cache. + @param Length The number of bytes to flush from the processor's data cache. This + function may flush more bytes than Length specifies depending upon + the granularity of the flush operation that the processor supports. + @param FlushType Specifies the type of flush operation to perform. + + @retval EFI_SUCCESS The address range from Start to Start+Length was flushed from + the processor's data cache. + @retval EFI_UNSUPPORTED The processor does not support the cache flush type specified + by FlushType. + @retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed + from the processor's data cache. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_CPU_FLUSH_DATA_CACHE)( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS Start, + IN UINT64 Length, + IN EFI_CPU_FLUSH_TYPE FlushType + ); + +/** + This function enables interrupt processing by the processor. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + + @retval EFI_SUCCESS Interrupts are enabled on the processor. + @retval EFI_DEVICE_ERROR Interrupts could not be enabled on the processor. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_CPU_ENABLE_INTERRUPT)( + IN EFI_CPU_ARCH_PROTOCOL *This + ); + +/** + This function disables interrupt processing by the processor. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + + @retval EFI_SUCCESS Interrupts are disabled on the processor. + @retval EFI_DEVICE_ERROR Interrupts could not be disabled on the processor. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_CPU_DISABLE_INTERRUPT)( + IN EFI_CPU_ARCH_PROTOCOL *This + ); + +/** + This function retrieves the processor's current interrupt state a returns it in + State. If interrupts are currently enabled, then TRUE is returned. If interrupts + are currently disabled, then FALSE is returned. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + @param State A pointer to the processor's current interrupt state. Set to TRUE if + interrupts are enabled and FALSE if interrupts are disabled. + + @retval EFI_SUCCESS The processor's current interrupt state was returned in State. + @retval EFI_INVALID_PARAMETER State is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_CPU_GET_INTERRUPT_STATE)( + IN EFI_CPU_ARCH_PROTOCOL *This, + OUT BOOLEAN *State + ); + +/** + This function generates an INIT on the processor. If this function succeeds, then the + processor will be reset, and control will not be returned to the caller. If InitType is + not supported by this processor, or the processor cannot programmatically generate an + INIT without help from external hardware, then EFI_UNSUPPORTED is returned. If an error + occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + @param InitType The type of processor INIT to perform. + + @retval EFI_SUCCESS The processor INIT was performed. This return code should never be seen. + @retval EFI_UNSUPPORTED The processor INIT operation specified by InitType is not supported + by this processor. + @retval EFI_DEVICE_ERROR The processor INIT failed. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_CPU_INIT)( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_CPU_INIT_TYPE InitType + ); + +/** + This function registers and enables the handler specified by InterruptHandler for a processor + interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the + handler for the processor interrupt or exception type specified by InterruptType is uninstalled. + The installed handler is called once for each processor interrupt or exception. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts + are enabled and FALSE if interrupts are disabled. + @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called + when a processor interrupt occurs. If this parameter is NULL, then the handler + will be uninstalled. + + @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. + @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was + previously installed. + @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not + previously installed. + @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_CPU_REGISTER_INTERRUPT_HANDLER)( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ); + +/** + This function reads the processor timer specified by TimerIndex and returns it in TimerValue. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + @param TimerIndex Specifies which processor timer is to be returned in TimerValue. This parameter + must be between 0 and NumberOfTimers-1. + @param TimerValue Pointer to the returned timer value. + @param TimerPeriod A pointer to the amount of time that passes in femtoseconds for each increment + of TimerValue. If TimerValue does not increment at a predictable rate, then 0 is + returned. This parameter is optional and may be NULL. + + @retval EFI_SUCCESS The processor timer value specified by TimerIndex was returned in TimerValue. + @retval EFI_DEVICE_ERROR An error occurred attempting to read one of the processor's timers. + @retval EFI_INVALID_PARAMETER TimerValue is NULL or TimerIndex is not valid. + @retval EFI_UNSUPPORTED The processor does not have any readable timers. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_CPU_GET_TIMER_VALUE)( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN UINT32 TimerIndex, + OUT UINT64 *TimerValue, + OUT UINT64 *TimerPeriod OPTIONAL + ); + +/** + This function modifies the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param This The EFI_CPU_ARCH_PROTOCOL instance. + @param BaseAddress The physical address that is the start address of a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to set for the memory region. + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_CPU_SET_MEMORY_ATTRIBUTES)( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +/// +/// The EFI_CPU_ARCH_PROTOCOL is used to abstract processor-specific functions from the DXE +/// Foundation. This includes flushing caches, enabling and disabling interrupts, hooking interrupt +/// vectors and exception vectors, reading internal processor timers, resetting the processor, and +/// determining the processor frequency. +/// +struct _EFI_CPU_ARCH_PROTOCOL { + EFI_CPU_FLUSH_DATA_CACHE FlushDataCache; + EFI_CPU_ENABLE_INTERRUPT EnableInterrupt; + EFI_CPU_DISABLE_INTERRUPT DisableInterrupt; + EFI_CPU_GET_INTERRUPT_STATE GetInterruptState; + EFI_CPU_INIT Init; + EFI_CPU_REGISTER_INTERRUPT_HANDLER RegisterInterruptHandler; + EFI_CPU_GET_TIMER_VALUE GetTimerValue; + EFI_CPU_SET_MEMORY_ATTRIBUTES SetMemoryAttributes; + /// + /// The number of timers that are available in a processor. The value in this + /// field is a constant that must not be modified after the CPU Architectural + /// Protocol is installed. All consumers must treat this as a read-only field. + /// + UINT32 NumberOfTimers; + /// + /// The size, in bytes, of the alignment required for DMA buffer allocations. + /// This is typically the size of the largest data cache line in the platform. + /// The value in this field is a constant that must not be modified after the + /// CPU Architectural Protocol is installed. All consumers must treat this as + /// a read-only field. + /// + UINT32 DmaBufferAlignment; +}; + +extern EFI_GUID gEfiCpuArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/CpuIo2.h b/sys/contrib/edk2/Include/Protocol/CpuIo2.h new file mode 100644 index 000000000000..fc8a3511d11c --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/CpuIo2.h @@ -0,0 +1,136 @@ +/** @file + This files describes the CPU I/O 2 Protocol. + + This protocol provides an I/O abstraction for a system processor. This protocol + is used by a PCI root bridge I/O driver to perform memory-mapped I/O and I/O transactions. + The I/O or memory primitives can be used by the consumer of the protocol to materialize + bus-specific configuration cycles, such as the transitional configuration address and data + ports for PCI. Only drivers that require direct access to the entire system should use this + protocol. + + Note: This is a boot-services only protocol and it may not be used by runtime drivers after + ExitBootServices(). It is different from the Framework CPU I/O Protocol, which is a runtime + protocol and can be used by runtime drivers after ExitBootServices(). + + Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is defined in UEFI Platform Initialization Specification 1.2 + Volume 5: Standards + +**/ + +#ifndef __CPU_IO2_H__ +#define __CPU_IO2_H__ + +#define EFI_CPU_IO2_PROTOCOL_GUID \ + { \ + 0xad61f191, 0xae5f, 0x4c0e, {0xb9, 0xfa, 0xe8, 0x69, 0xd2, 0x88, 0xc6, 0x4f} \ + } + +typedef struct _EFI_CPU_IO2_PROTOCOL EFI_CPU_IO2_PROTOCOL; + +/// +/// Enumeration that defines the width of the I/O operation. +/// +typedef enum { + EfiCpuIoWidthUint8, + EfiCpuIoWidthUint16, + EfiCpuIoWidthUint32, + EfiCpuIoWidthUint64, + EfiCpuIoWidthFifoUint8, + EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, + EfiCpuIoWidthFifoUint64, + EfiCpuIoWidthFillUint8, + EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, + EfiCpuIoWidthFillUint64, + EfiCpuIoWidthMaximum +} EFI_CPU_IO_PROTOCOL_WIDTH; + +/** + Enables a driver to access registers in the PI CPU I/O space. + + The Io.Read() and Io.Write() functions enable a driver to access PCI controller + registers in the PI CPU I/O space. + + The I/O operations are carried out exactly as requested. The caller is responsible + for satisfying any alignment and I/O width restrictions that a PI System on a + platform might require. For example on some platforms, width requests of + EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will + be handled by the driver. + + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, EfiCpuIoWidthUint32, + or EfiCpuIoWidthUint64, then both Address and Buffer are incremented for + each of the Count operations that is performed. + + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only Buffer is + incremented for each of the Count operations that is performed. The read or + write operation is performed Count times on the same Address. + + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only Address is + incremented for each of the Count operations that is performed. The read or + write operation is performed Count times from the first element of Buffer. + + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. + @param[in] Width Signifies the width of the I/O or Memory operation. + @param[in] Address The base address of the I/O operation. + @param[in] Count The number of I/O operations to perform. The number + of bytes moved is Width size * Count, starting at Address. + @param[in, out] Buffer For read operations, the destination buffer to store the results. + For write operations, the source buffer from which to write data. + + @retval EFI_SUCCESS The data was read from or written to the PI system. + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. + @retval EFI_UNSUPPORTED The address range specified by Address, Width, + and Count is not valid for this PI system. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_CPU_IO_PROTOCOL_IO_MEM)( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +/// +/// Service for read and write accesses. +/// +typedef struct { + /// + /// This service provides the various modalities of memory and I/O read. + /// + EFI_CPU_IO_PROTOCOL_IO_MEM Read; + /// + /// This service provides the various modalities of memory and I/O write. + /// + EFI_CPU_IO_PROTOCOL_IO_MEM Write; +} EFI_CPU_IO_PROTOCOL_ACCESS; + +/// +/// Provides the basic memory and I/O interfaces that are used to abstract +/// accesses to devices in a system. +/// +struct _EFI_CPU_IO2_PROTOCOL { + /// + /// Enables a driver to access memory-mapped registers in the EFI system memory space. + /// + EFI_CPU_IO_PROTOCOL_ACCESS Mem; + /// + /// Enables a driver to access registers in the EFI CPU I/O space. + /// + EFI_CPU_IO_PROTOCOL_ACCESS Io; +}; + +extern EFI_GUID gEfiCpuIo2ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/DebugSupport.h b/sys/contrib/edk2/Include/Protocol/DebugSupport.h new file mode 100644 index 000000000000..65f737140e7d --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/DebugSupport.h @@ -0,0 +1,966 @@ +/** @file + DebugSupport protocol and supporting definitions as defined in the UEFI2.4 + specification. + + The DebugSupport protocol is used by source level debuggers to abstract the + processor and handle context save and restore operations. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR> +Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __DEBUG_SUPPORT_H__ +#define __DEBUG_SUPPORT_H__ + +#include <IndustryStandard/PeImage.h> + +typedef struct _EFI_DEBUG_SUPPORT_PROTOCOL EFI_DEBUG_SUPPORT_PROTOCOL; + +/// +/// Debug Support protocol {2755590C-6F3C-42FA-9EA4-A3BA543CDA25}. +/// +#define EFI_DEBUG_SUPPORT_PROTOCOL_GUID \ + { \ + 0x2755590C, 0x6F3C, 0x42FA, {0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \ + } + +/// +/// Processor exception to be hooked. +/// All exception types for IA32, X64, Itanium and EBC processors are defined. +/// +typedef INTN EFI_EXCEPTION_TYPE; + +/// +/// IA-32 processor exception types. +/// +#define EXCEPT_IA32_DIVIDE_ERROR 0 +#define EXCEPT_IA32_DEBUG 1 +#define EXCEPT_IA32_NMI 2 +#define EXCEPT_IA32_BREAKPOINT 3 +#define EXCEPT_IA32_OVERFLOW 4 +#define EXCEPT_IA32_BOUND 5 +#define EXCEPT_IA32_INVALID_OPCODE 6 +#define EXCEPT_IA32_DOUBLE_FAULT 8 +#define EXCEPT_IA32_INVALID_TSS 10 +#define EXCEPT_IA32_SEG_NOT_PRESENT 11 +#define EXCEPT_IA32_STACK_FAULT 12 +#define EXCEPT_IA32_GP_FAULT 13 +#define EXCEPT_IA32_PAGE_FAULT 14 +#define EXCEPT_IA32_FP_ERROR 16 +#define EXCEPT_IA32_ALIGNMENT_CHECK 17 +#define EXCEPT_IA32_MACHINE_CHECK 18 +#define EXCEPT_IA32_SIMD 19 + +/// +/// FXSAVE_STATE. +/// FP / MMX / XMM registers (see fxrstor instruction definition). +/// +typedef struct { + UINT16 Fcw; + UINT16 Fsw; + UINT16 Ftw; + UINT16 Opcode; + UINT32 Eip; + UINT16 Cs; + UINT16 Reserved1; + UINT32 DataOffset; + UINT16 Ds; + UINT8 Reserved2[10]; + UINT8 St0Mm0[10], Reserved3[6]; + UINT8 St1Mm1[10], Reserved4[6]; + UINT8 St2Mm2[10], Reserved5[6]; + UINT8 St3Mm3[10], Reserved6[6]; + UINT8 St4Mm4[10], Reserved7[6]; + UINT8 St5Mm5[10], Reserved8[6]; + UINT8 St6Mm6[10], Reserved9[6]; + UINT8 St7Mm7[10], Reserved10[6]; + UINT8 Xmm0[16]; + UINT8 Xmm1[16]; + UINT8 Xmm2[16]; + UINT8 Xmm3[16]; + UINT8 Xmm4[16]; + UINT8 Xmm5[16]; + UINT8 Xmm6[16]; + UINT8 Xmm7[16]; + UINT8 Reserved11[14 * 16]; +} EFI_FX_SAVE_STATE_IA32; + +/// +/// IA-32 processor context definition. +/// +typedef struct { + UINT32 ExceptionData; + EFI_FX_SAVE_STATE_IA32 FxSaveState; + UINT32 Dr0; + UINT32 Dr1; + UINT32 Dr2; + UINT32 Dr3; + UINT32 Dr6; + UINT32 Dr7; + UINT32 Cr0; + UINT32 Cr1; /* Reserved */ + UINT32 Cr2; + UINT32 Cr3; + UINT32 Cr4; + UINT32 Eflags; + UINT32 Ldtr; + UINT32 Tr; + UINT32 Gdtr[2]; + UINT32 Idtr[2]; + UINT32 Eip; + UINT32 Gs; + UINT32 Fs; + UINT32 Es; + UINT32 Ds; + UINT32 Cs; + UINT32 Ss; + UINT32 Edi; + UINT32 Esi; + UINT32 Ebp; + UINT32 Esp; + UINT32 Ebx; + UINT32 Edx; + UINT32 Ecx; + UINT32 Eax; +} EFI_SYSTEM_CONTEXT_IA32; + +/// +/// x64 processor exception types. +/// +#define EXCEPT_X64_DIVIDE_ERROR 0 +#define EXCEPT_X64_DEBUG 1 +#define EXCEPT_X64_NMI 2 +#define EXCEPT_X64_BREAKPOINT 3 +#define EXCEPT_X64_OVERFLOW 4 +#define EXCEPT_X64_BOUND 5 +#define EXCEPT_X64_INVALID_OPCODE 6 +#define EXCEPT_X64_DOUBLE_FAULT 8 +#define EXCEPT_X64_INVALID_TSS 10 +#define EXCEPT_X64_SEG_NOT_PRESENT 11 +#define EXCEPT_X64_STACK_FAULT 12 +#define EXCEPT_X64_GP_FAULT 13 +#define EXCEPT_X64_PAGE_FAULT 14 +#define EXCEPT_X64_FP_ERROR 16 +#define EXCEPT_X64_ALIGNMENT_CHECK 17 +#define EXCEPT_X64_MACHINE_CHECK 18 +#define EXCEPT_X64_SIMD 19 + +/// +/// FXSAVE_STATE. +/// FP / MMX / XMM registers (see fxrstor instruction definition). +/// +typedef struct { + UINT16 Fcw; + UINT16 Fsw; + UINT16 Ftw; + UINT16 Opcode; + UINT64 Rip; + UINT64 DataOffset; + UINT8 Reserved1[8]; + UINT8 St0Mm0[10], Reserved2[6]; + UINT8 St1Mm1[10], Reserved3[6]; + UINT8 St2Mm2[10], Reserved4[6]; + UINT8 St3Mm3[10], Reserved5[6]; + UINT8 St4Mm4[10], Reserved6[6]; + UINT8 St5Mm5[10], Reserved7[6]; + UINT8 St6Mm6[10], Reserved8[6]; + UINT8 St7Mm7[10], Reserved9[6]; + UINT8 Xmm0[16]; + UINT8 Xmm1[16]; + UINT8 Xmm2[16]; + UINT8 Xmm3[16]; + UINT8 Xmm4[16]; + UINT8 Xmm5[16]; + UINT8 Xmm6[16]; + UINT8 Xmm7[16]; + // + // NOTE: UEFI 2.0 spec definition as follows. + // + UINT8 Reserved11[14 * 16]; +} EFI_FX_SAVE_STATE_X64; + +/// +/// x64 processor context definition. +/// +typedef struct { + UINT64 ExceptionData; + EFI_FX_SAVE_STATE_X64 FxSaveState; + UINT64 Dr0; + UINT64 Dr1; + UINT64 Dr2; + UINT64 Dr3; + UINT64 Dr6; + UINT64 Dr7; + UINT64 Cr0; + UINT64 Cr1; /* Reserved */ + UINT64 Cr2; + UINT64 Cr3; + UINT64 Cr4; + UINT64 Cr8; + UINT64 Rflags; + UINT64 Ldtr; + UINT64 Tr; + UINT64 Gdtr[2]; + UINT64 Idtr[2]; + UINT64 Rip; + UINT64 Gs; + UINT64 Fs; + UINT64 Es; + UINT64 Ds; + UINT64 Cs; + UINT64 Ss; + UINT64 Rdi; + UINT64 Rsi; + UINT64 Rbp; + UINT64 Rsp; + UINT64 Rbx; + UINT64 Rdx; + UINT64 Rcx; + UINT64 Rax; + UINT64 R8; + UINT64 R9; + UINT64 R10; + UINT64 R11; + UINT64 R12; + UINT64 R13; + UINT64 R14; + UINT64 R15; +} EFI_SYSTEM_CONTEXT_X64; + +/// +/// Itanium Processor Family Exception types. +/// +#define EXCEPT_IPF_VHTP_TRANSLATION 0 +#define EXCEPT_IPF_INSTRUCTION_TLB 1 +#define EXCEPT_IPF_DATA_TLB 2 +#define EXCEPT_IPF_ALT_INSTRUCTION_TLB 3 +#define EXCEPT_IPF_ALT_DATA_TLB 4 +#define EXCEPT_IPF_DATA_NESTED_TLB 5 +#define EXCEPT_IPF_INSTRUCTION_KEY_MISSED 6 +#define EXCEPT_IPF_DATA_KEY_MISSED 7 +#define EXCEPT_IPF_DIRTY_BIT 8 +#define EXCEPT_IPF_INSTRUCTION_ACCESS_BIT 9 +#define EXCEPT_IPF_DATA_ACCESS_BIT 10 +#define EXCEPT_IPF_BREAKPOINT 11 +#define EXCEPT_IPF_EXTERNAL_INTERRUPT 12 +// +// 13 - 19 reserved +// +#define EXCEPT_IPF_PAGE_NOT_PRESENT 20 +#define EXCEPT_IPF_KEY_PERMISSION 21 +#define EXCEPT_IPF_INSTRUCTION_ACCESS_RIGHTS 22 +#define EXCEPT_IPF_DATA_ACCESS_RIGHTS 23 +#define EXCEPT_IPF_GENERAL_EXCEPTION 24 +#define EXCEPT_IPF_DISABLED_FP_REGISTER 25 +#define EXCEPT_IPF_NAT_CONSUMPTION 26 +#define EXCEPT_IPF_SPECULATION 27 +// +// 28 reserved +// +#define EXCEPT_IPF_DEBUG 29 +#define EXCEPT_IPF_UNALIGNED_REFERENCE 30 +#define EXCEPT_IPF_UNSUPPORTED_DATA_REFERENCE 31 +#define EXCEPT_IPF_FP_FAULT 32 +#define EXCEPT_IPF_FP_TRAP 33 +#define EXCEPT_IPF_LOWER_PRIVILEGE_TRANSFER_TRAP 34 +#define EXCEPT_IPF_TAKEN_BRANCH 35 +#define EXCEPT_IPF_SINGLE_STEP 36 +// +// 37 - 44 reserved +// +#define EXCEPT_IPF_IA32_EXCEPTION 45 +#define EXCEPT_IPF_IA32_INTERCEPT 46 +#define EXCEPT_IPF_IA32_INTERRUPT 47 + +/// +/// IPF processor context definition. +/// +typedef struct { + // + // The first reserved field is necessary to preserve alignment for the correct + // bits in UNAT and to insure F2 is 16 byte aligned. + // + UINT64 Reserved; + UINT64 R1; + UINT64 R2; + UINT64 R3; + UINT64 R4; + UINT64 R5; + UINT64 R6; + UINT64 R7; + UINT64 R8; + UINT64 R9; + UINT64 R10; + UINT64 R11; + UINT64 R12; + UINT64 R13; + UINT64 R14; + UINT64 R15; + UINT64 R16; + UINT64 R17; + UINT64 R18; + UINT64 R19; + UINT64 R20; + UINT64 R21; + UINT64 R22; + UINT64 R23; + UINT64 R24; + UINT64 R25; + UINT64 R26; + UINT64 R27; + UINT64 R28; + UINT64 R29; + UINT64 R30; + UINT64 R31; + + UINT64 F2[2]; + UINT64 F3[2]; + UINT64 F4[2]; + UINT64 F5[2]; + UINT64 F6[2]; + UINT64 F7[2]; + UINT64 F8[2]; + UINT64 F9[2]; + UINT64 F10[2]; + UINT64 F11[2]; + UINT64 F12[2]; + UINT64 F13[2]; + UINT64 F14[2]; + UINT64 F15[2]; + UINT64 F16[2]; + UINT64 F17[2]; + UINT64 F18[2]; + UINT64 F19[2]; + UINT64 F20[2]; + UINT64 F21[2]; + UINT64 F22[2]; + UINT64 F23[2]; + UINT64 F24[2]; + UINT64 F25[2]; + UINT64 F26[2]; + UINT64 F27[2]; + UINT64 F28[2]; + UINT64 F29[2]; + UINT64 F30[2]; + UINT64 F31[2]; + + UINT64 Pr; + + UINT64 B0; + UINT64 B1; + UINT64 B2; + UINT64 B3; + UINT64 B4; + UINT64 B5; + UINT64 B6; + UINT64 B7; + + // + // application registers + // + UINT64 ArRsc; + UINT64 ArBsp; + UINT64 ArBspstore; + UINT64 ArRnat; + + UINT64 ArFcr; + + UINT64 ArEflag; + UINT64 ArCsd; + UINT64 ArSsd; + UINT64 ArCflg; + UINT64 ArFsr; + UINT64 ArFir; + UINT64 ArFdr; + + UINT64 ArCcv; + + UINT64 ArUnat; + + UINT64 ArFpsr; + + UINT64 ArPfs; + UINT64 ArLc; + UINT64 ArEc; + + // + // control registers + // + UINT64 CrDcr; + UINT64 CrItm; + UINT64 CrIva; + UINT64 CrPta; + UINT64 CrIpsr; + UINT64 CrIsr; + UINT64 CrIip; + UINT64 CrIfa; + UINT64 CrItir; + UINT64 CrIipa; + UINT64 CrIfs; + UINT64 CrIim; + UINT64 CrIha; + + // + // debug registers + // + UINT64 Dbr0; + UINT64 Dbr1; + UINT64 Dbr2; + UINT64 Dbr3; + UINT64 Dbr4; + UINT64 Dbr5; + UINT64 Dbr6; + UINT64 Dbr7; + + UINT64 Ibr0; + UINT64 Ibr1; + UINT64 Ibr2; + UINT64 Ibr3; + UINT64 Ibr4; + UINT64 Ibr5; + UINT64 Ibr6; + UINT64 Ibr7; + + // + // virtual registers - nat bits for R1-R31 + // + UINT64 IntNat; +} EFI_SYSTEM_CONTEXT_IPF; + +/// +/// EBC processor exception types. +/// +#define EXCEPT_EBC_UNDEFINED 0 +#define EXCEPT_EBC_DIVIDE_ERROR 1 +#define EXCEPT_EBC_DEBUG 2 +#define EXCEPT_EBC_BREAKPOINT 3 +#define EXCEPT_EBC_OVERFLOW 4 +#define EXCEPT_EBC_INVALID_OPCODE 5 ///< Opcode out of range. +#define EXCEPT_EBC_STACK_FAULT 6 +#define EXCEPT_EBC_ALIGNMENT_CHECK 7 +#define EXCEPT_EBC_INSTRUCTION_ENCODING 8 ///< Malformed instruction. +#define EXCEPT_EBC_BAD_BREAK 9 ///< BREAK 0 or undefined BREAK. +#define EXCEPT_EBC_STEP 10 ///< To support debug stepping. +/// +/// For coding convenience, define the maximum valid EBC exception. +/// +#define MAX_EBC_EXCEPTION EXCEPT_EBC_STEP + +/// +/// EBC processor context definition. +/// +typedef struct { + UINT64 R0; + UINT64 R1; + UINT64 R2; + UINT64 R3; + UINT64 R4; + UINT64 R5; + UINT64 R6; + UINT64 R7; + UINT64 Flags; + UINT64 ControlFlags; + UINT64 Ip; +} EFI_SYSTEM_CONTEXT_EBC; + +/// +/// ARM processor exception types. +/// +#define EXCEPT_ARM_RESET 0 +#define EXCEPT_ARM_UNDEFINED_INSTRUCTION 1 +#define EXCEPT_ARM_SOFTWARE_INTERRUPT 2 +#define EXCEPT_ARM_PREFETCH_ABORT 3 +#define EXCEPT_ARM_DATA_ABORT 4 +#define EXCEPT_ARM_RESERVED 5 +#define EXCEPT_ARM_IRQ 6 +#define EXCEPT_ARM_FIQ 7 + +/// +/// For coding convenience, define the maximum valid ARM exception. +/// +#define MAX_ARM_EXCEPTION EXCEPT_ARM_FIQ + +/// +/// ARM processor context definition. +/// +typedef struct { + UINT32 R0; + UINT32 R1; + UINT32 R2; + UINT32 R3; + UINT32 R4; + UINT32 R5; + UINT32 R6; + UINT32 R7; + UINT32 R8; + UINT32 R9; + UINT32 R10; + UINT32 R11; + UINT32 R12; + UINT32 SP; + UINT32 LR; + UINT32 PC; + UINT32 CPSR; + UINT32 DFSR; + UINT32 DFAR; + UINT32 IFSR; + UINT32 IFAR; +} EFI_SYSTEM_CONTEXT_ARM; + +/// +/// AARCH64 processor exception types. +/// +#define EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS 0 +#define EXCEPT_AARCH64_IRQ 1 +#define EXCEPT_AARCH64_FIQ 2 +#define EXCEPT_AARCH64_SERROR 3 + +/// +/// For coding convenience, define the maximum valid ARM exception. +/// +#define MAX_AARCH64_EXCEPTION EXCEPT_AARCH64_SERROR + +typedef struct { + // General Purpose Registers + UINT64 X0; + UINT64 X1; + UINT64 X2; + UINT64 X3; + UINT64 X4; + UINT64 X5; + UINT64 X6; + UINT64 X7; + UINT64 X8; + UINT64 X9; + UINT64 X10; + UINT64 X11; + UINT64 X12; + UINT64 X13; + UINT64 X14; + UINT64 X15; + UINT64 X16; + UINT64 X17; + UINT64 X18; + UINT64 X19; + UINT64 X20; + UINT64 X21; + UINT64 X22; + UINT64 X23; + UINT64 X24; + UINT64 X25; + UINT64 X26; + UINT64 X27; + UINT64 X28; + UINT64 FP; // x29 - Frame pointer + UINT64 LR; // x30 - Link Register + UINT64 SP; // x31 - Stack pointer + + // FP/SIMD Registers + UINT64 V0[2]; + UINT64 V1[2]; + UINT64 V2[2]; + UINT64 V3[2]; + UINT64 V4[2]; + UINT64 V5[2]; + UINT64 V6[2]; + UINT64 V7[2]; + UINT64 V8[2]; + UINT64 V9[2]; + UINT64 V10[2]; + UINT64 V11[2]; + UINT64 V12[2]; + UINT64 V13[2]; + UINT64 V14[2]; + UINT64 V15[2]; + UINT64 V16[2]; + UINT64 V17[2]; + UINT64 V18[2]; + UINT64 V19[2]; + UINT64 V20[2]; + UINT64 V21[2]; + UINT64 V22[2]; + UINT64 V23[2]; + UINT64 V24[2]; + UINT64 V25[2]; + UINT64 V26[2]; + UINT64 V27[2]; + UINT64 V28[2]; + UINT64 V29[2]; + UINT64 V30[2]; + UINT64 V31[2]; + + UINT64 ELR; // Exception Link Register + UINT64 SPSR; // Saved Processor Status Register + UINT64 FPSR; // Floating Point Status Register + UINT64 ESR; // Exception syndrome register + UINT64 FAR; // Fault Address Register +} EFI_SYSTEM_CONTEXT_AARCH64; + +/// +/// RISC-V processor exception types. +/// +#define EXCEPT_RISCV_INST_MISALIGNED 0 +#define EXCEPT_RISCV_INST_ACCESS_FAULT 1 +#define EXCEPT_RISCV_ILLEGAL_INST 2 +#define EXCEPT_RISCV_BREAKPOINT 3 +#define EXCEPT_RISCV_LOAD_ADDRESS_MISALIGNED 4 +#define EXCEPT_RISCV_LOAD_ACCESS_FAULT 5 +#define EXCEPT_RISCV_STORE_AMO_ADDRESS_MISALIGNED 6 +#define EXCEPT_RISCV_STORE_AMO_ACCESS_FAULT 7 +#define EXCEPT_RISCV_ENV_CALL_FROM_UMODE 8 +#define EXCEPT_RISCV_ENV_CALL_FROM_SMODE 9 +#define EXCEPT_RISCV_ENV_CALL_FROM_VS_MODE 10 +#define EXCEPT_RISCV_ENV_CALL_FROM_MMODE 11 +#define EXCEPT_RISCV_INST_ACCESS_PAGE_FAULT 12 +#define EXCEPT_RISCV_LOAD_ACCESS_PAGE_FAULT 13 +#define EXCEPT_RISCV_14 14 +#define EXCEPT_RISCV_STORE_ACCESS_PAGE_FAULT 15 +#define EXCEPT_RISCV_16 16 +#define EXCEPT_RISCV_17 17 +#define EXCEPT_RISCV_18 18 +#define EXCEPT_RISCV_19 19 +#define EXCEPT_RISCV_INST_GUEST_PAGE_FAULT 20 +#define EXCEPT_RISCV_LOAD_GUEST_PAGE_FAULT 21 +#define EXCEPT_RISCV_VIRTUAL_INSTRUCTION 22 +#define EXCEPT_RISCV_STORE_GUEST_PAGE_FAULT 23 +#define EXCEPT_RISCV_MAX_EXCEPTIONS (EXCEPT_RISCV_STORE_GUEST_PAGE_FAULT) + +/// +/// RISC-V processor exception types for interrupts. +/// +#define EXCEPT_RISCV_IS_IRQ(x) ((x & 0x8000000000000000UL) != 0) +#define EXCEPT_RISCV_IRQ_INDEX(x) (x & 0x7FFFFFFFFFFFFFFFUL) +#define EXCEPT_RISCV_IRQ_0 0x8000000000000000UL +#define EXCEPT_RISCV_IRQ_SOFT_FROM_SMODE 0x8000000000000001UL +#define EXCEPT_RISCV_IRQ_SOFT_FROM_VSMODE 0x8000000000000002UL +#define EXCEPT_RISCV_IRQ_SOFT_FROM_MMODE 0x8000000000000003UL +#define EXCEPT_RISCV_IRQ_4 0x8000000000000004UL +#define EXCEPT_RISCV_IRQ_TIMER_FROM_SMODE 0x8000000000000005UL +#define EXCEPT_RISCV_MAX_IRQS (EXCEPT_RISCV_IRQ_INDEX(EXCEPT_RISCV_IRQ_TIMER_FROM_SMODE)) + +typedef struct { + UINT64 X0; + UINT64 X1; + UINT64 X2; + UINT64 X3; + UINT64 X4; + UINT64 X5; + UINT64 X6; + UINT64 X7; + UINT64 X8; + UINT64 X9; + UINT64 X10; + UINT64 X11; + UINT64 X12; + UINT64 X13; + UINT64 X14; + UINT64 X15; + UINT64 X16; + UINT64 X17; + UINT64 X18; + UINT64 X19; + UINT64 X20; + UINT64 X21; + UINT64 X22; + UINT64 X23; + UINT64 X24; + UINT64 X25; + UINT64 X26; + UINT64 X27; + UINT64 X28; + UINT64 X29; + UINT64 X30; + UINT64 X31; + UINT64 SEPC; + UINT32 SSTATUS; + UINT32 STVAL; +} EFI_SYSTEM_CONTEXT_RISCV64; + +/// +/// LoongArch processor exception types. +/// +/// The exception types is located in the CSR ESTAT +/// register offset 16 bits, width 6 bits. +/// +/// If you want to register an exception hook, you can +/// shfit the number left by 16 bits, and the exception +/// handler will know the types. +/// +/// For example: +/// mCpu->CpuRegisterInterruptHandler ( +/// mCpu, +/// (EXCEPT_LOONGARCH_PPI << CSR_ESTAT_EXC_SHIFT), +/// PpiExceptionHandler +/// ); +/// +#define EXCEPT_LOONGARCH_INT 0 +#define EXCEPT_LOONGARCH_PIL 1 +#define EXCEPT_LOONGARCH_PIS 2 +#define EXCEPT_LOONGARCH_PIF 3 +#define EXCEPT_LOONGARCH_PME 4 +#define EXCEPT_LOONGARCH_PNR 5 +#define EXCEPT_LOONGARCH_PNX 6 +#define EXCEPT_LOONGARCH_PPI 7 +#define EXCEPT_LOONGARCH_ADE 8 +#define EXCEPT_LOONGARCH_ALE 9 +#define EXCEPT_LOONGARCH_BCE 10 +#define EXCEPT_LOONGARCH_SYS 11 +#define EXCEPT_LOONGARCH_BRK 12 +#define EXCEPT_LOONGARCH_INE 13 +#define EXCEPT_LOONGARCH_IPE 14 +#define EXCEPT_LOONGARCH_FPD 15 +#define EXCEPT_LOONGARCH_SXD 16 +#define EXCEPT_LOONGARCH_ASXD 17 +#define EXCEPT_LOONGARCH_FPE 18 +#define EXCEPT_LOONGARCH_WPE 19 +#define EXCEPT_LOONGARCH_BTD 20 +#define EXCEPT_LOONGARCH_BTE 21 +#define EXCEPT_LOONGARCH_GSPR 22 +#define EXCEPT_LOONGARCH_HVC 23 +#define EXCEPT_LOONGARCH_GCXC 24 + +/// +/// For coding convenience, define the maximum valid +/// LoongArch exception. +/// +#define MAX_LOONGARCH_EXCEPTION 64 + +/// +/// LoongArch processor Interrupt types. +/// +#define EXCEPT_LOONGARCH_INT_SIP0 0 +#define EXCEPT_LOONGARCH_INT_SIP1 1 +#define EXCEPT_LOONGARCH_INT_IP0 2 +#define EXCEPT_LOONGARCH_INT_IP1 3 +#define EXCEPT_LOONGARCH_INT_IP2 4 +#define EXCEPT_LOONGARCH_INT_IP3 5 +#define EXCEPT_LOONGARCH_INT_IP4 6 +#define EXCEPT_LOONGARCH_INT_IP5 7 +#define EXCEPT_LOONGARCH_INT_IP6 8 +#define EXCEPT_LOONGARCH_INT_IP7 9 +#define EXCEPT_LOONGARCH_INT_PMC 10 +#define EXCEPT_LOONGARCH_INT_TIMER 11 +#define EXCEPT_LOONGARCH_INT_IPI 12 + +/// +/// For coding convenience, define the maximum valid +/// LoongArch interrupt. +/// +#define MAX_LOONGARCH_INTERRUPT 16 + +typedef struct { + UINT64 R0; + UINT64 R1; + UINT64 R2; + UINT64 R3; + UINT64 R4; + UINT64 R5; + UINT64 R6; + UINT64 R7; + UINT64 R8; + UINT64 R9; + UINT64 R10; + UINT64 R11; + UINT64 R12; + UINT64 R13; + UINT64 R14; + UINT64 R15; + UINT64 R16; + UINT64 R17; + UINT64 R18; + UINT64 R19; + UINT64 R20; + UINT64 R21; + UINT64 R22; + UINT64 R23; + UINT64 R24; + UINT64 R25; + UINT64 R26; + UINT64 R27; + UINT64 R28; + UINT64 R29; + UINT64 R30; + UINT64 R31; + + UINT64 CRMD; // CuRrent MoDe information + UINT64 PRMD; // PRe-exception MoDe information + UINT64 EUEN; // Extended component Unit ENable + UINT64 MISC; // MISCellaneous controller + UINT64 ECFG; // Exception ConFiGuration + UINT64 ESTAT; // Exception STATus + UINT64 ERA; // Exception Return Address + UINT64 BADV; // BAD Virtual address + UINT64 BADI; // BAD Instruction +} EFI_SYSTEM_CONTEXT_LOONGARCH64; + +/// +/// Universal EFI_SYSTEM_CONTEXT definition. +/// +typedef union { + EFI_SYSTEM_CONTEXT_EBC *SystemContextEbc; + EFI_SYSTEM_CONTEXT_IA32 *SystemContextIa32; + EFI_SYSTEM_CONTEXT_X64 *SystemContextX64; + EFI_SYSTEM_CONTEXT_IPF *SystemContextIpf; + EFI_SYSTEM_CONTEXT_ARM *SystemContextArm; + EFI_SYSTEM_CONTEXT_AARCH64 *SystemContextAArch64; + EFI_SYSTEM_CONTEXT_RISCV64 *SystemContextRiscV64; + EFI_SYSTEM_CONTEXT_LOONGARCH64 *SystemContextLoongArch64; +} EFI_SYSTEM_CONTEXT; + +// +// DebugSupport callback function prototypes +// + +/** + Registers and enables an exception callback function for the specified exception. + + @param ExceptionType Exception types in EBC, IA-32, x64, or IPF. + @param SystemContext Exception content. + +**/ +typedef +VOID +(EFIAPI *EFI_EXCEPTION_CALLBACK)( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN OUT EFI_SYSTEM_CONTEXT SystemContext + ); + +/** + Registers and enables the on-target debug agent's periodic entry point. + + @param SystemContext Exception content. + +**/ +typedef +VOID +(EFIAPI *EFI_PERIODIC_CALLBACK)( + IN OUT EFI_SYSTEM_CONTEXT SystemContext + ); + +/// +/// Machine type definition +/// +typedef enum { + IsaIa32 = IMAGE_FILE_MACHINE_I386, ///< 0x014C + IsaX64 = IMAGE_FILE_MACHINE_X64, ///< 0x8664 + IsaIpf = IMAGE_FILE_MACHINE_IA64, ///< 0x0200 + IsaEbc = IMAGE_FILE_MACHINE_EBC, ///< 0x0EBC + IsaArm = IMAGE_FILE_MACHINE_ARMTHUMB_MIXED, ///< 0x01c2 + IsaAArch64 = IMAGE_FILE_MACHINE_ARM64 ///< 0xAA64 +} EFI_INSTRUCTION_SET_ARCHITECTURE; + +// +// DebugSupport member function definitions +// + +/** + Returns the maximum value that may be used for the ProcessorIndex parameter in + RegisterPeriodicCallback() and RegisterExceptionCallback(). + + @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. + @param MaxProcessorIndex Pointer to a caller-allocated UINTN in which the maximum supported + processor index is returned. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_GET_MAXIMUM_PROCESSOR_INDEX)( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + OUT UINTN *MaxProcessorIndex + ); + +/** + Registers a function to be called back periodically in interrupt context. + + @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. + @param ProcessorIndex Specifies which processor the callback function applies to. + @param PeriodicCallback A pointer to a function of type PERIODIC_CALLBACK that is the main + periodic entry point of the debug agent. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback + function was previously registered. + @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback + function. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_PERIODIC_CALLBACK)( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN EFI_PERIODIC_CALLBACK PeriodicCallback + ); + +/** + Registers a function to be called when a given processor exception occurs. + + @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. + @param ProcessorIndex Specifies which processor the callback function applies to. + @param ExceptionCallback A pointer to a function of type EXCEPTION_CALLBACK that is called + when the processor exception specified by ExceptionType occurs. + @param ExceptionType Specifies which processor exception to hook. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback + function was previously registered. + @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback + function. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_EXCEPTION_CALLBACK)( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN EFI_EXCEPTION_CALLBACK ExceptionCallback, + IN EFI_EXCEPTION_TYPE ExceptionType + ); + +/** + Invalidates processor instruction cache for a memory range. Subsequent execution in this range + causes a fresh memory fetch to retrieve code to be executed. + + @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. + @param ProcessorIndex Specifies which processor's instruction cache is to be invalidated. + @param Start Specifies the physical base of the memory range to be invalidated. + @param Length Specifies the minimum number of bytes in the processor's instruction + cache to invalidate. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_INVALIDATE_INSTRUCTION_CACHE)( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN VOID *Start, + IN UINT64 Length + ); + +/// +/// This protocol provides the services to allow the debug agent to register +/// callback functions that are called either periodically or when specific +/// processor exceptions occur. +/// +struct _EFI_DEBUG_SUPPORT_PROTOCOL { + /// + /// Declares the processor architecture for this instance of the EFI Debug Support protocol. + /// + EFI_INSTRUCTION_SET_ARCHITECTURE Isa; + EFI_GET_MAXIMUM_PROCESSOR_INDEX GetMaximumProcessorIndex; + EFI_REGISTER_PERIODIC_CALLBACK RegisterPeriodicCallback; + EFI_REGISTER_EXCEPTION_CALLBACK RegisterExceptionCallback; + EFI_INVALIDATE_INSTRUCTION_CACHE InvalidateInstructionCache; +}; + +extern EFI_GUID gEfiDebugSupportProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Decompress.h b/sys/contrib/edk2/Include/Protocol/Decompress.h new file mode 100644 index 000000000000..32cdb377321c --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Decompress.h @@ -0,0 +1,116 @@ +/** @file + The Decompress Protocol Interface as defined in UEFI spec + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __DECOMPRESS_H__ +#define __DECOMPRESS_H__ + +#define EFI_DECOMPRESS_PROTOCOL_GUID \ + { \ + 0xd8117cfe, 0x94a6, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +typedef struct _EFI_DECOMPRESS_PROTOCOL EFI_DECOMPRESS_PROTOCOL; + +/** + The GetInfo() function retrieves the size of the uncompressed buffer + and the temporary scratch buffer required to decompress the buffer + specified by Source and SourceSize. If the size of the uncompressed + buffer or the size of the scratch buffer cannot be determined from + the compressed data specified by Source and SourceData, then + EFI_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed + buffer is returned in DestinationSize, the size of the scratch buffer is + returned in ScratchSize, and EFI_SUCCESS is returned. + + The GetInfo() function does not have a scratch buffer available to perform + a thorough checking of the validity of the source data. It just retrieves + the 'Original Size' field from the beginning bytes of the source data and + output it as DestinationSize. And ScratchSize is specific to the decompression + implementation. + + @param This A pointer to the EFI_DECOMPRESS_PROTOCOL instance. + @param Source The source buffer containing the compressed data. + @param SourceSize The size, in bytes, of source buffer. + @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer + that will be generated when the compressed buffer specified + by Source and SourceSize is decompressed. + @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that + is required to decompress the compressed buffer specified by + Source and SourceSize. + + @retval EFI_SUCCESS The size of the uncompressed data was returned in DestinationSize + and the size of the scratch buffer was returned in ScratchSize. + @retval EFI_INVALID_PARAMETER The size of the uncompressed data or the size of the scratch + buffer cannot be determined from the compressed data specified by + Source and SourceData. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DECOMPRESS_GET_INFO)( + IN EFI_DECOMPRESS_PROTOCOL *This, + IN VOID *Source, + IN UINT32 SourceSize, + OUT UINT32 *DestinationSize, + OUT UINT32 *ScratchSize + ); + +/** + The Decompress() function extracts decompressed data to its original form. + + This protocol is designed so that the decompression algorithm can be + implemented without using any memory services. As a result, the + Decompress() function is not allowed to call AllocatePool() or + AllocatePages() in its implementation. It is the caller's responsibility + to allocate and free the Destination and Scratch buffers. + + If the compressed source data specified by Source and SourceSize is + successfully decompressed into Destination, then EFI_SUCCESS is returned. + If the compressed source data specified by Source and SourceSize is not in + a valid compressed data format, then EFI_INVALID_PARAMETER is returned. + + @param This A pointer to the EFI_DECOMPRESS_PROTOCOL instance. + @param Source The source buffer containing the compressed data. + @param SourceSize The size of source data. + @param Destination On output, the destination buffer that contains + the uncompressed data. + @param DestinationSize The size of destination buffer. The size of destination + buffer needed is obtained from GetInfo(). + @param Scratch A temporary scratch buffer that is used to perform the + decompression. + @param ScratchSize The size of scratch buffer. The size of scratch buffer needed + is obtained from GetInfo(). + + @retval EFI_SUCCESS Decompression completed successfully, and the uncompressed + buffer is returned in Destination. + @retval EFI_INVALID_PARAMETER The source buffer specified by Source and SourceSize is + corrupted (not in a valid compressed format). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DECOMPRESS_DECOMPRESS)( + IN EFI_DECOMPRESS_PROTOCOL *This, + IN VOID *Source, + IN UINT32 SourceSize, + IN OUT VOID *Destination, + IN UINT32 DestinationSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize + ); + +/// +/// Provides a decompression service. +/// +struct _EFI_DECOMPRESS_PROTOCOL { + EFI_DECOMPRESS_GET_INFO GetInfo; + EFI_DECOMPRESS_DECOMPRESS Decompress; +}; + +extern EFI_GUID gEfiDecompressProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/DeviceIo.h b/sys/contrib/edk2/Include/Protocol/DeviceIo.h new file mode 100644 index 000000000000..78fed7512607 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/DeviceIo.h @@ -0,0 +1,262 @@ +/** @file + Device IO protocol as defined in the EFI 1.10 specification. + + Device IO is used to abstract hardware access to devices. It includes + memory mapped IO, IO, PCI Config space, and DMA. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __DEVICE_IO_H__ +#define __DEVICE_IO_H__ + +#define EFI_DEVICE_IO_PROTOCOL_GUID \ + { \ + 0xaf6ac311, 0x84c3, 0x11d2, {0x8e, 0x3c, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +typedef struct _EFI_DEVICE_IO_PROTOCOL EFI_DEVICE_IO_PROTOCOL; + +/// +/// Protocol GUID name defined in EFI1.1. +/// +#define DEVICE_IO_PROTOCOL EFI_DEVICE_IO_PROTOCOL_GUID + +/// +/// Protocol defined in EFI1.1. +/// +typedef EFI_DEVICE_IO_PROTOCOL EFI_DEVICE_IO_INTERFACE; + +/// +/// Device IO Access Width +/// +typedef enum { + IO_UINT8 = 0, + IO_UINT16 = 1, + IO_UINT32 = 2, + IO_UINT64 = 3, + // + // Below enumerations are added in "Extensible Firmware Interface Specification, + // Version 1.10, Specification Update, Version 001". + // + MMIO_COPY_UINT8 = 4, + MMIO_COPY_UINT16 = 5, + MMIO_COPY_UINT32 = 6, + MMIO_COPY_UINT64 = 7 +} EFI_IO_WIDTH; + +/** + Enables a driver to access device registers in the appropriate memory or I/O space. + + @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. + @param Width Signifies the width of the I/O operations. + @param Address The base address of the I/O operations. + @param Count The number of I/O operations to perform. + @param Buffer For read operations, the destination buffer to store the results. For write + operations, the source buffer to write data from. If + Width is MMIO_COPY_UINT8, MMIO_COPY_UINT16, + MMIO_COPY_UINT32, or MMIO_COPY_UINT64, then + Buffer is interpreted as a base address of an I/O operation such as Address. + + @retval EFI_SUCCESS The data was read from or written to the device. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_INVALID_PARAMETER Width is invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DEVICE_IO)( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_IO_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +typedef struct { + EFI_DEVICE_IO Read; + EFI_DEVICE_IO Write; +} EFI_IO_ACCESS; + +/** + Provides an EFI Device Path for a PCI device with the given PCI configuration space address. + + @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. + @param PciAddress The PCI configuration space address of the device whose Device Path + is going to be returned. + @param PciDevicePath A pointer to the pointer for the EFI Device Path for PciAddress. + Memory for the Device Path is allocated from the pool. + + @retval EFI_SUCCESS The PciDevicePath returns a pointer to a valid EFI Device Path. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_UNSUPPORTED The PciAddress does not map to a valid EFI Device Path. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_DEVICE_PATH)( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN UINT64 PciAddress, + IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath + ); + +typedef enum { + /// + /// A read operation from system memory by a bus master. + /// + EfiBusMasterRead, + + /// + /// A write operation to system memory by a bus master. + /// + EfiBusMasterWrite, + + /// + /// Provides both read and write access to system memory + /// by both the processor and a bus master. The buffer is + /// coherent from both the processor's and the bus master's + /// point of view. + /// + EfiBusMasterCommonBuffer +} EFI_IO_OPERATION_TYPE; + +/** + Provides the device-specific addresses needed to access system memory. + + @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. + @param Operation Indicates if the bus master is going to read or write to system memory. + @param HostAddress The system memory address to map to the device. + @param NumberOfBytes On input, the number of bytes to map. + On output, the number of bytes that were mapped. + @param DeviceAddress The resulting map address for the bus master device to use to access the + hosts HostAddress. + @param Mapping A resulting value to pass to Unmap(). + + @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. + @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined. + @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IO_MAP)( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_IO_OPERATION_TYPE Operation, + IN EFI_PHYSICAL_ADDRESS *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ); + +/** + Completes the Map() operation and releases any corresponding resources. + + @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. + @param Mapping A resulting value to pass to Unmap(). + + @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. + @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IO_UNMAP)( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN VOID *Mapping + ); + +/** + Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping. + + @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. + @param Type The type allocation to perform. + @param MemoryType The type of memory to allocate, EfiBootServicesData or + EfiRuntimeServicesData. + @param Pages The number of pages to allocate. + @param HostAddress A pointer to store the base address of the allocated range. + + @retval EFI_SUCCESS The requested memory pages were allocated. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + @retval EFI_INVALID_PARAMETER The requested memory type is invalid. + @retval EFI_UNSUPPORTED The requested HostAddress is not supported on + this platform. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IO_ALLOCATE_BUFFER)( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *HostAddress + ); + +/** + Flushes any posted write data to the device. + + @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. + + @retval EFI_SUCCESS The buffers were flushed. + @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IO_FLUSH)( + IN EFI_DEVICE_IO_PROTOCOL *This + ); + +/** + Frees pages that were allocated with AllocateBuffer(). + + @param This A pointer to the EFI_DEVICE_IO_INTERFACE instance. + @param Pages The number of pages to free. + @param HostAddress The base address of the range to free. + + @retval EFI_SUCCESS The requested memory pages were allocated. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + AllocateBuffer(). + @retval EFI_INVALID_PARAMETER HostAddress is not page aligned or Pages is invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IO_FREE_BUFFER)( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN UINTN Pages, + IN EFI_PHYSICAL_ADDRESS HostAddress + ); + +/// +/// This protocol provides the basic Memory, I/O, and PCI interfaces that +/// are used to abstract accesses to devices. +/// +struct _EFI_DEVICE_IO_PROTOCOL { + /// + /// Allows reads and writes to memory mapped I/O space. + /// + EFI_IO_ACCESS Mem; + /// + /// Allows reads and writes to I/O space. + /// + EFI_IO_ACCESS Io; + /// + /// Allows reads and writes to PCI configuration space. + /// + EFI_IO_ACCESS Pci; + EFI_IO_MAP Map; + EFI_PCI_DEVICE_PATH PciDevicePath; + EFI_IO_UNMAP Unmap; + EFI_IO_ALLOCATE_BUFFER AllocateBuffer; + EFI_IO_FLUSH Flush; + EFI_IO_FREE_BUFFER FreeBuffer; +}; + +extern EFI_GUID gEfiDeviceIoProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Dhcp4.h b/sys/contrib/edk2/Include/Protocol/Dhcp4.h new file mode 100644 index 000000000000..fec8fea9989a --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Dhcp4.h @@ -0,0 +1,762 @@ +/** @file + EFI_DHCP4_PROTOCOL as defined in UEFI 2.0. + EFI_DHCP4_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.0. + These protocols are used to collect configuration information for the EFI IPv4 Protocol + drivers and to provide DHCPv4 server and PXE boot server discovery services. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol was introduced in UEFI Specification 2.0. + +**/ + +#ifndef __EFI_DHCP4_PROTOCOL_H__ +#define __EFI_DHCP4_PROTOCOL_H__ + +#define EFI_DHCP4_PROTOCOL_GUID \ + { \ + 0x8a219718, 0x4ef5, 0x4761, {0x91, 0xc8, 0xc0, 0xf0, 0x4b, 0xda, 0x9e, 0x56 } \ + } + +#define EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0x9d9a39d8, 0xbd42, 0x4a73, {0xa4, 0xd5, 0x8e, 0xe9, 0x4b, 0xe1, 0x13, 0x80 } \ + } + +typedef struct _EFI_DHCP4_PROTOCOL EFI_DHCP4_PROTOCOL; + +#pragma pack(1) +typedef struct { + /// + /// DHCP option code. + /// + UINT8 OpCode; + /// + /// Length of the DHCP option data. Not present if OpCode is 0 or 255. + /// + UINT8 Length; + /// + /// Start of the DHCP option data. Not present if OpCode is 0 or 255 or if Length is zero. + /// + UINT8 Data[1]; +} EFI_DHCP4_PACKET_OPTION; +#pragma pack() + +#pragma pack(1) +/// +/// EFI_DHCP4_PACKET defines the format of DHCPv4 packets. See RFC 2131 for more information. +/// +typedef struct { + UINT8 OpCode; + UINT8 HwType; + UINT8 HwAddrLen; + UINT8 Hops; + UINT32 Xid; + UINT16 Seconds; + UINT16 Reserved; + EFI_IPv4_ADDRESS ClientAddr; ///< Client IP address from client. + EFI_IPv4_ADDRESS YourAddr; ///< Client IP address from server. + EFI_IPv4_ADDRESS ServerAddr; ///< IP address of next server in bootstrap. + EFI_IPv4_ADDRESS GatewayAddr; ///< Relay agent IP address. + UINT8 ClientHwAddr[16]; ///< Client hardware address. + CHAR8 ServerName[64]; + CHAR8 BootFileName[128]; +} EFI_DHCP4_HEADER; +#pragma pack() + +#pragma pack(1) +typedef struct { + /// + /// Size of the EFI_DHCP4_PACKET buffer. + /// + UINT32 Size; + /// + /// Length of the EFI_DHCP4_PACKET from the first byte of the Header field + /// to the last byte of the Option[] field. + /// + UINT32 Length; + + struct { + /// + /// DHCP packet header. + /// + EFI_DHCP4_HEADER Header; + /// + /// DHCP magik cookie in network byte order. + /// + UINT32 Magik; + /// + /// Start of the DHCP packed option data. + /// + UINT8 Option[1]; + } Dhcp4; +} EFI_DHCP4_PACKET; +#pragma pack() + +typedef enum { + /// + /// The EFI DHCPv4 Protocol driver is stopped. + /// + Dhcp4Stopped = 0x0, + /// + /// The EFI DHCPv4 Protocol driver is inactive. + /// + Dhcp4Init = 0x1, + /// + /// The EFI DHCPv4 Protocol driver is collecting DHCP offer packets from DHCP servers. + /// + Dhcp4Selecting = 0x2, + /// + /// The EFI DHCPv4 Protocol driver has sent the request to the DHCP server and is waiting for a response. + /// + Dhcp4Requesting = 0x3, + /// + /// The DHCP configuration has completed. + /// + Dhcp4Bound = 0x4, + /// + /// The DHCP configuration is being renewed and another request has + /// been sent out, but it has not received a response from the server yet. + /// + Dhcp4Renewing = 0x5, + /// + /// The DHCP configuration has timed out and the EFI DHCPv4 + /// Protocol driver is trying to extend the lease time. + /// + Dhcp4Rebinding = 0x6, + /// + /// The EFI DHCPv4 Protocol driver was initialized with a previously + /// allocated or known IP address. + /// + Dhcp4InitReboot = 0x7, + /// + /// The EFI DHCPv4 Protocol driver is seeking to reuse the previously + /// allocated IP address by sending a request to the DHCP server. + /// + Dhcp4Rebooting = 0x8 +} EFI_DHCP4_STATE; + +typedef enum { + /// + /// The packet to start the configuration sequence is about to be sent. + /// + Dhcp4SendDiscover = 0x01, + /// + /// A reply packet was just received. + /// + Dhcp4RcvdOffer = 0x02, + /// + /// It is time for Dhcp4Callback to select an offer. + /// + Dhcp4SelectOffer = 0x03, + /// + /// A request packet is about to be sent. + /// + Dhcp4SendRequest = 0x04, + /// + /// A DHCPACK packet was received and will be passed to Dhcp4Callback. + /// + Dhcp4RcvdAck = 0x05, + /// + /// A DHCPNAK packet was received and will be passed to Dhcp4Callback. + /// + Dhcp4RcvdNak = 0x06, + /// + /// A decline packet is about to be sent. + /// + Dhcp4SendDecline = 0x07, + /// + /// The DHCP configuration process has completed. No packet is associated with this event. + /// + Dhcp4BoundCompleted = 0x08, + /// + /// It is time to enter the Dhcp4Renewing state and to contact the server + /// that originally issued the network address. No packet is associated with this event. + /// + Dhcp4EnterRenewing = 0x09, + /// + /// It is time to enter the Dhcp4Rebinding state and to contact any server. + /// No packet is associated with this event. + /// + Dhcp4EnterRebinding = 0x0a, + /// + /// The configured IP address was lost either because the lease has expired, + /// the user released the configuration, or a DHCPNAK packet was received in + /// the Dhcp4Renewing or Dhcp4Rebinding state. No packet is associated with this event. + /// + Dhcp4AddressLost = 0x0b, + /// + /// The DHCP process failed because a DHCPNAK packet was received or the user + /// aborted the DHCP process at a time when the configuration was not available yet. + /// No packet is associated with this event. + /// + Dhcp4Fail = 0x0c +} EFI_DHCP4_EVENT; + +/** + Callback routine. + + EFI_DHCP4_CALLBACK is provided by the consumer of the EFI DHCPv4 Protocol driver + to intercept events that occurred in the configuration process. This structure + provides advanced control of each state transition of the DHCP process. The + returned status code determines the behavior of the EFI DHCPv4 Protocol driver. + There are three possible returned values, which are described in the following + table. + + @param This The pointer to the EFI DHCPv4 Protocol instance that is used to + configure this callback function. + @param Context The pointer to the context that is initialized by + EFI_DHCP4_PROTOCOL.Configure(). + @param CurrentState The current operational state of the EFI DHCPv4 Protocol + driver. + @param Dhcp4Event The event that occurs in the current state, which usually means a + state transition. + @param Packet The DHCP packet that is going to be sent or already received. + @param NewPacket The packet that is used to replace the above Packet. + + @retval EFI_SUCCESS Tells the EFI DHCPv4 Protocol driver to continue the DHCP process. + When it is in the Dhcp4Selecting state, it tells the EFI DHCPv4 Protocol + driver to stop collecting additional packets. The driver will exit + the Dhcp4Selecting state and enter the Dhcp4Requesting state. + @retval EFI_NOT_READY Only used in the Dhcp4Selecting state. The EFI DHCPv4 Protocol + driver will continue to wait for more packets until the retry + timeout expires. + @retval EFI_ABORTED Tells the EFI DHCPv4 Protocol driver to abort the current process and + return to the Dhcp4Init or Dhcp4InitReboot state. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP4_CALLBACK)( + IN EFI_DHCP4_PROTOCOL *This, + IN VOID *Context, + IN EFI_DHCP4_STATE CurrentState, + IN EFI_DHCP4_EVENT Dhcp4Event, + IN EFI_DHCP4_PACKET *Packet OPTIONAL, + OUT EFI_DHCP4_PACKET **NewPacket OPTIONAL + ); + +typedef struct { + /// + /// The number of times to try sending a packet during the Dhcp4SendDiscover + /// event and waiting for a response during the Dhcp4RcvdOffer event. + /// Set to zero to use the default try counts and timeout values. + /// + UINT32 DiscoverTryCount; + /// + /// The maximum amount of time (in seconds) to wait for returned packets in each + /// of the retries. Timeout values of zero will default to a timeout value + /// of one second. Set to NULL to use default timeout values. + /// + UINT32 *DiscoverTimeout; + /// + /// The number of times to try sending a packet during the Dhcp4SendRequest event + /// and waiting for a response during the Dhcp4RcvdAck event before accepting + /// failure. Set to zero to use the default try counts and timeout values. + /// + UINT32 RequestTryCount; + /// + /// The maximum amount of time (in seconds) to wait for return packets in each of the retries. + /// Timeout values of zero will default to a timeout value of one second. + /// Set to NULL to use default timeout values. + /// + UINT32 *RequestTimeout; + /// + /// For a DHCPDISCOVER, setting this parameter to the previously allocated IP + /// address will cause the EFI DHCPv4 Protocol driver to enter the Dhcp4InitReboot state. + /// And set this field to 0.0.0.0 to enter the Dhcp4Init state. + /// For a DHCPINFORM this parameter should be set to the client network address + /// which was assigned to the client during a DHCPDISCOVER. + /// + EFI_IPv4_ADDRESS ClientAddress; + /// + /// The callback function to intercept various events that occurred in + /// the DHCP configuration process. Set to NULL to ignore all those events. + /// + EFI_DHCP4_CALLBACK Dhcp4Callback; + /// + /// The pointer to the context that will be passed to Dhcp4Callback when it is called. + /// + VOID *CallbackContext; + /// + /// Number of DHCP options in the OptionList. + /// + UINT32 OptionCount; + /// + /// List of DHCP options to be included in every packet that is sent during the + /// Dhcp4SendDiscover event. Pad options are appended automatically by DHCP driver + /// in outgoing DHCP packets. If OptionList itself contains pad option, they are + /// ignored by the driver. OptionList can be freed after EFI_DHCP4_PROTOCOL.Configure() + /// returns. Ignored if OptionCount is zero. + /// + EFI_DHCP4_PACKET_OPTION **OptionList; +} EFI_DHCP4_CONFIG_DATA; + +typedef struct { + /// + /// The EFI DHCPv4 Protocol driver operating state. + /// + EFI_DHCP4_STATE State; + /// + /// The configuration data of the current EFI DHCPv4 Protocol driver instance. + /// + EFI_DHCP4_CONFIG_DATA ConfigData; + /// + /// The client IP address that was acquired from the DHCP server. If it is zero, + /// the DHCP acquisition has not completed yet and the following fields in this structure are undefined. + /// + EFI_IPv4_ADDRESS ClientAddress; + /// + /// The local hardware address. + /// + EFI_MAC_ADDRESS ClientMacAddress; + /// + /// The server IP address that is providing the DHCP service to this client. + /// + EFI_IPv4_ADDRESS ServerAddress; + /// + /// The router IP address that was acquired from the DHCP server. + /// May be zero if the server does not offer this address. + /// + EFI_IPv4_ADDRESS RouterAddress; + /// + /// The subnet mask of the connected network that was acquired from the DHCP server. + /// + EFI_IPv4_ADDRESS SubnetMask; + /// + /// The lease time (in 1-second units) of the configured IP address. + /// The value 0xFFFFFFFF means that the lease time is infinite. + /// A default lease of 7 days is used if the DHCP server does not provide a value. + /// + UINT32 LeaseTime; + /// + /// The cached latest DHCPACK or DHCPNAK or BOOTP REPLY packet. May be NULL if no packet is cached. + /// + EFI_DHCP4_PACKET *ReplyPacket; +} EFI_DHCP4_MODE_DATA; + +typedef struct { + /// + /// Alternate listening address. It can be a unicast, multicast, or broadcast address. + /// + EFI_IPv4_ADDRESS ListenAddress; + /// + /// The subnet mask of above listening unicast/broadcast IP address. + /// Ignored if ListenAddress is a multicast address. + /// + EFI_IPv4_ADDRESS SubnetMask; + /// + /// Alternate station source (or listening) port number. + /// If zero, then the default station port number (68) will be used. + /// + UINT16 ListenPort; +} EFI_DHCP4_LISTEN_POINT; + +typedef struct { + /// + /// The completion status of transmitting and receiving. + /// + EFI_STATUS Status; + /// + /// If not NULL, the event that will be signaled when the collection process + /// completes. If NULL, this function will busy-wait until the collection process competes. + /// + EFI_EVENT CompletionEvent; + /// + /// The pointer to the server IP address. This address may be a unicast, multicast, or broadcast address. + /// + EFI_IPv4_ADDRESS RemoteAddress; + /// + /// The server listening port number. If zero, the default server listening port number (67) will be used. + /// + UINT16 RemotePort; + /// + /// The pointer to the gateway address to override the existing setting. + /// + EFI_IPv4_ADDRESS GatewayAddress; + /// + /// The number of entries in ListenPoints. If zero, the default station address and port number 68 are used. + /// + UINT32 ListenPointCount; + /// + /// An array of station address and port number pairs that are used as receiving filters. + /// The first entry is also used as the source address and source port of the outgoing packet. + /// + EFI_DHCP4_LISTEN_POINT *ListenPoints; + /// + /// The number of seconds to collect responses. Zero is invalid. + /// + UINT32 TimeoutValue; + /// + /// The pointer to the packet to be transmitted. + /// + EFI_DHCP4_PACKET *Packet; + /// + /// Number of received packets. + /// + UINT32 ResponseCount; + /// + /// The pointer to the allocated list of received packets. + /// + EFI_DHCP4_PACKET *ResponseList; +} EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN; + +/** + Returns the current operating mode and cached data packet for the EFI DHCPv4 Protocol driver. + + The GetModeData() function returns the current operating mode and cached data + packet for the EFI DHCPv4 Protocol driver. + + @param This The pointer to the EFI_DHCP4_PROTOCOL instance. + @param Dhcp4ModeData The pointer to storage for the EFI_DHCP4_MODE_DATA structure. + + @retval EFI_SUCCESS The mode data was returned. + @retval EFI_INVALID_PARAMETER This is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP4_GET_MODE_DATA)( + IN EFI_DHCP4_PROTOCOL *This, + OUT EFI_DHCP4_MODE_DATA *Dhcp4ModeData + ); + +/** + Initializes, changes, or resets the operational settings for the EFI DHCPv4 Protocol driver. + + The Configure() function is used to initialize, change, or reset the operational + settings of the EFI DHCPv4 Protocol driver for the communication device on which + the EFI DHCPv4 Service Binding Protocol is installed. This function can be + successfully called only if both of the following are true: + * This instance of the EFI DHCPv4 Protocol driver is in the Dhcp4Stopped, Dhcp4Init, + Dhcp4InitReboot, or Dhcp4Bound states. + * No other EFI DHCPv4 Protocol driver instance that is controlled by this EFI + DHCPv4 Service Binding Protocol driver instance has configured this EFI DHCPv4 + Protocol driver. + When this driver is in the Dhcp4Stopped state, it can transfer into one of the + following two possible initial states: + * Dhcp4Init + * Dhcp4InitReboot. + The driver can transfer into these states by calling Configure() with a non-NULL + Dhcp4CfgData. The driver will transfer into the appropriate state based on the + supplied client network address in the ClientAddress parameter and DHCP options + in the OptionList parameter as described in RFC 2131. + When Configure() is called successfully while Dhcp4CfgData is set to NULL, the + default configuring data will be reset in the EFI DHCPv4 Protocol driver and + the state of the EFI DHCPv4 Protocol driver will not be changed. If one instance + wants to make it possible for another instance to configure the EFI DHCPv4 Protocol + driver, it must call this function with Dhcp4CfgData set to NULL. + + @param This The pointer to the EFI_DHCP4_PROTOCOL instance. + @param Dhcp4CfgData The pointer to the EFI_DHCP4_CONFIG_DATA. + + @retval EFI_SUCCESS The EFI DHCPv4 Protocol driver is now in the Dhcp4Init or + Dhcp4InitReboot state, if the original state of this driver + was Dhcp4Stopped, Dhcp4Init,Dhcp4InitReboot, or Dhcp4Bound + and the value of Dhcp4CfgData was not NULL. + Otherwise, the state was left unchanged. + @retval EFI_ACCESS_DENIED This instance of the EFI DHCPv4 Protocol driver was not in the + Dhcp4Stopped, Dhcp4Init, Dhcp4InitReboot, or Dhcp4Bound state; + Or onother instance of this EFI DHCPv4 Protocol driver is already + in a valid configured state. + @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE: + This is NULL. + DiscoverTryCount > 0 and DiscoverTimeout is NULL + RequestTryCount > 0 and RequestTimeout is NULL. + OptionCount >0 and OptionList is NULL. + ClientAddress is not a valid unicast address. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP4_CONFIGURE)( + IN EFI_DHCP4_PROTOCOL *This, + IN EFI_DHCP4_CONFIG_DATA *Dhcp4CfgData OPTIONAL + ); + +/** + Starts the DHCP configuration process. + + The Start() function starts the DHCP configuration process. This function can + be called only when the EFI DHCPv4 Protocol driver is in the Dhcp4Init or + Dhcp4InitReboot state. + If the DHCP process completes successfully, the state of the EFI DHCPv4 Protocol + driver will be transferred through Dhcp4Selecting and Dhcp4Requesting to the + Dhcp4Bound state. The CompletionEvent will then be signaled if it is not NULL. + If the process aborts, either by the user or by some unexpected network error, + the state is restored to the Dhcp4Init state. The Start() function can be called + again to restart the process. + Refer to RFC 2131 for precise state transitions during this process. At the + time when each event occurs in this process, the callback function that was set + by EFI_DHCP4_PROTOCOL.Configure() will be called and the user can take this + opportunity to control the process. + + @param This The pointer to the EFI_DHCP4_PROTOCOL instance. + @param CompletionEvent If not NULL, it indicates the event that will be signaled when the + EFI DHCPv4 Protocol driver is transferred into the + Dhcp4Bound state or when the DHCP process is aborted. + EFI_DHCP4_PROTOCOL.GetModeData() can be called to + check the completion status. If NULL, + EFI_DHCP4_PROTOCOL.Start() will wait until the driver + is transferred into the Dhcp4Bound state or the process fails. + + @retval EFI_SUCCESS The DHCP configuration process has started, or it has completed + when CompletionEvent is NULL. + @retval EFI_NOT_STARTED The EFI DHCPv4 Protocol driver is in the Dhcp4Stopped + state. EFI_DHCP4_PROTOCOL. Configure() needs to be called. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_TIMEOUT The DHCP configuration process failed because no response was + received from the server within the specified timeout value. + @retval EFI_ABORTED The user aborted the DHCP process. + @retval EFI_ALREADY_STARTED Some other EFI DHCPv4 Protocol instance already started the + DHCP process. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_NO_MEDIA There was a media error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP4_START)( + IN EFI_DHCP4_PROTOCOL *This, + IN EFI_EVENT CompletionEvent OPTIONAL + ); + +/** + Extends the lease time by sending a request packet. + + The RenewRebind() function is used to manually extend the lease time when the + EFI DHCPv4 Protocol driver is in the Dhcp4Bound state, and the lease time has + not expired yet. This function will send a request packet to the previously + found server (or to any server when RebindRequest is TRUE) and transfer the + state into the Dhcp4Renewing state (or Dhcp4Rebinding when RebindingRequest is + TRUE). When a response is received, the state is returned to Dhcp4Bound. + If no response is received before the try count is exceeded (the RequestTryCount + field that is specified in EFI_DHCP4_CONFIG_DATA) but before the lease time that + was issued by the previous server expires, the driver will return to the Dhcp4Bound + state, and the previous configuration is restored. The outgoing and incoming packets + can be captured by the EFI_DHCP4_CALLBACK function. + + @param This The pointer to the EFI_DHCP4_PROTOCOL instance. + @param RebindRequest If TRUE, this function broadcasts the request packets and enters + the Dhcp4Rebinding state. Otherwise, it sends a unicast + request packet and enters the Dhcp4Renewing state. + @param CompletionEvent If not NULL, this event is signaled when the renew/rebind phase + completes or some error occurs. + EFI_DHCP4_PROTOCOL.GetModeData() can be called to + check the completion status. If NULL, + EFI_DHCP4_PROTOCOL.RenewRebind() will busy-wait + until the DHCP process finishes. + + @retval EFI_SUCCESS The EFI DHCPv4 Protocol driver is now in the + Dhcp4Renewing state or is back to the Dhcp4Bound state. + @retval EFI_NOT_STARTED The EFI DHCPv4 Protocol driver is in the Dhcp4Stopped + state. EFI_DHCP4_PROTOCOL.Configure() needs to + be called. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_TIMEOUT There was no response from the server when the try count was + exceeded. + @retval EFI_ACCESS_DENIED The driver is not in the Dhcp4Bound state. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP4_RENEW_REBIND)( + IN EFI_DHCP4_PROTOCOL *This, + IN BOOLEAN RebindRequest, + IN EFI_EVENT CompletionEvent OPTIONAL + ); + +/** + Releases the current address configuration. + + The Release() function releases the current configured IP address by doing either + of the following: + * Sending a DHCPRELEASE packet when the EFI DHCPv4 Protocol driver is in the + Dhcp4Bound state + * Setting the previously assigned IP address that was provided with the + EFI_DHCP4_PROTOCOL.Configure() function to 0.0.0.0 when the driver is in + Dhcp4InitReboot state + After a successful call to this function, the EFI DHCPv4 Protocol driver returns + to the Dhcp4Init state, and any subsequent incoming packets will be discarded silently. + + @param This The pointer to the EFI_DHCP4_PROTOCOL instance. + + @retval EFI_SUCCESS The EFI DHCPv4 Protocol driver is now in the Dhcp4Init phase. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_ACCESS_DENIED The EFI DHCPv4 Protocol driver is not Dhcp4InitReboot state. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP4_RELEASE)( + IN EFI_DHCP4_PROTOCOL *This + ); + +/** + Stops the current address configuration. + + The Stop() function is used to stop the DHCP configuration process. After this + function is called successfully, the EFI DHCPv4 Protocol driver is transferred + into the Dhcp4Stopped state. EFI_DHCP4_PROTOCOL.Configure() needs to be called + before DHCP configuration process can be started again. This function can be + called when the EFI DHCPv4 Protocol driver is in any state. + + @param This The pointer to the EFI_DHCP4_PROTOCOL instance. + + @retval EFI_SUCCESS The EFI DHCPv4 Protocol driver is now in the Dhcp4Stopped phase. + @retval EFI_INVALID_PARAMETER This is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP4_STOP)( + IN EFI_DHCP4_PROTOCOL *This + ); + +/** + Builds a DHCP packet, given the options to be appended or deleted or replaced. + + The Build() function is used to assemble a new packet from the original packet + by replacing or deleting existing options or appending new options. This function + does not change any state of the EFI DHCPv4 Protocol driver and can be used at + any time. + + @param This The pointer to the EFI_DHCP4_PROTOCOL instance. + @param SeedPacket Initial packet to be used as a base for building new packet. + @param DeleteCount Number of opcodes in the DeleteList. + @param DeleteList List of opcodes to be deleted from the seed packet. + Ignored if DeleteCount is zero. + @param AppendCount Number of entries in the OptionList. + @param AppendList The pointer to a DHCP option list to be appended to SeedPacket. + If SeedPacket also contains options in this list, they are + replaced by new options (except pad option). Ignored if + AppendCount is zero. Type EFI_DHCP4_PACKET_OPTION + @param NewPacket The pointer to storage for the pointer to the new allocated packet. + Use the EFI Boot Service FreePool() on the resulting pointer + when done with the packet. + + @retval EFI_SUCCESS The new packet was built. + @retval EFI_OUT_OF_RESOURCES Storage for the new packet could not be allocated. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + SeedPacket is NULL. + SeedPacket is not a well-formed DHCP packet. + AppendCount is not zero and AppendList is NULL. + DeleteCount is not zero and DeleteList is NULL. + NewPacket is NULL + Both DeleteCount and AppendCount are zero and + NewPacket is not NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP4_BUILD)( + IN EFI_DHCP4_PROTOCOL *This, + IN EFI_DHCP4_PACKET *SeedPacket, + IN UINT32 DeleteCount, + IN UINT8 *DeleteList OPTIONAL, + IN UINT32 AppendCount, + IN EFI_DHCP4_PACKET_OPTION *AppendList[] OPTIONAL, + OUT EFI_DHCP4_PACKET **NewPacket + ); + +/** + Transmits a DHCP formatted packet and optionally waits for responses. + + The TransmitReceive() function is used to transmit a DHCP packet and optionally + wait for the response from servers. This function does not change the state of + the EFI DHCPv4 Protocol driver. It can be used at any time because of this. + + @param This The pointer to the EFI_DHCP4_PROTOCOL instance. + @param Token The pointer to the EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN structure. + + @retval EFI_SUCCESS The packet was successfully queued for transmission. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + Token.RemoteAddress is zero. + Token.Packet is NULL. + Token.Packet is not a well-formed DHCP packet. + The transaction ID in Token.Packet is in use by another DHCP process. + @retval EFI_NOT_READY The previous call to this function has not finished yet. Try to call + this function after collection process completes. + @retval EFI_NO_MAPPING The default station address is not available yet. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_UNSUPPORTED The implementation doesn't support this function + @retval Others Some other unexpected error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP4_TRANSMIT_RECEIVE)( + IN EFI_DHCP4_PROTOCOL *This, + IN EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token + ); + +/** + Parses the packed DHCP option data. + + The Parse() function is used to retrieve the option list from a DHCP packet. + If *OptionCount isn't zero, and there is enough space for all the DHCP options + in the Packet, each element of PacketOptionList is set to point to somewhere in + the Packet->Dhcp4.Option where a new DHCP option begins. If RFC3396 is supported, + the caller should reassemble the parsed DHCP options to get the final result. + If *OptionCount is zero or there isn't enough space for all of them, the number + of DHCP options in the Packet is returned in OptionCount. + + @param This The pointer to the EFI_DHCP4_PROTOCOL instance. + @param Packet The pointer to packet to be parsed. + @param OptionCount On input, the number of entries in the PacketOptionList. + On output, the number of entries that were written into the + PacketOptionList. + @param PacketOptionList A list of packet option entries to be filled in. End option or pad + options are not included. + + @retval EFI_SUCCESS The packet was successfully parsed. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + The packet is NULL. + The packet is not a well-formed DHCP packet. + OptionCount is NULL. + @retval EFI_BUFFER_TOO_SMALL One or more of the following conditions is TRUE: + 1) *OptionCount is smaller than the number of options that + were found in the Packet. + 2) PacketOptionList is NULL. + @retval EFI_OUT_OF_RESOURCE The packet failed to parse because of a resource shortage. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP4_PARSE)( + IN EFI_DHCP4_PROTOCOL *This, + IN EFI_DHCP4_PACKET *Packet, + IN OUT UINT32 *OptionCount, + OUT EFI_DHCP4_PACKET_OPTION *PacketOptionList[] OPTIONAL + ); + +/// +/// This protocol is used to collect configuration information for the EFI IPv4 Protocol drivers +/// and to provide DHCPv4 server and PXE boot server discovery services. +/// +struct _EFI_DHCP4_PROTOCOL { + EFI_DHCP4_GET_MODE_DATA GetModeData; + EFI_DHCP4_CONFIGURE Configure; + EFI_DHCP4_START Start; + EFI_DHCP4_RENEW_REBIND RenewRebind; + EFI_DHCP4_RELEASE Release; + EFI_DHCP4_STOP Stop; + EFI_DHCP4_BUILD Build; + EFI_DHCP4_TRANSMIT_RECEIVE TransmitReceive; + EFI_DHCP4_PARSE Parse; +}; + +extern EFI_GUID gEfiDhcp4ProtocolGuid; +extern EFI_GUID gEfiDhcp4ServiceBindingProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Dhcp6.h b/sys/contrib/edk2/Include/Protocol/Dhcp6.h new file mode 100644 index 000000000000..5672353ffd05 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Dhcp6.h @@ -0,0 +1,780 @@ +/** @file + UEFI Dynamic Host Configuration Protocol 6 Definition, which is used to get IPv6 + addresses and other configuration parameters from DHCPv6 servers. + + Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.2 + +**/ + +#ifndef __EFI_DHCP6_PROTOCOL_H__ +#define __EFI_DHCP6_PROTOCOL_H__ + +#define EFI_DHCP6_PROTOCOL_GUID \ + { \ + 0x87c8bad7, 0x595, 0x4053, {0x82, 0x97, 0xde, 0xde, 0x39, 0x5f, 0x5d, 0x5b } \ + } + +#define EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0x9fb9a8a1, 0x2f4a, 0x43a6, {0x88, 0x9c, 0xd0, 0xf7, 0xb6, 0xc4, 0x7a, 0xd5 } \ + } + +typedef struct _EFI_DHCP6_PROTOCOL EFI_DHCP6_PROTOCOL; + +typedef enum { + /// + /// The EFI DHCPv6 Protocol instance is configured, and start() needs + /// to be called + /// + Dhcp6Init = 0x0, + /// + /// A Solicit packet is sent out to discover DHCPv6 server, and the EFI + /// DHCPv6 Protocol instance is collecting Advertise packets. + /// + Dhcp6Selecting = 0x1, + /// + /// A Request is sent out to the DHCPv6 server, and the EFI DHCPv6 + /// Protocol instance is waiting for Reply packet. + /// + Dhcp6Requesting = 0x2, + /// + /// A Decline packet is sent out to indicate one or more addresses of the + /// configured IA are in use by another node, and the EFI DHCPv6. + /// Protocol instance is waiting for Reply packet. + /// + Dhcp6Declining = 0x3, + /// + /// A Confirm packet is sent out to confirm the IPv6 addresses of the + /// configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet. + /// + Dhcp6Confirming = 0x4, + /// + /// A Release packet is sent out to release one or more IPv6 addresses of + /// the configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet. + /// + Dhcp6Releasing = 0x5, + /// + /// The DHCPv6 S.A.R.R process is completed for the configured IA. + /// + Dhcp6Bound = 0x6, + /// + /// A Renew packet is sent out to extend lifetime for the IPv6 addresses of + /// the configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet. + /// + Dhcp6Renewing = 0x7, + /// + /// A Rebind packet is sent out to extend lifetime for the IPv6 addresses of + /// the configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet. + /// + Dhcp6Rebinding = 0x8 +} EFI_DHCP6_STATE; + +typedef enum { + /// + /// A Solicit packet is about to be sent. The packet is passed to Dhcp6Callback and + /// can be modified or replaced in Dhcp6Callback. + /// + Dhcp6SendSolicit = 0x0, + /// + /// An Advertise packet is received and will be passed to Dhcp6Callback. + /// + Dhcp6RcvdAdvertise = 0x1, + /// + /// It is time for Dhcp6Callback to determine whether select the default Advertise + /// packet by RFC 3315 policy, or overwrite it by specific user policy. + /// + Dhcp6SelectAdvertise = 0x2, + /// + /// A Request packet is about to be sent. The packet is passed to Dhcp6Callback and + /// can be modified or replaced in Dhcp6Callback. + /// + Dhcp6SendRequest = 0x3, + /// + /// A Reply packet is received and will be passed to Dhcp6Callback. + /// + Dhcp6RcvdReply = 0x4, + /// + /// A Reconfigure packet is received and will be passed to Dhcp6Callback. + /// + Dhcp6RcvdReconfigure = 0x5, + /// + /// A Decline packet is about to be sent. The packet is passed to Dhcp6Callback and + /// can be modified or replaced in Dhcp6Callback. + /// + Dhcp6SendDecline = 0x6, + /// + /// A Confirm packet is about to be sent. The packet is passed to Dhcp6Callback and + /// can be modified or replaced in Dhcp6Callback. + /// + Dhcp6SendConfirm = 0x7, + /// + /// A Release packet is about to be sent. The packet is passed to Dhcp6Callback and + /// can be modified or replaced in Dhcp6Callback. + /// + Dhcp6SendRelease = 0x8, + /// + /// A Renew packet is about to be sent. The packet is passed to Dhcp6Callback and + /// can be modified or replaced in Dhcp6Callback. + /// + Dhcp6EnterRenewing = 0x9, + /// + /// A Rebind packet is about to be sent. The packet is passed to Dhcp6Callback and + /// can be modified or replaced in Dhcp6Callback. + /// + Dhcp6EnterRebinding = 0xa +} EFI_DHCP6_EVENT; + +/// +/// An IA which carries assigned not temporary address. +/// +#define EFI_DHCP6_IA_TYPE_NA 3 +/// +/// An IA which carries assigned temporary address. +/// +#define EFI_DHCP6_IA_TYPE_TA 4 + +#pragma pack(1) +/// +/// EFI_DHCP6_PACKET_OPTION +/// defines the format of the DHCPv6 option, See RFC 3315 for more information. +/// This data structure is used to reference option data that is packed in the DHCPv6 packet. +/// +typedef struct { + /// + /// The DHCPv6 option code, stored in network order. + /// + UINT16 OpCode; + /// + /// Length of the DHCPv6 option data, stored in network order. + /// From the first byte to the last byte of the Data field. + /// + UINT16 OpLen; + /// + /// The data for the DHCPv6 option, stored in network order. + /// + UINT8 Data[1]; +} EFI_DHCP6_PACKET_OPTION; + +/// +/// EFI_DHCP6_HEADER +/// defines the format of the DHCPv6 header. See RFC 3315 for more information. +/// +typedef struct { + /// + /// The DHCPv6 transaction ID. + /// + UINT32 MessageType : 8; + /// + /// The DHCPv6 message type. + /// + UINT32 TransactionId : 24; +} EFI_DHCP6_HEADER; + +/// +/// EFI_DHCP6_PACKET +/// defines the format of the DHCPv6 packet. See RFC 3315 for more information. +/// +typedef struct { + /// + /// Size of the EFI_DHCP6_PACKET buffer. + /// + UINT32 Size; + /// + /// Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last + /// byte of the Option[] field. + /// + UINT32 Length; + struct { + /// + /// The DHCPv6 packet header. + /// + EFI_DHCP6_HEADER Header; + /// + /// Start of the DHCPv6 packed option data. + /// + UINT8 Option[1]; + } Dhcp6; +} EFI_DHCP6_PACKET; + +#pragma pack() + +typedef struct { + /// + /// Length of DUID in octects. + /// + UINT16 Length; + /// + /// Array of DUID octects. + /// + UINT8 Duid[1]; +} EFI_DHCP6_DUID; + +typedef struct { + /// + /// Initial retransmission timeout. + /// + UINT32 Irt; + /// + /// Maximum retransmission count for one packet. If Mrc is zero, there's no upper limit + /// for retransmission count. + /// + UINT32 Mrc; + /// + /// Maximum retransmission timeout for each retry. It's the upper bound of the number of + /// retransmission timeout. If Mrt is zero, there is no upper limit for retransmission + /// timeout. + /// + UINT32 Mrt; + /// + /// Maximum retransmission duration for one packet. It's the upper bound of the numbers + /// the client may retransmit a message. If Mrd is zero, there's no upper limit for + /// retransmission duration. + /// + UINT32 Mrd; +} EFI_DHCP6_RETRANSMISSION; + +typedef struct { + /// + /// The IPv6 address. + /// + EFI_IPv6_ADDRESS IpAddress; + /// + /// The preferred lifetime in unit of seconds for the IPv6 address. + /// + UINT32 PreferredLifetime; + /// + /// The valid lifetime in unit of seconds for the IPv6 address. + /// + UINT32 ValidLifetime; +} EFI_DHCP6_IA_ADDRESS; + +typedef struct { + UINT16 Type; ///< Type for an IA. + UINT32 IaId; ///< The identifier for an IA. +} EFI_DHCP6_IA_DESCRIPTOR; + +typedef struct { + /// + /// The descriptor for IA. + /// + EFI_DHCP6_IA_DESCRIPTOR Descriptor; + /// + /// The state of the configured IA. + /// + EFI_DHCP6_STATE State; + /// + /// Pointer to the cached latest Reply packet. May be NULL if no packet is cached. + /// + EFI_DHCP6_PACKET *ReplyPacket; + /// + /// Number of IPv6 addresses of the configured IA. + /// + UINT32 IaAddressCount; + /// + /// List of the IPv6 addresses of the configured IA. When the state of the configured IA is + /// in Dhcp6Bound, Dhcp6Renewing and Dhcp6Rebinding, the IPv6 addresses are usable. + /// + EFI_DHCP6_IA_ADDRESS IaAddress[1]; +} EFI_DHCP6_IA; + +typedef struct { + /// + /// Pointer to the DHCPv6 unique identifier. The caller is responsible for freeing this buffer. + /// + EFI_DHCP6_DUID *ClientId; + /// + /// Pointer to the configured IA of current instance. The caller can free this buffer after + /// using it. + /// + EFI_DHCP6_IA *Ia; +} EFI_DHCP6_MODE_DATA; + +/** + EFI_DHCP6_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol instance to + intercept events that occurs in the DHCPv6 S.A.R.R process. + + @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance that is used to configure this + callback function. + @param[in] Context Pointer to the context that is initialized by EFI_DHCP6_PROTOCOL.Configure(). + @param[in] CurrentState The current state of the configured IA. + @param[in] Dhcp6Event The event that occurs in the current state, which usually means a state transition. + @param[in] Packet Pointer to the DHCPv6 packet that is about to be sent or has been received. + The EFI DHCPv6 Protocol instance is responsible for freeing the buffer. + @param[out] NewPacket Pointer to the new DHCPv6 packet to overwrite the Packet. NewPacket can not + share the buffer with Packet. If *NewPacket is not NULL, the EFI DHCPv6 + Protocol instance is responsible for freeing the buffer. + + @retval EFI_SUCCESS Tell the EFI DHCPv6 Protocol instance to continue the DHCPv6 S.A.R.R process. + @retval EFI_ABORTED Tell the EFI DHCPv6 Protocol instance to abort the DHCPv6 S.A.R.R process, + and the state of the configured IA will be transferred to Dhcp6Init. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP6_CALLBACK)( + IN EFI_DHCP6_PROTOCOL *This, + IN VOID *Context, + IN EFI_DHCP6_STATE CurrentState, + IN EFI_DHCP6_EVENT Dhcp6Event, + IN EFI_DHCP6_PACKET *Packet, + OUT EFI_DHCP6_PACKET **NewPacket OPTIONAL + ); + +typedef struct { + /// + /// The callback function is to intercept various events that occur in the DHCPv6 S.A.R.R + /// process. Set to NULL to ignore all those events. + /// + EFI_DHCP6_CALLBACK Dhcp6Callback; + /// + /// Pointer to the context that will be passed to Dhcp6Callback. + /// + VOID *CallbackContext; + /// + /// Number of the DHCPv6 options in the OptionList. + /// + UINT32 OptionCount; + /// + /// List of the DHCPv6 options to be included in Solicit and Request packet. The buffer + /// can be freed after EFI_DHCP6_PROTOCOL.Configure() returns. Ignored if + /// OptionCount is zero. OptionList should not contain Client Identifier option + /// and any IA option, which will be appended by EFI DHCPv6 Protocol instance + /// automatically. + /// + EFI_DHCP6_PACKET_OPTION **OptionList; + /// + /// The descriptor for the IA of the EFI DHCPv6 Protocol instance. + /// + EFI_DHCP6_IA_DESCRIPTOR IaDescriptor; + /// + /// If not NULL, the event will be signaled when any IPv6 address information of the + /// configured IA is updated, including IPv6 address, preferred lifetime and valid + /// lifetime, or the DHCPv6 S.A.R.R process fails. Otherwise, Start(), + /// renewrebind(), decline(), release() and stop() will be blocking + /// operations, and they will wait for the exchange process completion or failure. + /// + EFI_EVENT IaInfoEvent; + /// + /// If TRUE, the EFI DHCPv6 Protocol instance is willing to accept Reconfigure packet. + /// Otherwise, it will ignore it. Reconfigure Accept option can not be specified through + /// OptionList parameter. + /// + BOOLEAN ReconfigureAccept; + /// + /// If TRUE, the EFI DHCPv6 Protocol instance will send Solicit packet with Rapid + /// Commit option. Otherwise, Rapid Commit option will not be included in Solicit + /// packet. Rapid Commit option can not be specified through OptionList parameter. + /// + BOOLEAN RapidCommit; + /// + /// Parameter to control Solicit packet retransmission behavior. The + /// buffer can be freed after EFI_DHCP6_PROTOCOL.Configure() returns. + /// + EFI_DHCP6_RETRANSMISSION *SolicitRetransmission; +} EFI_DHCP6_CONFIG_DATA; + +/** + EFI_DHCP6_INFO_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol + instance to intercept events that occurs in the DHCPv6 Information Request exchange process. + + @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance that is used to configure this + callback function. + @param[in] Context Pointer to the context that is initialized in the EFI_DHCP6_PROTOCOL.InfoRequest(). + @param[in] Packet Pointer to Reply packet that has been received. The EFI DHCPv6 Protocol instance is + responsible for freeing the buffer. + + @retval EFI_SUCCESS Tell the EFI DHCPv6 Protocol instance to finish Information Request exchange process. + @retval EFI_NOT_READY Tell the EFI DHCPv6 Protocol instance to continue Information Request exchange process. + @retval EFI_ABORTED Tell the EFI DHCPv6 Protocol instance to abort the Information Request exchange process. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP6_INFO_CALLBACK)( + IN EFI_DHCP6_PROTOCOL *This, + IN VOID *Context, + IN EFI_DHCP6_PACKET *Packet + ); + +/** + Retrieve the current operating mode data and configuration data for the EFI DHCPv6 Protocol instance. + + @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. + @param[out] Dhcp6ModeData Pointer to the DHCPv6 mode data structure. The caller is responsible for freeing this + structure and each reference buffer. + @param[out] Dhcp6ConfigData Pointer to the DHCPv6 configuration data structure. The caller is responsible for + freeing this structure and each reference buffer. + + @retval EFI_SUCCESS The mode data was returned. + @retval EFI_ACCESS_DENIED The EFI DHCPv6 Protocol instance has not been configured when Dhcp6ConfigData is not NULL. + @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE: + - This is NULL. + - Both Dhcp6ConfigData and Dhcp6ModeData are NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP6_GET_MODE_DATA)( + IN EFI_DHCP6_PROTOCOL *This, + OUT EFI_DHCP6_MODE_DATA *Dhcp6ModeData OPTIONAL, + OUT EFI_DHCP6_CONFIG_DATA *Dhcp6ConfigData OPTIONAL + ); + +/** + Initialize or clean up the configuration data for the EFI DHCPv6 Protocol instance. + + The Configure() function is used to initialize or clean up the configuration data of the EFI + DHCPv6 Protocol instance. + - When Dhcp6CfgData is not NULL and Configure() is called successfully, the + configuration data will be initialized in the EFI DHCPv6 Protocol instance and the state of the + configured IA will be transferred into Dhcp6Init. + - When Dhcp6CfgData is NULL and Configure() is called successfully, the configuration + data will be cleaned up and no IA will be associated with the EFI DHCPv6 Protocol instance. + + To update the configuration data for an EFI DCHPv6 Protocol instance, the original data must be + cleaned up before setting the new configuration data. + + @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. + @param[in] Dhcp6CfgData Pointer to the DHCPv6 configuration data structure. + + @retval EFI_SUCCESS The mode data was returned. + @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE + - This is NULL. + - OptionCount > 0 and OptionList is NULL. + - OptionList is not NULL, and Client Id option, Reconfigure Accept option, + Rapid Commit option or any IA option is specified in the OptionList. + - IaDescriptor.Type is neither EFI_DHCP6_IA_TYPE_NA nor EFI_DHCP6_IA_TYPE_NA. + - IaDescriptor is not unique. + - Both IaInfoEvent and SolicitRetransimssion are NULL. + - SolicitRetransmission is not NULL, and both SolicitRetransimssion->Mrc and + SolicitRetransmission->Mrd are zero. + @retval EFI_ACCESS_DENIED The EFI DHCPv6 Protocol instance has been already configured + when Dhcp6CfgData is not NULL. + The EFI DHCPv6 Protocol instance has already started the + DHCPv6 S.A.R.R when Dhcp6CfgData is NULL. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP6_CONFIGURE)( + IN EFI_DHCP6_PROTOCOL *This, + IN EFI_DHCP6_CONFIG_DATA *Dhcp6CfgData OPTIONAL + ); + +/** + Start the DHCPv6 S.A.R.R process. + + The Start() function starts the DHCPv6 S.A.R.R process. This function can be called only when + the state of the configured IA is in the Dhcp6Init state. If the DHCPv6 S.A.R.R process completes + successfully, the state of the configured IA will be transferred through Dhcp6Selecting and + Dhcp6Requesting to Dhcp6Bound state. The update of the IPv6 addresses will be notified through + EFI_DHCP6_CONFIG_DATA.IaInfoEvent. At the time when each event occurs in this process, the + callback function set by EFI_DHCP6_PROTOCOL.Configure() will be called and the user can take + this opportunity to control the process. If EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, the + Start() function call is a blocking operation. It will return after the DHCPv6 S.A.R.R process + completes or aborted by users. If the process is aborted by system or network error, the state of + the configured IA will be transferred to Dhcp6Init. The Start() function can be called again to + restart the process. + + @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. + + @retval EFI_SUCCESS The DHCPv6 S.A.R.R process is completed and at least one IPv6 + address has been bound to the configured IA when + EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL. + The DHCPv6 S.A.R.R process is started when + EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL. + @retval EFI_ACCESS_DENIED The EFI DHCPv6 Child instance hasn't been configured. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_ALREADY_STARTED The DHCPv6 S.A.R.R process has already started. + @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. + @retval EFI_NO_RESPONSE The DHCPv6 S.A.R.R process failed because of no response. + @retval EFI_NO_MAPPING No IPv6 address has been bound to the configured IA after the + DHCPv6 S.A.R.R process. + @retval EFI_ABORTED The DHCPv6 S.A.R.R process aborted by user. + @retval EFI_NO_MEDIA There was a media error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP6_START)( + IN EFI_DHCP6_PROTOCOL *This + ); + +/** + Request configuration information without the assignment of any IA addresses of the client. + + The InfoRequest() function is used to request configuration information without the assignment + of any IPv6 address of the client. Client sends out Information Request packet to obtain + the required configuration information, and DHCPv6 server responds with Reply packet containing + the information for the client. The received Reply packet will be passed to the user by + ReplyCallback function. If user returns EFI_NOT_READY from ReplyCallback, the EFI DHCPv6 + Protocol instance will continue to receive other Reply packets unless timeout according to + the Retransmission parameter. Otherwise, the Information Request exchange process will be + finished successfully if user returns EFI_SUCCESS from ReplyCallback. + + @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. + @param[in] SendClientId If TRUE, the EFI DHCPv6 Protocol instance will build Client + Identifier option and include it into Information Request + packet. If FALSE, Client Identifier option will not be included. + Client Identifier option can not be specified through OptionList + parameter. + @param[in] OptionRequest Pointer to the Option Request option in the Information Request + packet. Option Request option can not be specified through + OptionList parameter. + @param[in] OptionCount Number of options in OptionList. + @param[in] OptionList List of other DHCPv6 options. These options will be appended + to the Option Request option. The caller is responsible for + freeing this buffer. Type is defined in EFI_DHCP6_PROTOCOL.GetModeData(). + @param[in] Retransmission Parameter to control Information Request packet retransmission + behavior. The buffer can be freed after EFI_DHCP6_PROTOCOL.InfoRequest() + returns. + @param[in] TimeoutEvent If not NULL, this event is signaled when the information request + exchange aborted because of no response. If NULL, the function + call is a blocking operation; and it will return after the + information-request exchange process finish or aborted by users. + @param[in] ReplyCallback The callback function is to intercept various events that occur + in the Information Request exchange process. It should not be + set to NULL. + @param[in] CallbackContext Pointer to the context that will be passed to ReplyCallback. + + @retval EFI_SUCCESS The DHCPv6 S.A.R.R process is completed and at least one IPv6 + @retval EFI_SUCCESS The DHCPv6 information request exchange process completed + when TimeoutEvent is NULL. Information Request packet has been + sent to DHCPv6 server when TimeoutEvent is not NULL. + @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE: + - This is NULL. + - OptionRequest is NULL or OptionRequest->OpCode is invalid. + - OptionCount > 0 and OptionList is NULL. + - OptionList is not NULL, and Client Identify option or + Option Request option is specified in the OptionList. + - Retransimssion is NULL. + - Both Retransimssion->Mrc and Retransmission->Mrd are zero. + - ReplyCallback is NULL. + @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. + @retval EFI_NO_RESPONSE The DHCPv6 information request exchange process failed + because of no response, or not all requested-options are + responded by DHCPv6 servers when Timeout happened. + @retval EFI_ABORTED The DHCPv6 information request exchange process aborted by user. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP6_INFO_REQUEST)( + IN EFI_DHCP6_PROTOCOL *This, + IN BOOLEAN SendClientId, + IN EFI_DHCP6_PACKET_OPTION *OptionRequest, + IN UINT32 OptionCount, + IN EFI_DHCP6_PACKET_OPTION *OptionList[] OPTIONAL, + IN EFI_DHCP6_RETRANSMISSION *Retransmission, + IN EFI_EVENT TimeoutEvent OPTIONAL, + IN EFI_DHCP6_INFO_CALLBACK ReplyCallback, + IN VOID *CallbackContext OPTIONAL + ); + +/** + Manually extend the valid and preferred lifetimes for the IPv6 addresses of the configured + IA and update other configuration parameters by sending Renew or Rebind packet. + + The RenewRebind() function is used to manually extend the valid and preferred lifetimes for the + IPv6 addresses of the configured IA and update other configuration parameters by sending Renew or + Rebind packet. + - When RebindRequest is FALSE and the state of the configured IA is Dhcp6Bound, it + will send Renew packet to the previously DHCPv6 server and transfer the state of the configured + IA to Dhcp6Renewing. If valid Reply packet received, the state transfers to Dhcp6Bound + and the valid and preferred timer restarts. If fails, the state transfers to Dhcp6Bound but the + timer continues. + - When RebindRequest is TRUE and the state of the configured IA is Dhcp6Bound, it will + send Rebind packet. If valid Reply packet received, the state transfers to Dhcp6Bound and the + valid and preferred timer restarts. If fails, the state transfers to Dhcp6Init and the IA can't + be used. + + @param[in] This Pointer to the EFI_DHCP4_PROTOCOL instance. + @param[in] RebindRequest If TRUE, it will send Rebind packet and enter the Dhcp6Rebinding state. + Otherwise, it will send Renew packet and enter the Dhcp6Renewing state. + + @retval EFI_SUCCESS The DHCPv6 renew/rebind exchange process has completed and at + least one IPv6 address of the configured IA has been bound again + when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL. + The EFI DHCPv6 Protocol instance has sent Renew or Rebind packet + when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL. + @retval EFI_ACCESS_DENIED The EFI DHCPv6 Child instance hasn't been configured, or the state + of the configured IA is not in Dhcp6Bound. + @retval EFI_ALREADY_STARTED The state of the configured IA has already entered Dhcp6Renewing + when RebindRequest is FALSE. + The state of the configured IA has already entered Dhcp6Rebinding + when RebindRequest is TRUE. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or system error occurred. + @retval EFI_NO_RESPONSE The DHCPv6 renew/rebind exchange process failed because of no response. + @retval EFI_NO_MAPPING No IPv6 address has been bound to the configured IA after the DHCPv6 + renew/rebind exchange process. + @retval EFI_ABORTED The DHCPv6 renew/rebind exchange process aborted by user. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP6_RENEW_REBIND)( + IN EFI_DHCP6_PROTOCOL *This, + IN BOOLEAN RebindRequest + ); + +/** + Inform that one or more IPv6 addresses assigned by a server are already in use by + another node. + + The Decline() function is used to manually decline the assignment of IPv6 addresses, which + have been already used by another node. If all IPv6 addresses of the configured IA are declined + through this function, the state of the IA will switch through Dhcp6Declining to Dhcp6Init, + otherwise, the state of the IA will restore to Dhcp6Bound after the declining process. The + Decline() can only be called when the IA is in Dhcp6Bound state. If the + EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, this function is a blocking operation. It + will return after the declining process finishes, or aborted by user. + + @param[in] This Pointer to the EFI_DHCP4_PROTOCOL instance. + @param[in] AddressCount Number of declining IPv6 addresses. + @param[in] Addresses Pointer to the buffer stored all the declining IPv6 addresses. + + @retval EFI_SUCCESS The DHCPv6 decline exchange process has completed when + EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL. + The EFI DHCPv6 Protocol instance has sent Decline packet when + EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL. + @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE + - This is NULL. + - AddressCount is zero or Addresses is NULL. + @retval EFI_NOT_FOUND Any specified IPv6 address is not correlated with the configured IA + for this instance. + @retval EFI_ACCESS_DENIED The EFI DHCPv6 Child instance hasn't been configured, or the + state of the configured IA is not in Dhcp6Bound. + @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. + @retval EFI_ABORTED The DHCPv6 decline exchange process aborted by user. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP6_DECLINE)( + IN EFI_DHCP6_PROTOCOL *This, + IN UINT32 AddressCount, + IN EFI_IPv6_ADDRESS *Addresses + ); + +/** + Release one or more IPv6 addresses associated with the configured IA for current instance. + + The Release() function is used to manually release the one or more IPv6 address. If AddressCount + is zero, it will release all IPv6 addresses of the configured IA. If all IPv6 addresses of the IA + are released through this function, the state of the IA will switch through Dhcp6Releasing to + Dhcp6Init, otherwise, the state of the IA will restore to Dhcp6Bound after the releasing process. + The Release() can only be called when the IA is in Dhcp6Bound state. If the + EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, the function is a blocking operation. It will return + after the releasing process finishes, or aborted by user. + + @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. + @param[in] AddressCount Number of releasing IPv6 addresses. + @param[in] Addresses Pointer to the buffer stored all the releasing IPv6 addresses. + Ignored if AddressCount is zero. + @retval EFI_SUCCESS The DHCPv6 release exchange process has completed when + EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL. + The EFI DHCPv6 Protocol instance has sent Release packet when + EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL. + @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE + - This is NULL. + - AddressCount is not zero or Addresses is NULL. + @retval EFI_NOT_FOUND Any specified IPv6 address is not correlated with the configured + IA for this instance. + @retval EFI_ACCESS_DENIED The EFI DHCPv6 Child instance hasn't been configured, or the + state of the configured IA is not in Dhcp6Bound. + @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. + @retval EFI_ABORTED The DHCPv6 release exchange process aborted by user. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP6_RELEASE)( + IN EFI_DHCP6_PROTOCOL *This, + IN UINT32 AddressCount, + IN EFI_IPv6_ADDRESS *Addresses + ); + +/** + Stop the DHCPv6 S.A.R.R process. + + The Stop() function is used to stop the DHCPv6 S.A.R.R process. If this function is called + successfully, all the IPv6 addresses of the configured IA will be released and the state of + the configured IA will be transferred to Dhcp6Init. + + @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. + + @retval EFI_SUCCESS The DHCPv6 S.A.R.R process has been stopped when + EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL. + The EFI DHCPv6 Protocol instance has sent Release packet if + need release or has been stopped if needn't, when + EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL. + @retval EFI_INVALID_PARAMETER This is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP6_STOP)( + IN EFI_DHCP6_PROTOCOL *This + ); + +/** + Parse the option data in the DHCPv6 packet. + + The Parse() function is used to retrieve the option list in the DHCPv6 packet. + + @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance. + + @param[in] Packet Pointer to packet to be parsed. + @param[in] OptionCount On input, the number of entries in the PacketOptionList. + On output, the number of DHCPv6 options in the Packet. + @param[in] PacketOptionList List of pointers to the DHCPv6 options in the Packet. + The OpCode and OpLen in EFI_DHCP6_PACKET_OPTION are + both stored in network byte order. + @retval EFI_SUCCESS The packet was successfully parsed. + @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE + - This is NULL. + - Packet is NULL. + - Packet is not a well-formed DHCPv6 packet. + - OptionCount is NULL. + - *OptionCount is not zero and PacketOptionList is NULL. + @retval EFI_BUFFER_TOO_SMALL *OptionCount is smaller than the number of options that were + found in the Packet. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DHCP6_PARSE)( + IN EFI_DHCP6_PROTOCOL *This, + IN EFI_DHCP6_PACKET *Packet, + IN OUT UINT32 *OptionCount, + OUT EFI_DHCP6_PACKET_OPTION *PacketOptionList[] OPTIONAL + ); + +/// +/// The EFI DHCPv6 Protocol is used to get IPv6 addresses and other configuration parameters +/// from DHCPv6 servers. +/// +struct _EFI_DHCP6_PROTOCOL { + EFI_DHCP6_GET_MODE_DATA GetModeData; + EFI_DHCP6_CONFIGURE Configure; + EFI_DHCP6_START Start; + EFI_DHCP6_INFO_REQUEST InfoRequest; + EFI_DHCP6_RENEW_REBIND RenewRebind; + EFI_DHCP6_DECLINE Decline; + EFI_DHCP6_RELEASE Release; + EFI_DHCP6_STOP Stop; + EFI_DHCP6_PARSE Parse; +}; + +extern EFI_GUID gEfiDhcp6ProtocolGuid; +extern EFI_GUID gEfiDhcp6ServiceBindingProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/DiskInfo.h b/sys/contrib/edk2/Include/Protocol/DiskInfo.h new file mode 100644 index 000000000000..69f559da99fd --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/DiskInfo.h @@ -0,0 +1,221 @@ +/** @file + Provides the basic interfaces to abstract platform information regarding an + IDE controller. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is defined in UEFI Platform Initialization Specification 1.6 + Volume 5: Standards + +**/ + +#ifndef __DISK_INFO_H__ +#define __DISK_INFO_H__ + +/// +/// Global ID for EFI_DISK_INFO_PROTOCOL +/// +#define EFI_DISK_INFO_PROTOCOL_GUID \ + { \ + 0xd432a67f, 0x14dc, 0x484b, {0xb3, 0xbb, 0x3f, 0x2, 0x91, 0x84, 0x93, 0x27 } \ + } + +/// +/// Forward declaration for EFI_DISK_INFO_PROTOCOL +/// +typedef struct _EFI_DISK_INFO_PROTOCOL EFI_DISK_INFO_PROTOCOL; + +/// +/// Global ID for an IDE interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface +/// +#define EFI_DISK_INFO_IDE_INTERFACE_GUID \ + { \ + 0x5e948fe3, 0x26d3, 0x42b5, {0xaf, 0x17, 0x61, 0x2, 0x87, 0x18, 0x8d, 0xec } \ + } + +/// +/// Global ID for a SCSI interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface +/// +#define EFI_DISK_INFO_SCSI_INTERFACE_GUID \ + { \ + 0x8f74baa, 0xea36, 0x41d9, {0x95, 0x21, 0x21, 0xa7, 0xf, 0x87, 0x80, 0xbc } \ + } + +/// +/// Global ID for a USB interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface +/// +#define EFI_DISK_INFO_USB_INTERFACE_GUID \ + { \ + 0xcb871572, 0xc11a, 0x47b5, {0xb4, 0x92, 0x67, 0x5e, 0xaf, 0xa7, 0x77, 0x27 } \ + } + +/// +/// Global ID for an AHCI interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface +/// +#define EFI_DISK_INFO_AHCI_INTERFACE_GUID \ + { \ + 0x9e498932, 0x4abc, 0x45af, {0xa3, 0x4d, 0x2, 0x47, 0x78, 0x7b, 0xe7, 0xc6 } \ + } + +/// +/// Global ID for a NVME interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface +/// +#define EFI_DISK_INFO_NVME_INTERFACE_GUID \ + { \ + 0x3ab14680, 0x5d3f, 0x4a4d, {0xbc, 0xdc, 0xcc, 0x38, 0x0, 0x18, 0xc7, 0xf7 } \ + } + +/// +/// Global ID for a UFS interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface +/// +#define EFI_DISK_INFO_UFS_INTERFACE_GUID \ + { \ + 0x4b3029cc, 0x6b98, 0x47fb, { 0xbc, 0x96, 0x76, 0xdc, 0xb8, 0x4, 0x41, 0xf0 } \ + } + +/// +/// Global ID for an SD/MMC interface. Used to fill in EFI_DISK_INFO_PROTOCOL.Interface +/// +#define EFI_DISK_INFO_SD_MMC_INTERFACE_GUID \ + { \ + 0x8deec992, 0xd39c, 0x4a5c, { 0xab, 0x6b, 0x98, 0x6e, 0x14, 0x24, 0x2b, 0x9d } \ + } + +/** + Provides inquiry information for the controller type. + + This function is used by the IDE bus driver to get inquiry data. Data format + of Identify data is defined by the Interface GUID. + + @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. + @param[in,out] InquiryData Pointer to a buffer for the inquiry data. + @param[in,out] InquiryDataSize Pointer to the value for the inquiry data size. + + @retval EFI_SUCCESS The command was accepted without any errors. + @retval EFI_NOT_FOUND Device does not support this data class + @retval EFI_DEVICE_ERROR Error reading InquiryData from device + @retval EFI_BUFFER_TOO_SMALL InquiryDataSize not big enough + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_INFO_INQUIRY)( + IN EFI_DISK_INFO_PROTOCOL *This, + IN OUT VOID *InquiryData, + IN OUT UINT32 *InquiryDataSize + ); + +/** + Provides identify information for the controller type. + + This function is used by the IDE bus driver to get identify data. Data format + of Identify data is defined by the Interface GUID. + + @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL + instance. + @param[in,out] IdentifyData Pointer to a buffer for the identify data. + @param[in,out] IdentifyDataSize Pointer to the value for the identify data + size. + + @retval EFI_SUCCESS The command was accepted without any errors. + @retval EFI_NOT_FOUND Device does not support this data class + @retval EFI_DEVICE_ERROR Error reading IdentifyData from device + @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_INFO_IDENTIFY)( + IN EFI_DISK_INFO_PROTOCOL *This, + IN OUT VOID *IdentifyData, + IN OUT UINT32 *IdentifyDataSize + ); + +/** + Provides sense data information for the controller type. + + This function is used by the IDE bus driver to get sense data. + Data format of Sense data is defined by the Interface GUID. + + @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. + @param[in,out] SenseData Pointer to the SenseData. + @param[in,out] SenseDataSize Size of SenseData in bytes. + @param[out] SenseDataNumber Pointer to the value for the sense data size. + + @retval EFI_SUCCESS The command was accepted without any errors. + @retval EFI_NOT_FOUND Device does not support this data class. + @retval EFI_DEVICE_ERROR Error reading SenseData from device. + @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_INFO_SENSE_DATA)( + IN EFI_DISK_INFO_PROTOCOL *This, + IN OUT VOID *SenseData, + IN OUT UINT32 *SenseDataSize, + OUT UINT8 *SenseDataNumber + ); + +/** + This function is used by the IDE bus driver to get controller information. + + @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. + @param[out] IdeChannel Pointer to the Ide Channel number. Primary or secondary. + @param[out] IdeDevice Pointer to the Ide Device number. Master or slave. + + @retval EFI_SUCCESS IdeChannel and IdeDevice are valid. + @retval EFI_UNSUPPORTED This is not an IDE device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_INFO_WHICH_IDE)( + IN EFI_DISK_INFO_PROTOCOL *This, + OUT UINT32 *IdeChannel, + OUT UINT32 *IdeDevice + ); + +/// +/// The EFI_DISK_INFO_PROTOCOL provides controller specific information. +/// +struct _EFI_DISK_INFO_PROTOCOL { + /// + /// A GUID that defines the format of buffers for the other member functions + /// of this protocol. + /// + EFI_GUID Interface; + /// + /// Return the results of the Inquiry command to a drive in InquiryData. Data + /// format of Inquiry data is defined by the Interface GUID. + /// + EFI_DISK_INFO_INQUIRY Inquiry; + /// + /// Return the results of the Identify command to a drive in IdentifyData. Data + /// format of Identify data is defined by the Interface GUID. + /// + EFI_DISK_INFO_IDENTIFY Identify; + /// + /// Return the results of the Request Sense command to a drive in SenseData. Data + /// format of Sense data is defined by the Interface GUID. + /// + EFI_DISK_INFO_SENSE_DATA SenseData; + /// + /// Specific controller. + /// + EFI_DISK_INFO_WHICH_IDE WhichIde; +}; + +extern EFI_GUID gEfiDiskInfoProtocolGuid; + +extern EFI_GUID gEfiDiskInfoIdeInterfaceGuid; +extern EFI_GUID gEfiDiskInfoScsiInterfaceGuid; +extern EFI_GUID gEfiDiskInfoUsbInterfaceGuid; +extern EFI_GUID gEfiDiskInfoAhciInterfaceGuid; +extern EFI_GUID gEfiDiskInfoNvmeInterfaceGuid; +extern EFI_GUID gEfiDiskInfoUfsInterfaceGuid; +extern EFI_GUID gEfiDiskInfoSdMmcInterfaceGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/DiskIo.h b/sys/contrib/edk2/Include/Protocol/DiskIo.h new file mode 100644 index 000000000000..0fea8774c4c9 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/DiskIo.h @@ -0,0 +1,111 @@ +/** @file + Disk IO protocol as defined in the UEFI 2.0 specification. + + The Disk IO protocol is used to convert block oriented devices into byte + oriented devices. The Disk IO protocol is intended to layer on top of the + Block IO protocol. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __DISK_IO_H__ +#define __DISK_IO_H__ + +#define EFI_DISK_IO_PROTOCOL_GUID \ + { \ + 0xce345171, 0xba0b, 0x11d2, {0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +/// +/// Protocol GUID name defined in EFI1.1. +/// +#define DISK_IO_PROTOCOL EFI_DISK_IO_PROTOCOL_GUID + +typedef struct _EFI_DISK_IO_PROTOCOL EFI_DISK_IO_PROTOCOL; + +/// +/// Protocol defined in EFI1.1. +/// +typedef EFI_DISK_IO_PROTOCOL EFI_DISK_IO; + +/** + Read BufferSize bytes from Offset into Buffer. + + @param This Protocol instance pointer. + @param MediaId Id of the media, changes every time the media is replaced. + @param Offset The starting byte offset to read from + @param BufferSize Size of Buffer + @param Buffer Buffer containing read data + + @retval EFI_SUCCESS The data was read correctly from the device. + @retval EFI_DEVICE_ERROR The device reported an error while performing the read. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not + valid for the device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_READ)( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +/** + Writes a specified number of bytes to a device. + + @param This Indicates a pointer to the calling context. + @param MediaId ID of the medium to be written. + @param Offset The starting byte offset on the logical block I/O device to write. + @param BufferSize The size in bytes of Buffer. The number of bytes to write to the device. + @param Buffer A pointer to the buffer containing the data to be written. + + @retval EFI_SUCCESS The data was written correctly to the device. + @retval EFI_WRITE_PROTECTED The device can not be written to. + @retval EFI_DEVICE_ERROR The device reported an error while performing the write. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not + valid for the device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_WRITE)( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +#define EFI_DISK_IO_PROTOCOL_REVISION 0x00010000 + +/// +/// Revision defined in EFI1.1 +/// +#define EFI_DISK_IO_INTERFACE_REVISION EFI_DISK_IO_PROTOCOL_REVISION + +/// +/// This protocol is used to abstract Block I/O interfaces. +/// +struct _EFI_DISK_IO_PROTOCOL { + /// + /// The revision to which the disk I/O interface adheres. All future + /// revisions must be backwards compatible. If a future version is not + /// backwards compatible, it is not the same GUID. + /// + UINT64 Revision; + EFI_DISK_READ ReadDisk; + EFI_DISK_WRITE WriteDisk; +}; + +extern EFI_GUID gEfiDiskIoProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/DriverBinding.h b/sys/contrib/edk2/Include/Protocol/DriverBinding.h new file mode 100644 index 000000000000..327e46d72129 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/DriverBinding.h @@ -0,0 +1,195 @@ +/** @file + UEFI DriverBinding Protocol is defined in UEFI specification. + + This protocol is produced by every driver that follows the UEFI Driver Model, + and it is the central component that allows drivers and controllers to be managed. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_DRIVER_BINDING_H__ +#define __EFI_DRIVER_BINDING_H__ + +/// +/// The global ID for the ControllerHandle Driver Protocol. +/// +#define EFI_DRIVER_BINDING_PROTOCOL_GUID \ + { \ + 0x18a031ab, 0xb443, 0x4d1a, {0xa5, 0xc0, 0xc, 0x9, 0x26, 0x1e, 0x9f, 0x71 } \ + } + +typedef struct _EFI_DRIVER_BINDING_PROTOCOL EFI_DRIVER_BINDING_PROTOCOL; + +/** + Tests to see if this driver supports a given controller. If a child device is provided, + it further tests to see if this driver supports creating a handle for the specified child device. + + This function checks to see if the driver specified by This supports the device specified by + ControllerHandle. Drivers will typically use the device path attached to + ControllerHandle and/or the services from the bus I/O abstraction attached to + ControllerHandle to determine if the driver supports ControllerHandle. This function + may be called many times during platform initialization. In order to reduce boot times, the tests + performed by this function must be very small, and take as little time as possible to execute. This + function must not change the state of any hardware devices, and this function must be aware that the + device specified by ControllerHandle may already be managed by the same driver or a + different driver. This function must match its calls to AllocatePages() with FreePages(), + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). + Because ControllerHandle may have been previously started by the same driver, if a protocol is + already in the opened state, then it must not be closed with CloseProtocol(). This is required + to guarantee the state of ControllerHandle is not modified by this function. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to test. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For bus drivers, if this parameter is not NULL, then + the bus driver must determine if the bus controller specified + by ControllerHandle and the child controller specified + by RemainingDevicePath are both supported by this + bus driver. + + @retval EFI_SUCCESS The device specified by ControllerHandle and + RemainingDevicePath is supported by the driver specified by This. + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + Currently not implemented. + @retval EFI_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DRIVER_BINDING_SUPPORTED)( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + Starts a device controller or a bus controller. + + The Start() function is designed to be invoked from the EFI boot service ConnectController(). + As a result, much of the error checking on the parameters to Start() has been moved into this + common boot service. It is legal to call Start() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE. + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned + EFI_DEVICE_PATH_PROTOCOL. + 3. Prior to calling Start(), the Supported() function for the driver specified by This must + have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS The device was started. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failded to start the device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DRIVER_BINDING_START)( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + Stops a device controller or a bus controller. + + The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). + As a result, much of the error checking on the parameters to Stop() has been moved + into this common boot service. It is legal to call Stop() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this + same driver's Start() function. + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid + EFI_HANDLE. In addition, all of these handles must have been created in this driver's + Start() function, and the Start() function must have called OpenProtocol() on + ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle A handle to the device being stopped. The handle must + support a bus specific I/O protocol for the driver + to use to stop the device. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DRIVER_BINDING_STOP)( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); + +/// +/// This protocol provides the services required to determine if a driver supports a given controller. +/// If a controller is supported, then it also provides routines to start and stop the controller. +/// +struct _EFI_DRIVER_BINDING_PROTOCOL { + EFI_DRIVER_BINDING_SUPPORTED Supported; + EFI_DRIVER_BINDING_START Start; + EFI_DRIVER_BINDING_STOP Stop; + + /// + /// The version number of the UEFI driver that produced the + /// EFI_DRIVER_BINDING_PROTOCOL. This field is used by + /// the EFI boot service ConnectController() to determine + /// the order that driver's Supported() service will be used when + /// a controller needs to be started. EFI Driver Binding Protocol + /// instances with higher Version values will be used before ones + /// with lower Version values. The Version values of 0x0- + /// 0x0f and 0xfffffff0-0xffffffff are reserved for + /// platform/OEM specific drivers. The Version values of 0x10- + /// 0xffffffef are reserved for IHV-developed drivers. + /// + UINT32 Version; + + /// + /// The image handle of the UEFI driver that produced this instance + /// of the EFI_DRIVER_BINDING_PROTOCOL. + /// + EFI_HANDLE ImageHandle; + + /// + /// The handle on which this instance of the + /// EFI_DRIVER_BINDING_PROTOCOL is installed. In most + /// cases, this is the same handle as ImageHandle. However, for + /// UEFI drivers that produce more than one instance of the + /// EFI_DRIVER_BINDING_PROTOCOL, this value may not be + /// the same as ImageHandle. + /// + EFI_HANDLE DriverBindingHandle; +}; + +extern EFI_GUID gEfiDriverBindingProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/DriverConfiguration2.h b/sys/contrib/edk2/Include/Protocol/DriverConfiguration2.h new file mode 100644 index 000000000000..6424b30a2321 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/DriverConfiguration2.h @@ -0,0 +1,184 @@ +/** @file + UEFI Driver Configuration2 Protocol + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_DRIVER_CONFIGURATION2_H__ +#define __EFI_DRIVER_CONFIGURATION2_H__ + +/// +/// Global ID for the Driver Configuration Protocol defined in UEFI 2.0 +/// +#define EFI_DRIVER_CONFIGURATION2_PROTOCOL_GUID \ + { \ + 0xbfd7dc1d, 0x24f1, 0x40d9, {0x82, 0xe7, 0x2e, 0x09, 0xbb, 0x6b, 0x4e, 0xbe } \ + } + +typedef struct _EFI_DRIVER_CONFIGURATION2_PROTOCOL EFI_DRIVER_CONFIGURATION2_PROTOCOL; + +typedef enum { + /// + /// The controller is still in a usable state. No actions + /// are required before this controller can be used again. + /// + EfiDriverConfigurationActionNone = 0, + /// + /// The driver has detected that the controller is not in a + /// usable state, and it needs to be stopped. + /// + EfiDriverConfigurationActionStopController = 1, + /// + /// This controller needs to be stopped and restarted + /// before it can be used again. + /// + EfiDriverConfigurationActionRestartController = 2, + /// + /// A configuration change has been made that requires the platform to be restarted before + /// the controller can be used again. + /// + EfiDriverConfigurationActionRestartPlatform = 3, + EfiDriverConfigurationActionMaximum +} EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED; + +#define EFI_DRIVER_CONFIGURATION_SAFE_DEFAULTS 0x00000000 +#define EFI_DRIVER_CONFIGURATION_MANUFACTURING_DEFAULTS 0x00000001 +#define EFI_DRIVER_CONFIGURATION_CUSTOM_DEFAULTS 0x00000002 +#define EFI_DRIVER_CONFIGURATION_PERORMANCE_DEFAULTS 0x00000003 + +/** + Allows the user to set controller specific options for a controller that a + driver is currently managing. + + @param This A pointer to the EFI_DRIVER_CONFIGURATION2_PROTOCOL instance. + @param ControllerHandle The handle of the controller to set options on. + @param ChildHandle The handle of the child controller to set options on. This + is an optional parameter that may be NULL. It will be NULL + for device drivers, and for bus drivers that wish to set + options for the bus controller. It will not be NULL for a + bus driver that wishes to set options for one of its child + controllers. + @param Language A Null-terminated ASCII string that contains one or more RFC 4646 + language codes. This is the list of language codes that this + protocol supports. The number of languages + supported by a driver is up to the driver writer. + @param ActionRequired A pointer to the action that the calling agent is required + to perform when this function returns. See "Related + Definitions" for a list of the actions that the calling + agent is required to perform prior to accessing + ControllerHandle again. + + @retval EFI_SUCCESS The driver specified by This successfully set the + configuration options for the controller specified + by ControllerHandle. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ActionRequired is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support setting + configuration options for the controller specified by + ControllerHandle and ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + @retval EFI_DEVICE_ERROR A device error occurred while attempting to set the + configuration options for the controller specified + by ControllerHandle and ChildHandle. + @retval EFI_OUT_RESOURCES There are not enough resources available to set the + configuration options for the controller specified + by ControllerHandle and ChildHandle. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DRIVER_CONFIGURATION2_SET_OPTIONS)( + IN EFI_DRIVER_CONFIGURATION2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired + ); + +/** + Tests to see if a controller's current configuration options are valid. + + @param This A pointer to the EFI_DRIVER_CONFIGURATION2_PROTOCOL instance. + @param ControllerHandle The handle of the controller to test if it's current + configuration options are valid. + @param ChildHandle The handle of the child controller to test if it's current + configuration options are valid. This is an optional + parameter that may be NULL. It will be NULL for device + drivers. It will also be NULL for bus drivers that wish + to test the configuration options for the bus controller. + It will not be NULL for a bus driver that wishes to test + configuration options for one of its child controllers. + + @retval EFI_SUCCESS The controller specified by ControllerHandle and + ChildHandle that is being managed by the driver + specified by This has a valid set of configuration + options. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by ControllerHandle + and ChildHandle. + @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and + ChildHandle that is being managed by the driver + specified by This has an invalid set of configuration + options. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DRIVER_CONFIGURATION2_OPTIONS_VALID)( + IN EFI_DRIVER_CONFIGURATION2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL + ); + +/** + Forces a driver to set the default configuration options for a controller. + + @param This A pointer to the EFI_DRIVER_CONFIGURATION2_PROTOCOL instance. + @param ControllerHandle The handle of the controller to force default configuration options on. + @param ChildHandle The handle of the child controller to force default configuration options on This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for bus drivers that wish to force default configuration options for the bus controller. It will not be NULL for a bus driver that wishes to force default configuration options for one of its child controllers. + @param DefaultType The type of default configuration options to force on the controller specified by ControllerHandle and ChildHandle. See Table 9-1 for legal values. A DefaultType of 0x00000000 must be supported by this protocol. + @param ActionRequired A pointer to the action that the calling agent is required to perform when this function returns. See "Related Definitions" in Section 9.1 for a list of the actions that the calling agent is required to perform prior to accessing ControllerHandle again. + + @retval EFI_SUCCESS The driver specified by This successfully forced the default configuration options on the controller specified by ControllerHandle and ChildHandle. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ActionRequired is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support forcing the default configuration options on the controller specified by ControllerHandle and ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the configuration type specified by DefaultType. + @retval EFI_DEVICE_ERROR A device error occurred while attempt to force the default configuration options on the controller specified by ControllerHandle and ChildHandle. + @retval EFI_OUT_RESOURCES There are not enough resources available to force the default configuration options on the controller specified by ControllerHandle and ChildHandle. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DRIVER_CONFIGURATION2_FORCE_DEFAULTS)( + IN EFI_DRIVER_CONFIGURATION2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN UINT32 DefaultType, + OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired + ); + +/// +/// Used to set configuration options for a controller that an EFI Driver is managing. +/// +struct _EFI_DRIVER_CONFIGURATION2_PROTOCOL { + EFI_DRIVER_CONFIGURATION2_SET_OPTIONS SetOptions; + EFI_DRIVER_CONFIGURATION2_OPTIONS_VALID OptionsValid; + EFI_DRIVER_CONFIGURATION2_FORCE_DEFAULTS ForceDefaults; + /// + /// A Null-terminated ASCII string that contains one or more RFC 4646 + /// language codes. This is the list of language codes that this protocol supports. + /// + CHAR8 *SupportedLanguages; +}; + +extern EFI_GUID gEfiDriverConfiguration2ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/DriverDiagnostics.h b/sys/contrib/edk2/Include/Protocol/DriverDiagnostics.h new file mode 100644 index 000000000000..e628d0a2bba7 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/DriverDiagnostics.h @@ -0,0 +1,125 @@ +/** @file + EFI Driver Diagnostics Protocol + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_DRIVER_DIAGNOSTICS_H__ +#define __EFI_DRIVER_DIAGNOSTICS_H__ + +/// +/// The global ID for the Driver Diagnostics Protocol as defined in EFI 1.1. +/// +#define EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID \ + { \ + 0x0784924f, 0xe296, 0x11d4, {0x9a, 0x49, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +typedef struct _EFI_DRIVER_DIAGNOSTICS_PROTOCOL EFI_DRIVER_DIAGNOSTICS_PROTOCOL; + +typedef enum { + /// + /// Performs standard diagnostics on the controller. + /// + EfiDriverDiagnosticTypeStandard = 0, + /// + /// This is an optional diagnostic type that performs diagnostics on the controller that may + /// take an extended amount of time to execute. + /// + EfiDriverDiagnosticTypeExtended = 1, + /// + /// This is an optional diagnostic type that performs diagnostics on the controller that are + /// suitable for a manufacturing and test environment. + /// + EfiDriverDiagnosticTypeManufacturing = 2, + /// + /// This is an optional diagnostic type that would only be used in the situation where an + /// EFI_NOT_READY had been returned by a previous call to RunDiagnostics() + /// and there is a desire to cancel the current running diagnostics operation. + /// + EfiDriverDiagnosticTypeCancel = 3, + EfiDriverDiagnosticTypeMaximum +} EFI_DRIVER_DIAGNOSTIC_TYPE; + +/** + Runs diagnostics on a controller. + + @param This A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL instance. + @param ControllerHandle The handle of the controller to run diagnostics on. + @param ChildHandle The handle of the child controller to run diagnostics on + This is an optional parameter that may be NULL. It will + be NULL for device drivers. It will also be NULL for a + bus drivers that wish to run diagnostics on the bus + controller. It will not be NULL for a bus driver that + wishes to run diagnostics on one of its child controllers. + @param DiagnosticType Indicates type of diagnostics to perform on the controller + specified by ControllerHandle and ChildHandle. See + "Related Definitions" for the list of supported types. + @param Language A pointer to a three character ISO 639-2 language + identifier. This is the language in which the optional + error message should be returned in Buffer, and it must + match one of the languages specified in SupportedLanguages. + The number of languages supported by a driver is up to + the driver writer. + @param ErrorType A GUID that defines the format of the data returned in Buffer. + @param BufferSize The size, in bytes, of the data returned in Buffer. + @param Buffer A buffer that contains a Null-terminated string + plus some additional data whose format is defined by + ErrorType. Buffer is allocated by this function with + AllocatePool(), and it is the caller's responsibility + to free it with a call to FreePool(). + + @retval EFI_SUCCESS The controller specified by ControllerHandle and + ChildHandle passed the diagnostic. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ErrorType is NULL. + @retval EFI_INVALID_PARAMETER BufferType is NULL. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support + running diagnostics for the controller specified + by ControllerHandle and ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + type of diagnostic specified by DiagnosticType. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to complete + the diagnostics. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to return + the status information in ErrorType, BufferSize, + and Buffer. + @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and + ChildHandle did not pass the diagnostic. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DRIVER_DIAGNOSTICS_RUN_DIAGNOSTICS)( + IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType, + IN CHAR8 *Language, + OUT EFI_GUID **ErrorType, + OUT UINTN *BufferSize, + OUT CHAR16 **Buffer + ); + +/// +/// Used to perform diagnostics on a controller that an EFI Driver is managing. +/// +struct _EFI_DRIVER_DIAGNOSTICS_PROTOCOL { + EFI_DRIVER_DIAGNOSTICS_RUN_DIAGNOSTICS RunDiagnostics; + /// + /// A Null-terminated ASCII string that contains one or more ISO 639-2 + /// language codes. This is the list of language codes that this protocol supports. + /// + CHAR8 *SupportedLanguages; +}; + +extern EFI_GUID gEfiDriverDiagnosticsProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/DriverDiagnostics2.h b/sys/contrib/edk2/Include/Protocol/DriverDiagnostics2.h new file mode 100644 index 000000000000..ab48b0268623 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/DriverDiagnostics2.h @@ -0,0 +1,105 @@ +/** @file + UEFI Driver Diagnostics2 Protocol + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_DRIVER_DIAGNOSTICS2_H__ +#define __EFI_DRIVER_DIAGNOSTICS2_H__ + +#include <Protocol/DriverDiagnostics.h> + +#define EFI_DRIVER_DIAGNOSTICS2_PROTOCOL_GUID \ + { \ + 0x4d330321, 0x025f, 0x4aac, {0x90, 0xd8, 0x5e, 0xd9, 0x00, 0x17, 0x3b, 0x63 } \ + } + +typedef struct _EFI_DRIVER_DIAGNOSTICS2_PROTOCOL EFI_DRIVER_DIAGNOSTICS2_PROTOCOL; + +/** + Runs diagnostics on a controller. + + @param This A pointer to the EFI_DRIVER_DIAGNOSTICS2_PROTOCOL instance. + @param ControllerHandle The handle of the controller to run diagnostics on. + @param ChildHandle The handle of the child controller to run diagnostics on + This is an optional parameter that may be NULL. It will + be NULL for device drivers. It will also be NULL for + bus drivers that wish to run diagnostics on the bus + controller. It will not be NULL for a bus driver that + wishes to run diagnostics on one of its child controllers. + @param DiagnosticType Indicates the type of diagnostics to perform on the controller + specified by ControllerHandle and ChildHandle. See + "Related Definitions" for the list of supported types. + @param Language A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller + is requesting, and it must match one of the + languages specified in SupportedLanguages. + The number of languages supported by a + driver is up to the driver writer. Language + is specified in RFC 4646 language code format. + @param ErrorType A GUID that defines the format of the data returned in Buffer. + @param BufferSize The size, in bytes, of the data returned in Buffer. + @param Buffer A buffer that contains a Null-terminated Unicode string + plus some additional data whose format is defined by + ErrorType. Buffer is allocated by this function with + AllocatePool(), and it is the caller's responsibility + to free it with a call to FreePool(). + + @retval EFI_SUCCESS The controller specified by ControllerHandle and + ChildHandle passed the diagnostic. + @retval EFI_ACCESS_DENIED The request for initiating diagnostics was unable + to be complete due to some underlying hardware or + software state. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ErrorType is NULL. + @retval EFI_INVALID_PARAMETER BufferType is NULL. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support + running diagnostics for the controller specified + by ControllerHandle and ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + type of diagnostic specified by DiagnosticType. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to complete + the diagnostics. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to return + the status information in ErrorType, BufferSize, + and Buffer. + @retval EFI_DEVICE_ERROR The controller specified by ControllerHandle and + ChildHandle did not pass the diagnostic. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS)( + IN EFI_DRIVER_DIAGNOSTICS2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType, + IN CHAR8 *Language, + OUT EFI_GUID **ErrorType, + OUT UINTN *BufferSize, + OUT CHAR16 **Buffer + ); + +/// +/// Used to perform diagnostics on a controller that an EFI Driver is managing. +/// +struct _EFI_DRIVER_DIAGNOSTICS2_PROTOCOL { + EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS RunDiagnostics; + /// + /// A Null-terminated ASCII string that contains one or more RFC 4646 + /// language codes. This is the list of language codes that this protocol supports. + /// + CHAR8 *SupportedLanguages; +}; + +extern EFI_GUID gEfiDriverDiagnostics2ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Ebc.h b/sys/contrib/edk2/Include/Protocol/Ebc.h new file mode 100644 index 000000000000..d21bcfcba906 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Ebc.h @@ -0,0 +1,308 @@ +/** @file + Describes the protocol interface to the EBC interpreter. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_EBC_PROTOCOL_H__ +#define __EFI_EBC_PROTOCOL_H__ + +#define EFI_EBC_INTERPRETER_PROTOCOL_GUID \ + { \ + 0x13AC6DD1, 0x73D0, 0x11D4, {0xB0, 0x6B, 0x00, 0xAA, 0x00, 0xBD, 0x6D, 0xE7 } \ + } + +// +// Define OPCODES +// +#define OPCODE_BREAK 0x00 +#define OPCODE_JMP 0x01 +#define OPCODE_JMP8 0x02 +#define OPCODE_CALL 0x03 +#define OPCODE_RET 0x04 +#define OPCODE_CMPEQ 0x05 +#define OPCODE_CMPLTE 0x06 +#define OPCODE_CMPGTE 0x07 +#define OPCODE_CMPULTE 0x08 +#define OPCODE_CMPUGTE 0x09 +#define OPCODE_NOT 0x0A +#define OPCODE_NEG 0x0B +#define OPCODE_ADD 0x0C +#define OPCODE_SUB 0x0D +#define OPCODE_MUL 0x0E +#define OPCODE_MULU 0x0F +#define OPCODE_DIV 0x10 +#define OPCODE_DIVU 0x11 +#define OPCODE_MOD 0x12 +#define OPCODE_MODU 0x13 +#define OPCODE_AND 0x14 +#define OPCODE_OR 0x15 +#define OPCODE_XOR 0x16 +#define OPCODE_SHL 0x17 +#define OPCODE_SHR 0x18 +#define OPCODE_ASHR 0x19 +#define OPCODE_EXTNDB 0x1A +#define OPCODE_EXTNDW 0x1B +#define OPCODE_EXTNDD 0x1C +#define OPCODE_MOVBW 0x1D +#define OPCODE_MOVWW 0x1E +#define OPCODE_MOVDW 0x1F +#define OPCODE_MOVQW 0x20 +#define OPCODE_MOVBD 0x21 +#define OPCODE_MOVWD 0x22 +#define OPCODE_MOVDD 0x23 +#define OPCODE_MOVQD 0x24 +#define OPCODE_MOVSNW 0x25 // Move signed natural with word index +#define OPCODE_MOVSND 0x26 // Move signed natural with dword index +// +// #define OPCODE_27 0x27 +// +#define OPCODE_MOVQQ 0x28 // Does this go away? +#define OPCODE_LOADSP 0x29 +#define OPCODE_STORESP 0x2A +#define OPCODE_PUSH 0x2B +#define OPCODE_POP 0x2C +#define OPCODE_CMPIEQ 0x2D +#define OPCODE_CMPILTE 0x2E +#define OPCODE_CMPIGTE 0x2F +#define OPCODE_CMPIULTE 0x30 +#define OPCODE_CMPIUGTE 0x31 +#define OPCODE_MOVNW 0x32 +#define OPCODE_MOVND 0x33 +// +// #define OPCODE_34 0x34 +// +#define OPCODE_PUSHN 0x35 +#define OPCODE_POPN 0x36 +#define OPCODE_MOVI 0x37 +#define OPCODE_MOVIN 0x38 +#define OPCODE_MOVREL 0x39 + +// +// Bit masks for opcode encodings +// +#define OPCODE_M_OPCODE 0x3F // bits of interest for first level decode +#define OPCODE_M_IMMDATA 0x80 +#define OPCODE_M_IMMDATA64 0x40 +#define OPCODE_M_64BIT 0x40 // for CMP +#define OPCODE_M_RELADDR 0x10 // for CALL instruction +#define OPCODE_M_CMPI32_DATA 0x80 // for CMPI +#define OPCODE_M_CMPI64 0x40 // for CMPI 32 or 64 bit comparison +#define OPERAND_M_MOVIN_N 0x80 +#define OPERAND_M_CMPI_INDEX 0x10 + +// +// Masks for instructions that encode presence of indexes for operand1 and/or +// operand2. +// +#define OPCODE_M_IMMED_OP1 0x80 +#define OPCODE_M_IMMED_OP2 0x40 + +// +// Bit masks for operand encodings +// +#define OPERAND_M_INDIRECT1 0x08 +#define OPERAND_M_INDIRECT2 0x80 +#define OPERAND_M_OP1 0x07 +#define OPERAND_M_OP2 0x70 + +// +// Masks for data manipulation instructions +// +#define DATAMANIP_M_64 0x40 // 64-bit width operation +#define DATAMANIP_M_IMMDATA 0x80 + +// +// For MOV instructions, need a mask for the opcode when immediate +// data applies to R2. +// +#define OPCODE_M_IMMED_OP2 0x40 + +// +// The MOVI/MOVIn instructions use bit 6 of operands byte to indicate +// if an index is present. Then bits 4 and 5 are used to indicate the width +// of the move. +// +#define MOVI_M_IMMDATA 0x40 +#define MOVI_M_DATAWIDTH 0xC0 +#define MOVI_DATAWIDTH16 0x40 +#define MOVI_DATAWIDTH32 0x80 +#define MOVI_DATAWIDTH64 0xC0 +#define MOVI_M_MOVEWIDTH 0x30 +#define MOVI_MOVEWIDTH8 0x00 +#define MOVI_MOVEWIDTH16 0x10 +#define MOVI_MOVEWIDTH32 0x20 +#define MOVI_MOVEWIDTH64 0x30 + +// +// Masks for CALL instruction encodings +// +#define OPERAND_M_RELATIVE_ADDR 0x10 +#define OPERAND_M_NATIVE_CALL 0x20 + +// +// Masks for decoding push/pop instructions +// +#define PUSHPOP_M_IMMDATA 0x80 // opcode bit indicating immediate data +#define PUSHPOP_M_64 0x40 // opcode bit indicating 64-bit operation +// +// Mask for operand of JMP instruction +// +#define JMP_M_RELATIVE 0x10 +#define JMP_M_CONDITIONAL 0x80 +#define JMP_M_CS 0x40 + +// +// Macros to determine if a given operand is indirect +// +#define OPERAND1_INDIRECT(op) ((op) & OPERAND_M_INDIRECT1) +#define OPERAND2_INDIRECT(op) ((op) & OPERAND_M_INDIRECT2) + +// +// Macros to extract the operands from second byte of instructions +// +#define OPERAND1_REGNUM(op) ((op) & OPERAND_M_OP1) +#define OPERAND2_REGNUM(op) (((op) & OPERAND_M_OP2) >> 4) + +#define OPERAND1_CHAR(op) ('0' + OPERAND1_REGNUM (op)) +#define OPERAND2_CHAR(op) ('0' + OPERAND2_REGNUM (op)) + +// +// Condition masks usually for byte 1 encodings of code +// +#define CONDITION_M_CONDITIONAL 0x80 +#define CONDITION_M_CS 0x40 + +/// +/// Protocol Guid Name defined in spec. +/// +#define EFI_EBC_PROTOCOL_GUID EFI_EBC_INTERPRETER_PROTOCOL_GUID + +/// +/// Define for forward reference. +/// +typedef struct _EFI_EBC_PROTOCOL EFI_EBC_PROTOCOL; + +/** + Creates a thunk for an EBC entry point, returning the address of the thunk. + + A PE32+ EBC image, like any other PE32+ image, contains an optional header that specifies the + entry point for image execution. However, for EBC images, this is the entry point of EBC + instructions, so is not directly executable by the native processor. Therefore, when an EBC image is + loaded, the loader must call this service to get a pointer to native code (thunk) that can be executed, + which will invoke the interpreter to begin execution at the original EBC entry point. + + @param This A pointer to the EFI_EBC_PROTOCOL instance. + @param ImageHandle Handle of image for which the thunk is being created. + @param EbcEntryPoint Address of the actual EBC entry point or protocol service the thunk should call. + @param Thunk Returned pointer to a thunk created. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Image entry point is not 2-byte aligned. + @retval EFI_OUT_OF_RESOURCES Memory could not be allocated for the thunk. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_EBC_CREATE_THUNK)( + IN EFI_EBC_PROTOCOL *This, + IN EFI_HANDLE ImageHandle, + IN VOID *EbcEntryPoint, + OUT VOID **Thunk + ); + +/** + Called prior to unloading an EBC image from memory. + + This function is called after an EBC image has exited, but before the image is actually unloaded. It + is intended to provide the interpreter with the opportunity to perform any cleanup that may be + necessary as a result of loading and executing the image. + + @param This A pointer to the EFI_EBC_PROTOCOL instance. + @param ImageHandle Image handle of the EBC image that is being unloaded from memory. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Image handle is not recognized as belonging + to an EBC image that has been executed. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_EBC_UNLOAD_IMAGE)( + IN EFI_EBC_PROTOCOL *This, + IN EFI_HANDLE ImageHandle + ); + +/** + This is the prototype for the Flush callback routine. A pointer to a routine + of this type is passed to the EBC EFI_EBC_REGISTER_ICACHE_FLUSH protocol service. + + @param Start The beginning physical address to flush from the processor's instruction cache. + @param Length The number of bytes to flush from the processor's instruction cache. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EBC_ICACHE_FLUSH)( + IN EFI_PHYSICAL_ADDRESS Start, + IN UINT64 Length + ); + +/** + Registers a callback function that the EBC interpreter calls to flush + the processor instruction cache following creation of thunks. + + @param This A pointer to the EFI_EBC_PROTOCOL instance. + @param Flush Pointer to a function of type EBC_ICACH_FLUSH. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_EBC_REGISTER_ICACHE_FLUSH)( + IN EFI_EBC_PROTOCOL *This, + IN EBC_ICACHE_FLUSH Flush + ); + +/** + Called to get the version of the interpreter. + + This function is called to get the version of the loaded EBC interpreter. The value and format of the + returned version is identical to that returned by the EBC BREAK 1 instruction. + + @param This A pointer to the EFI_EBC_PROTOCOL instance. + @param Version Pointer to where to store the returned version of the interpreter. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Version pointer is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_EBC_GET_VERSION)( + IN EFI_EBC_PROTOCOL *This, + IN OUT UINT64 *Version + ); + +/// +/// The EFI EBC protocol provides services to load and execute EBC images, which will typically be +/// loaded into option ROMs. The image loader will load the EBC image, perform standard relocations, +/// and invoke the CreateThunk() service to create a thunk for the EBC image's entry point. The +/// image can then be run using the standard EFI start image services. +/// +struct _EFI_EBC_PROTOCOL { + EFI_EBC_CREATE_THUNK CreateThunk; + EFI_EBC_UNLOAD_IMAGE UnloadImage; + EFI_EBC_REGISTER_ICACHE_FLUSH RegisterICacheFlush; + EFI_EBC_GET_VERSION GetVersion; +}; + +// +// Extern the global EBC protocol GUID +// +extern EFI_GUID gEfiEbcProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/EdidActive.h b/sys/contrib/edk2/Include/Protocol/EdidActive.h new file mode 100644 index 000000000000..b96f86819f5e --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/EdidActive.h @@ -0,0 +1,46 @@ +/** @file + EDID Active Protocol from the UEFI 2.0 specification. + + Placed on the video output device child handle that is actively displaying output. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EDID_ACTIVE_H__ +#define __EDID_ACTIVE_H__ + +#define EFI_EDID_ACTIVE_PROTOCOL_GUID \ + { \ + 0xbd8c1056, 0x9f36, 0x44ec, {0x92, 0xa8, 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86 } \ + } + +/// +/// This protocol contains the EDID information for an active video output device. This is either the +/// EDID information retrieved from the EFI_EDID_OVERRIDE_PROTOCOL if an override is +/// available, or an identical copy of the EDID information from the +/// EFI_EDID_DISCOVERED_PROTOCOL if no overrides are available. +/// +typedef struct { + /// + /// The size, in bytes, of the Edid buffer. 0 if no EDID information + /// is available from the video output device. Otherwise, it must be a + /// minimum of 128 bytes. + /// + UINT32 SizeOfEdid; + + /// + /// A pointer to a read-only array of bytes that contains the EDID + /// information for an active video output device. This pointer is + /// NULL if no EDID information is available for the video output + /// device. The minimum size of a valid Edid buffer is 128 bytes. + /// EDID information is defined in the E-EDID EEPROM + /// specification published by VESA (www.vesa.org). + /// + UINT8 *Edid; +} EFI_EDID_ACTIVE_PROTOCOL; + +extern EFI_GUID gEfiEdidActiveProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/EdidDiscovered.h b/sys/contrib/edk2/Include/Protocol/EdidDiscovered.h new file mode 100644 index 000000000000..9b38c82310ce --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/EdidDiscovered.h @@ -0,0 +1,44 @@ +/** @file + EDID Discovered Protocol from the UEFI 2.0 specification. + + This protocol is placed on the video output device child handle. It represents + the EDID information being used for the output device represented by the child handle. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EDID_DISCOVERED_H__ +#define __EDID_DISCOVERED_H__ + +#define EFI_EDID_DISCOVERED_PROTOCOL_GUID \ + { \ + 0x1c0c34f6, 0xd380, 0x41fa, {0xa0, 0x49, 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa } \ + } + +/// +/// This protocol contains the EDID information retrieved from a video output device. +/// +typedef struct { + /// + /// The size, in bytes, of the Edid buffer. 0 if no EDID information + /// is available from the video output device. Otherwise, it must be a + /// minimum of 128 bytes. + /// + UINT32 SizeOfEdid; + + /// + /// A pointer to a read-only array of bytes that contains the EDID + /// information for an active video output device. This pointer is + /// NULL if no EDID information is available for the video output + /// device. The minimum size of a valid Edid buffer is 128 bytes. + /// EDID information is defined in the E-EDID EEPROM + /// specification published by VESA (www.vesa.org). + /// + UINT8 *Edid; +} EFI_EDID_DISCOVERED_PROTOCOL; + +extern EFI_GUID gEfiEdidDiscoveredProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/FirmwareVolume2.h b/sys/contrib/edk2/Include/Protocol/FirmwareVolume2.h new file mode 100644 index 000000000000..2b6c01b051a5 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/FirmwareVolume2.h @@ -0,0 +1,747 @@ +/** @file + The Firmware Volume Protocol provides file-level access to the firmware volume. + Each firmware volume driver must produce an instance of the + Firmware Volume Protocol if the firmware volume is to be visible to + the system during the DXE phase. The Firmware Volume Protocol also provides + mechanisms for determining and modifying some attributes of the firmware volume. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: PI + Version 1.00. + +**/ + +#ifndef __FIRMWARE_VOLUME2_H__ +#define __FIRMWARE_VOLUME2_H__ + +#define EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID \ + { 0x220e73b6, 0x6bdb, 0x4413, { 0x84, 0x5, 0xb9, 0x74, 0xb1, 0x8, 0x61, 0x9a } } + +typedef struct _EFI_FIRMWARE_VOLUME2_PROTOCOL EFI_FIRMWARE_VOLUME2_PROTOCOL; + +/// +/// EFI_FV_ATTRIBUTES +/// +typedef UINT64 EFI_FV_ATTRIBUTES; + +// +// EFI_FV_ATTRIBUTES bit definitions +// +// EFI_FV_ATTRIBUTES bit semantics +#define EFI_FV2_READ_DISABLE_CAP 0x0000000000000001ULL +#define EFI_FV2_READ_ENABLE_CAP 0x0000000000000002ULL +#define EFI_FV2_READ_STATUS 0x0000000000000004ULL +#define EFI_FV2_WRITE_DISABLE_CAP 0x0000000000000008ULL +#define EFI_FV2_WRITE_ENABLE_CAP 0x0000000000000010ULL +#define EFI_FV2_WRITE_STATUS 0x0000000000000020ULL +#define EFI_FV2_LOCK_CAP 0x0000000000000040ULL +#define EFI_FV2_LOCK_STATUS 0x0000000000000080ULL +#define EFI_FV2_WRITE_POLICY_RELIABLE 0x0000000000000100ULL +#define EFI_FV2_READ_LOCK_CAP 0x0000000000001000ULL +#define EFI_FV2_READ_LOCK_STATUS 0x0000000000002000ULL +#define EFI_FV2_WRITE_LOCK_CAP 0x0000000000004000ULL +#define EFI_FV2_WRITE_LOCK_STATUS 0x0000000000008000ULL +#define EFI_FV2_ALIGNMENT 0x00000000001F0000ULL +#define EFI_FV2_ALIGNMENT_1 0x0000000000000000ULL +#define EFI_FV2_ALIGNMENT_2 0x0000000000010000ULL +#define EFI_FV2_ALIGNMENT_4 0x0000000000020000ULL +#define EFI_FV2_ALIGNMENT_8 0x0000000000030000ULL +#define EFI_FV2_ALIGNMENT_16 0x0000000000040000ULL +#define EFI_FV2_ALIGNMENT_32 0x0000000000050000ULL +#define EFI_FV2_ALIGNMENT_64 0x0000000000060000ULL +#define EFI_FV2_ALIGNMENT_128 0x0000000000070000ULL +#define EFI_FV2_ALIGNMENT_256 0x0000000000080000ULL +#define EFI_FV2_ALIGNMENT_512 0x0000000000090000ULL +#define EFI_FV2_ALIGNMENT_1K 0x00000000000A0000ULL +#define EFI_FV2_ALIGNMENT_2K 0x00000000000B0000ULL +#define EFI_FV2_ALIGNMENT_4K 0x00000000000C0000ULL +#define EFI_FV2_ALIGNMENT_8K 0x00000000000D0000ULL +#define EFI_FV2_ALIGNMENT_16K 0x00000000000E0000ULL +#define EFI_FV2_ALIGNMENT_32K 0x00000000000F0000ULL +#define EFI_FV2_ALIGNMENT_64K 0x0000000000100000ULL +#define EFI_FV2_ALIGNMENT_128K 0x0000000000110000ULL +#define EFI_FV2_ALIGNMENT_256K 0x0000000000120000ULL +#define EFI_FV2_ALIGNMENT_512K 0x0000000000130000ULL +#define EFI_FV2_ALIGNMENT_1M 0x0000000000140000ULL +#define EFI_FV2_ALIGNMENT_2M 0x0000000000150000ULL +#define EFI_FV2_ALIGNMENT_4M 0x0000000000160000ULL +#define EFI_FV2_ALIGNMENT_8M 0x0000000000170000ULL +#define EFI_FV2_ALIGNMENT_16M 0x0000000000180000ULL +#define EFI_FV2_ALIGNMENT_32M 0x0000000000190000ULL +#define EFI_FV2_ALIGNMENT_64M 0x00000000001A0000ULL +#define EFI_FV2_ALIGNMENT_128M 0x00000000001B0000ULL +#define EFI_FV2_ALIGNMENT_256M 0x00000000001C0000ULL +#define EFI_FV2_ALIGNMENT_512M 0x00000000001D0000ULL +#define EFI_FV2_ALIGNMENT_1G 0x00000000001E0000ULL +#define EFI_FV2_ALIGNMENT_2G 0x00000000001F0000ULL + +/** + Returns the attributes and current settings of the firmware volume. + + Because of constraints imposed by the underlying firmware + storage, an instance of the Firmware Volume Protocol may not + be to able to support all possible variations of this + architecture. These constraints and the current state of the + firmware volume are exposed to the caller using the + GetVolumeAttributes() function. GetVolumeAttributes() is + callable only from TPL_NOTIFY and below. Behavior of + GetVolumeAttributes() at any EFI_TPL above TPL_NOTIFY is + undefined. + + @param This Indicates the EFI_FIRMWARE_VOLUME2_PROTOCOL instance. + + @param FvAttributes Pointer to an EFI_FV_ATTRIBUTES in which + the attributes and current settings are + returned. + + + @retval EFI_SUCCESS The firmware volume attributes were + returned. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FV_GET_ATTRIBUTES)( + IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, + OUT EFI_FV_ATTRIBUTES *FvAttributes + ); + +/** + Modifies the current settings of the firmware volume according to the input parameter. + + The SetVolumeAttributes() function is used to set configurable + firmware volume attributes. Only EFI_FV_READ_STATUS, + EFI_FV_WRITE_STATUS, and EFI_FV_LOCK_STATUS may be modified, and + then only in accordance with the declared capabilities. All + other bits of FvAttributes are ignored on input. On successful + return, all bits of *FvAttributes are valid and it contains the + completed EFI_FV_ATTRIBUTES for the volume. To modify an + attribute, the corresponding status bit in the EFI_FV_ATTRIBUTES + is set to the desired value on input. The EFI_FV_LOCK_STATUS bit + does not affect the ability to read or write the firmware + volume. Rather, once the EFI_FV_LOCK_STATUS bit is set, it + prevents further modification to all the attribute bits. + SetVolumeAttributes() is callable only from TPL_NOTIFY and + below. Behavior of SetVolumeAttributes() at any EFI_TPL above + TPL_NOTIFY is undefined. + + @param This Indicates the EFI_FIRMWARE_VOLUME2_PROTOCOL instance. + + @param FvAttributes On input, FvAttributes is a pointer to + an EFI_FV_ATTRIBUTES containing the + desired firmware volume settings. On + successful return, it contains the new + settings of the firmware volume. On + unsuccessful return, FvAttributes is not + modified and the firmware volume + settings are not changed. + + @retval EFI_SUCCESS The requested firmware volume attributes + were set and the resulting + EFI_FV_ATTRIBUTES is returned in + FvAttributes. + + @retval EFI_INVALID_PARAMETER FvAttributes:EFI_FV_READ_STATUS + is set to 1 on input, but the + device does not support enabling + reads + (FvAttributes:EFI_FV_READ_ENABLE + is clear on return from + GetVolumeAttributes()). Actual + volume attributes are unchanged. + + @retval EFI_INVALID_PARAMETER FvAttributes:EFI_FV_READ_STATUS + is cleared to 0 on input, but + the device does not support + disabling reads + (FvAttributes:EFI_FV_READ_DISABL + is clear on return from + GetVolumeAttributes()). Actual + volume attributes are unchanged. + + @retval EFI_INVALID_PARAMETER FvAttributes:EFI_FV_WRITE_STATUS + is set to 1 on input, but the + device does not support enabling + writes + (FvAttributes:EFI_FV_WRITE_ENABL + is clear on return from + GetVolumeAttributes()). Actual + volume attributes are unchanged. + + @retval EFI_INVALID_PARAMETER FvAttributes:EFI_FV_WRITE_STATUS + is cleared to 0 on input, but + the device does not support + disabling writes + (FvAttributes:EFI_FV_WRITE_DISAB + is clear on return from + GetVolumeAttributes()). Actual + volume attributes are unchanged. + + @retval EFI_INVALID_PARAMETER FvAttributes:EFI_FV_LOCK_STATUS + is set on input, but the device + does not support locking + (FvAttributes:EFI_FV_LOCK_CAP is + clear on return from + GetVolumeAttributes()). Actual + volume attributes are unchanged. + + @retval EFI_ACCESS_DENIED Device is locked and does not + allow attribute modification + (FvAttributes:EFI_FV_LOCK_STATUS + is set on return from + GetVolumeAttributes()). Actual + volume attributes are unchanged. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FV_SET_ATTRIBUTES)( + IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, + IN OUT EFI_FV_ATTRIBUTES *FvAttributes + ); + +/** + Retrieves a file and/or file information from the firmware volume. + + ReadFile() is used to retrieve any file from a firmware volume + during the DXE phase. The actual binary encoding of the file in + the firmware volume media may be in any arbitrary format as long + as it does the following: It is accessed using the Firmware + Volume Protocol. The image that is returned follows the image + format defined in Code Definitions: PI Firmware File Format. + If the input value of Buffer==NULL, it indicates the caller is + requesting only that the type, attributes, and size of the + file be returned and that there is no output buffer. In this + case, the following occurs: + - BufferSize is returned with the size that is required to + successfully complete the read. + - The output parameters FoundType and *FileAttributes are + returned with valid values. + - The returned value of *AuthenticationStatus is undefined. + + If the input value of Buffer!=NULL, the output buffer is + specified by a double indirection of the Buffer parameter. The + input value of *Buffer is used to determine if the output + buffer is caller allocated or is dynamically allocated by + ReadFile(). If the input value of *Buffer!=NULL, it indicates + the output buffer is caller allocated. In this case, the input + value of *BufferSize indicates the size of the + caller-allocated output buffer. If the output buffer is not + large enough to contain the entire requested output, it is + filled up to the point that the output buffer is exhausted and + EFI_WARN_BUFFER_TOO_SMALL is returned, and then BufferSize is + returned with the size required to successfully complete the + read. All other output parameters are returned with valid + values. If the input value of *Buffer==NULL, it indicates the + output buffer is to be allocated by ReadFile(). In this case, + ReadFile() will allocate an appropriately sized buffer from + boot services pool memory, which will be returned in Buffer. + The size of the new buffer is returned in BufferSize and all + other output parameters are returned with valid values. + ReadFile() is callable only from TPL_NOTIFY and below. + Behavior of ReadFile() at any EFI_TPL above TPL_NOTIFY is + undefined. + + @param This Indicates the EFI_FIRMWARE_VOLUME2_PROTOCOL instance. + + @param NameGuid Pointer to an EFI_GUID, which is the file + name. All firmware file names are EFI_GUIDs. + A single firmware volume must not have two + valid files with the same file name + EFI_GUID. + + @param Buffer Pointer to a pointer to a buffer in which the + file contents are returned, not including the + file header. + + @param BufferSize Pointer to a caller-allocated UINTN. It + indicates the size of the memory + represented by Buffer. + + @param FoundType Pointer to a caller-allocated EFI_FV_FILETYPE. + + @param FileAttributes Pointer to a caller-allocated + EFI_FV_FILE_ATTRIBUTES. + + @param AuthenticationStatus Pointer to a caller-allocated + UINT32 in which the + authentication status is + returned. + + @retval EFI_SUCCESS The call completed successfully. + + @retval EFI_WARN_BUFFER_TOO_SMALL The buffer is too small to + contain the requested + output. The buffer is + filled and the output is + truncated. + + @retval EFI_OUT_OF_RESOURCES An allocation failure occurred. + + @retval EFI_NOT_FOUND Name was not found in the firmware volume. + + @retval EFI_DEVICE_ERROR A hardware error occurred when + attempting to access the firmware volume. + + @retval EFI_ACCESS_DENIED The firmware volume is configured to + disallow reads. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FV_READ_FILE)( + IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, + IN CONST EFI_GUID *NameGuid, + IN OUT VOID **Buffer, + IN OUT UINTN *BufferSize, + OUT EFI_FV_FILETYPE *FoundType, + OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes, + OUT UINT32 *AuthenticationStatus + ); + +/** + Locates the requested section within a file and returns it in a buffer. + + ReadSection() is used to retrieve a specific section from a file + within a firmware volume. The section returned is determined + using a depth-first, left-to-right search algorithm through all + sections found in the specified file. The output buffer is specified by a double indirection + of the Buffer parameter. The input value of Buffer is used to + determine if the output buffer is caller allocated or is + dynamically allocated by ReadSection(). If the input value of + Buffer!=NULL, it indicates that the output buffer is caller + allocated. In this case, the input value of *BufferSize + indicates the size of the caller-allocated output buffer. If + the output buffer is not large enough to contain the entire + requested output, it is filled up to the point that the output + buffer is exhausted and EFI_WARN_BUFFER_TOO_SMALL is returned, + and then BufferSize is returned with the size that is required + to successfully complete the read. All other + output parameters are returned with valid values. If the input + value of *Buffer==NULL, it indicates the output buffer is to + be allocated by ReadSection(). In this case, ReadSection() + will allocate an appropriately sized buffer from boot services + pool memory, which will be returned in *Buffer. The size of + the new buffer is returned in *BufferSize and all other output + parameters are returned with valid values. ReadSection() is + callable only from TPL_NOTIFY and below. Behavior of + ReadSection() at any EFI_TPL above TPL_NOTIFY is + undefined. + + @param This Indicates the EFI_FIRMWARE_VOLUME2_PROTOCOL instance. + + @param NameGuid Pointer to an EFI_GUID, which indicates the + file name from which the requested section + will be read. + + @param SectionType Indicates the section type to return. + SectionType in conjunction with + SectionInstance indicates which section to + return. + + @param SectionInstance Indicates which instance of sections + with a type of SectionType to return. + SectionType in conjunction with + SectionInstance indicates which + section to return. SectionInstance is + zero based. + + @param Buffer Pointer to a pointer to a buffer in which the + section contents are returned, not including + the section header. + + @param BufferSize Pointer to a caller-allocated UINTN. It + indicates the size of the memory + represented by Buffer. + + @param AuthenticationStatus Pointer to a caller-allocated + UINT32 in which the authentication + status is returned. + + + @retval EFI_SUCCESS The call completed successfully. + + @retval EFI_WARN_BUFFER_TOO_SMALL The caller-allocated + buffer is too small to + contain the requested + output. The buffer is + filled and the output is + truncated. + + @retval EFI_OUT_OF_RESOURCES An allocation failure occurred. + + @retval EFI_NOT_FOUND The requested file was not found in + the firmware volume. EFI_NOT_FOUND The + requested section was not found in the + specified file. + + @retval EFI_DEVICE_ERROR A hardware error occurred when + attempting to access the firmware + volume. + + @retval EFI_ACCESS_DENIED The firmware volume is configured to + disallow reads. EFI_PROTOCOL_ERROR + The requested section was not found, + but the file could not be fully + parsed because a required + GUIDED_SECTION_EXTRACTION_PROTOCOL + was not found. It is possible the + requested section exists within the + file and could be successfully + extracted once the required + GUIDED_SECTION_EXTRACTION_PROTOCOL + is published. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FV_READ_SECTION)( + IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, + IN CONST EFI_GUID *NameGuid, + IN EFI_SECTION_TYPE SectionType, + IN UINTN SectionInstance, + IN OUT VOID **Buffer, + IN OUT UINTN *BufferSize, + OUT UINT32 *AuthenticationStatus + ); + +/// +/// EFI_FV_WRITE_POLICY, two policies (unreliable write and reliable write) are defined. +/// +typedef UINT32 EFI_FV_WRITE_POLICY; +#define EFI_FV_UNRELIABLE_WRITE 0x00000000 +#define EFI_FV_RELIABLE_WRITE 0x00000001 + +// +// EFI_FV_WRITE_FILE_DATA +// +typedef struct { + /// + /// Pointer to a GUID, which is the file name to be written. + /// + EFI_GUID *NameGuid; + /// + /// Indicates the type of file to be written. + /// + EFI_FV_FILETYPE Type; + /// + /// Indicates the attributes for the file to be written. + /// + EFI_FV_FILE_ATTRIBUTES FileAttributes; + /// + /// Pointer to a buffer containing the file to be written. + /// + VOID *Buffer; + /// + /// Indicates the size of the file image contained in Buffer. + /// + UINT32 BufferSize; +} EFI_FV_WRITE_FILE_DATA; + +/** + Locates the requested section within a file and returns it in a buffer. + + WriteFile() is used to write one or more files to a firmware + volume. Each file to be written is described by an + EFI_FV_WRITE_FILE_DATA structure. The caller must ensure that + any required alignment for all files listed in the FileData + array is compatible with the firmware volume. Firmware volume + capabilities can be determined using the GetVolumeAttributes() + call. Similarly, if the WritePolicy is set to + EFI_FV_RELIABLE_WRITE, the caller must check the firmware volume + capabilities to ensure EFI_FV_RELIABLE_WRITE is supported by the + firmware volume. EFI_FV_UNRELIABLE_WRITE must always be + supported. Writing a file with a size of zero + (FileData[n].BufferSize == 0) deletes the file from the firmware + volume if it exists. Deleting a file must be done one at a time. + Deleting a file as part of a multiple file write is not allowed. + Platform Initialization Specification VOLUME 3 Shared + Architectural Elements 84 August 21, 2006 Version 1.0 + WriteFile() is callable only from TPL_NOTIFY and below. + Behavior of WriteFile() at any EFI_TPL above TPL_NOTIFY is + undefined. + + @param This Indicates the EFI_FIRMWARE_VOLUME2_PROTOCOL instance. + + @param NumberOfFiles Indicates the number of elements in the array pointed to by FileData + + @param WritePolicy Indicates the level of reliability for the + write in the event of a power failure or + other system failure during the write + operation. + + @param FileData Pointer to an array of + EFI_FV_WRITE_FILE_DATA. Each element of + FileData[] represents a file to be written. + + + @retval EFI_SUCCESS The write completed successfully. + + @retval EFI_OUT_OF_RESOURCES The firmware volume does not + have enough free space to + storefile(s). + + @retval EFI_DEVICE_ERROR A hardware error occurred when + attempting to access the firmware volume. + + @retval EFI_WRITE_PROTECTED The firmware volume is + configured to disallow writes. + + @retval EFI_NOT_FOUND A delete was requested, but the + requested file was not found in the + firmware volume. + + @retval EFI_INVALID_PARAMETER A delete was requested with a + multiple file write. + + @retval EFI_INVALID_PARAMETER An unsupported WritePolicy was + requested. + + @retval EFI_INVALID_PARAMETER An unknown file type was + specified. + + @retval EFI_INVALID_PARAMETER A file system specific error + has occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FV_WRITE_FILE)( + IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, + IN UINT32 NumberOfFiles, + IN EFI_FV_WRITE_POLICY WritePolicy, + IN EFI_FV_WRITE_FILE_DATA *FileData + ); + +/** + Retrieves information about the next file in the firmware volume store + that matches the search criteria. + + GetNextFile() is the interface that is used to search a firmware + volume for a particular file. It is called successively until + the desired file is located or the function returns + EFI_NOT_FOUND. To filter uninteresting files from the output, + the type of file to search for may be specified in FileType. For + example, if *FileType is EFI_FV_FILETYPE_DRIVER, only files of + this type will be returned in the output. If *FileType is + EFI_FV_FILETYPE_ALL, no filtering of file types is done. The Key + parameter is used to indicate a starting point of the search. If + the buffer *Key is completely initialized to zero, the search + re-initialized and starts at the beginning. Subsequent calls to + GetNextFile() must maintain the value of *Key returned by the + immediately previous call. The actual contents of *Key are + implementation specific and no semantic content is implied. + GetNextFile() is callable only from TPL_NOTIFY and below. + Behavior of GetNextFile() at any EFI_TPL above TPL_NOTIFY is + undefined. + + @param This Indicates the EFI_FIRMWARE_VOLUME2_PROTOCOL instance. + + @param Key Pointer to a caller-allocated buffer that contains implementation-specific data that is + used to track where to begin the search for the next file. The size of the buffer must be + at least This->KeySize bytes long. To re-initialize the search and begin from the + beginning of the firmware volume, the entire buffer must be cleared to zero. Other + than clearing the buffer to initiate a new search, the caller must not modify the data in + the buffer between calls to GetNextFile(). + + @param FileType Pointer to a caller-allocated + EFI_FV_FILETYPE. The GetNextFile() API can + filter its search for files based on the + value of the FileType input. A *FileType + input of EFI_FV_FILETYPE_ALL causes + GetNextFile() to search for files of all + types. If a file is found, the file's type + is returned in FileType. *FileType is not + modified if no file is found. + + @param NameGuid Pointer to a caller-allocated EFI_GUID. If a + matching file is found, the file's name is + returned in NameGuid. If no matching file is + found, *NameGuid is not modified. + + @param Attributes Pointer to a caller-allocated + EFI_FV_FILE_ATTRIBUTES. If a matching file + is found, the file's attributes are returned + in Attributes. If no matching file is found, + Attributes is not modified. Type + EFI_FV_FILE_ATTRIBUTES is defined in + ReadFile(). + + @param Size Pointer to a caller-allocated UINTN. If a + matching file is found, the file's size is + returned in *Size. If no matching file is found, + Size is not modified. + + @retval EFI_SUCCESS The output parameters are filled with data + obtained from the first matching file that + was found. + + @retval FI_NOT_FOUND No files of type FileType were found. + + + @retval EFI_DEVICE_ERROR A hardware error occurred when + attempting to access the firmware + volume. + + @retval EFI_ACCESS_DENIED The firmware volume is configured to + disallow reads. + + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FV_GET_NEXT_FILE)( + IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, + IN OUT VOID *Key, + IN OUT EFI_FV_FILETYPE *FileType, + OUT EFI_GUID *NameGuid, + OUT EFI_FV_FILE_ATTRIBUTES *Attributes, + OUT UINTN *Size + ); + +/** + Return information about a firmware volume. + + The GetInfo() function returns information of type + InformationType for the requested firmware volume. If the volume + does not support the requested information type, then + EFI_UNSUPPORTED is returned. If the buffer is not large enough + to hold the requested structure, EFI_BUFFER_TOO_SMALL is + returned and the BufferSize is set to the size of buffer that is + required to make the request. The information types defined by + this specification are required information types that all file + systems must support. + + @param This A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL + instance that is the file handle the requested + information is for. + + @param InformationType The type identifier for the + information being requested. + + @param BufferSize On input, the size of Buffer. On output, + the amount of data returned in Buffer. In + both cases, the size is measured in bytes. + + @param Buffer A pointer to the data buffer to return. The + buffer's type is indicated by InformationType. + + + @retval EFI_SUCCESS The information was retrieved. + + @retval EFI_UNSUPPORTED The InformationType is not known. + + @retval EFI_NO_MEDIA The device has no medium. + + @retval EFI_DEVICE_ERROR The device reported an error. + + @retval EFI_VOLUME_CORRUPTED The file system structures are + corrupted. + + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to + read the current directory + entry. BufferSize has been + updated with the size needed to + complete the request. + + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FV_GET_INFO)( + IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, + IN CONST EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +/** + Sets information about a firmware volume. + + The SetInfo() function sets information of type InformationType + on the requested firmware volume. + + + @param This A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL + instance that is the file handle the information + is for. + + @param InformationType The type identifier for the + information being set. + + @param BufferSize The size, in bytes, of Buffer. + + @param Buffer A pointer to the data buffer to write. The + buffer's type is indicated by InformationType. + + @retval EFI_SUCCESS The information was set. + + @retval EFI_UNSUPPORTED The InformationType is not known. + + @retval EFI_NO_MEDIA The device has no medium. + + @retval EFI_DEVICE_ERROR The device reported an error. + + @retval EFI_VOLUME_CORRUPTED The file system structures are + corrupted. + + + @retval EFI_WRITE_PROTECTED The media is read only. + + @retval EFI_VOLUME_FULL The volume is full. + + @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the + size of the type indicated by + InformationType. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FV_SET_INFO)( + IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, + IN CONST EFI_GUID *InformationType, + IN UINTN BufferSize, + IN CONST VOID *Buffer + ); + +/// +/// The Firmware Volume Protocol contains the file-level +/// abstraction to the firmware volume as well as some firmware +/// volume attribute reporting and configuration services. The +/// Firmware Volume Protocol is the interface used by all parts of +/// DXE that are not directly involved with managing the firmware +/// volume itself. This abstraction allows many varied types of +/// firmware volume implementations. A firmware volume may be a +/// flash device or it may be a file in the UEFI system partition, +/// for example. This level of firmware volume implementation +/// detail is not visible to the consumers of the Firmware Volume +/// Protocol. +/// +struct _EFI_FIRMWARE_VOLUME2_PROTOCOL { + EFI_FV_GET_ATTRIBUTES GetVolumeAttributes; + EFI_FV_SET_ATTRIBUTES SetVolumeAttributes; + EFI_FV_READ_FILE ReadFile; + EFI_FV_READ_SECTION ReadSection; + EFI_FV_WRITE_FILE WriteFile; + EFI_FV_GET_NEXT_FILE GetNextFile; + + /// + /// Data field that indicates the size in bytes + /// of the Key input buffer for the + /// GetNextFile() API. + /// + UINT32 KeySize; + + /// + /// Handle of the parent firmware volume. + /// + EFI_HANDLE ParentHandle; + EFI_FV_GET_INFO GetInfo; + EFI_FV_SET_INFO SetInfo; +}; + +extern EFI_GUID gEfiFirmwareVolume2ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/FirmwareVolumeBlock.h b/sys/contrib/edk2/Include/Protocol/FirmwareVolumeBlock.h new file mode 100644 index 000000000000..5bf149ed9841 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/FirmwareVolumeBlock.h @@ -0,0 +1,352 @@ +/** @file + This file provides control over block-oriented firmware devices. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: PI + Version 1.0 and 1.2. + +**/ + +#ifndef __FIRMWARE_VOLUME_BLOCK_H__ +#define __FIRMWARE_VOLUME_BLOCK_H__ + +// +// EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL is defined in PI 1.0 spec and its GUID value +// is later updated to be the same as that of EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL +// defined in PI 1.2 spec. +// +#define EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID \ + { 0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } } + +#define EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL_GUID \ + { 0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } } + +typedef struct _EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL; + +typedef EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL; + +/** + The GetAttributes() function retrieves the attributes and + current settings of the block. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the + attributes and current settings are + returned. Type EFI_FVB_ATTRIBUTES_2 is defined + in EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were + returned. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FVB_GET_ATTRIBUTES)( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +/** + The SetAttributes() function sets configurable firmware volume + attributes and returns the new settings of the firmware volume. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Attributes On input, Attributes is a pointer to + EFI_FVB_ATTRIBUTES_2 that contains the + desired firmware volume settings. On + successful return, it contains the new + settings of the firmware volume. Type + EFI_FVB_ATTRIBUTES_2 is defined in + EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + + @retval EFI_INVALID_PARAMETER The attributes requested are in + conflict with the capabilities + as declared in the firmware + volume header. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FVB_SET_ATTRIBUTES)( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +/** + The GetPhysicalAddress() function retrieves the base address of + a memory-mapped firmware volume. This function should be called + only for memory-mapped firmware volumes. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Address Pointer to a caller-allocated + EFI_PHYSICAL_ADDRESS that, on successful + return from GetPhysicalAddress(), contains the + base address of the firmware volume. + + @retval EFI_SUCCESS The firmware volume base address was returned. + + @retval EFI_UNSUPPORTED The firmware volume is not memory mapped. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FVB_GET_PHYSICAL_ADDRESS)( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +/** + The GetBlockSize() function retrieves the size of the requested + block. It also returns the number of additional blocks with + the identical size. The GetBlockSize() function is used to + retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). + + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba Indicates the block for which to return the size. + + @param BlockSize Pointer to a caller-allocated UINTN in which + the size of the block is returned. + + @param NumberOfBlocks Pointer to a caller-allocated UINTN in + which the number of consecutive blocks, + starting with Lba, is returned. All + blocks in this range have a size of + BlockSize. + + + @retval EFI_SUCCESS The firmware volume base address was returned. + + @retval EFI_INVALID_PARAMETER The requested LBA is out of range. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FVB_GET_BLOCK_SIZE)( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ); + +/** + Reads the specified number of bytes into a buffer from the specified block. + + The Read() function reads the requested number of bytes from the + requested block and stores them in the provided buffer. + Implementations should be mindful that the firmware volume + might be in the ReadDisabled state. If it is in this state, + the Read() function must return the status code + EFI_ACCESS_DENIED without modifying the contents of the + buffer. The Read() function must also prevent spanning block + boundaries. If a read is requested that would span a block + boundary, the read must read up to the boundary but not + beyond. The output parameter NumBytes must be set to correctly + indicate the number of bytes actually read. The caller must be + aware that a read may be partially completed. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba The starting logical block index + from which to read. + + @param Offset Offset into the block at which to begin reading. + + @param NumBytes Pointer to a UINTN. At entry, *NumBytes + contains the total size of the buffer. At + exit, *NumBytes contains the total number of + bytes read. + + @param Buffer Pointer to a caller-allocated buffer that will + be used to hold the data that is read. + + @retval EFI_SUCCESS The firmware volume was read successfully, + and contents are in Buffer. + + @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA + boundary. On output, NumBytes + contains the total number of bytes + returned in Buffer. + + @retval EFI_ACCESS_DENIED The firmware volume is in the + ReadDisabled state. + + @retval EFI_DEVICE_ERROR The block device is not + functioning correctly and could + not be read. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FVB_READ)( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ); + +/** + Writes the specified number of bytes from the input buffer to the block. + + The Write() function writes the specified number of bytes from + the provided buffer to the specified block and offset. If the + firmware volume is sticky write, the caller must ensure that + all the bits of the specified range to write are in the + EFI_FVB_ERASE_POLARITY state before calling the Write() + function, or else the result will be unpredictable. This + unpredictability arises because, for a sticky-write firmware + volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY + state but cannot flip it back again. Before calling the + Write() function, it is recommended for the caller to first call + the EraseBlocks() function to erase the specified block to + write. A block erase cycle will transition bits from the + (NOT)EFI_FVB_ERASE_POLARITY state back to the + EFI_FVB_ERASE_POLARITY state. Implementations should be + mindful that the firmware volume might be in the WriteDisabled + state. If it is in this state, the Write() function must + return the status code EFI_ACCESS_DENIED without modifying the + contents of the firmware volume. The Write() function must + also prevent spanning block boundaries. If a write is + requested that spans a block boundary, the write must store up + to the boundary but not beyond. The output parameter NumBytes + must be set to correctly indicate the number of bytes actually + written. The caller must be aware that a write may be + partially completed. All writes, partial or otherwise, must be + fully flushed to the hardware before the Write() service + returns. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba The starting logical block index to write to. + + @param Offset Offset into the block at which to begin writing. + + @param NumBytes The pointer to a UINTN. At entry, *NumBytes + contains the total size of the buffer. At + exit, *NumBytes contains the total number of + bytes actually written. + + @param Buffer The pointer to a caller-allocated buffer that + contains the source for the write. + + @retval EFI_SUCCESS The firmware volume was written successfully. + + @retval EFI_BAD_BUFFER_SIZE The write was attempted across an + LBA boundary. On output, NumBytes + contains the total number of bytes + actually written. + + @retval EFI_ACCESS_DENIED The firmware volume is in the + WriteDisabled state. + + @retval EFI_DEVICE_ERROR The block device is malfunctioning + and could not be written. + + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FVB_WRITE)( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +/// +/// EFI_LBA_LIST_TERMINATOR +/// +#define EFI_LBA_LIST_TERMINATOR 0xFFFFFFFFFFFFFFFFULL + +/** + Erases and initializes a firmware volume block. + + The EraseBlocks() function erases one or more blocks as denoted + by the variable argument list. The entire parameter list of + blocks must be verified before erasing any blocks. If a block is + requested that does not exist within the associated firmware + volume (it has a larger index than the last block of the + firmware volume), the EraseBlocks() function must return the + status code EFI_INVALID_PARAMETER without modifying the contents + of the firmware volume. Implementations should be mindful that + the firmware volume might be in the WriteDisabled state. If it + is in this state, the EraseBlocks() function must return the + status code EFI_ACCESS_DENIED without modifying the contents of + the firmware volume. All calls to EraseBlocks() must be fully + flushed to the hardware before the EraseBlocks() service + returns. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL + instance. + + @param ... The variable argument list is a list of tuples. + Each tuple describes a range of LBAs to erase + and consists of the following: + - An EFI_LBA that indicates the starting LBA + - A UINTN that indicates the number of blocks to + erase. + + The list is terminated with an + EFI_LBA_LIST_TERMINATOR. For example, the + following indicates that two ranges of blocks + (5-7 and 10-11) are to be erased: EraseBlocks + (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR); + + @retval EFI_SUCCESS The erase request successfully + completed. + + @retval EFI_ACCESS_DENIED The firmware volume is in the + WriteDisabled state. + @retval EFI_DEVICE_ERROR The block device is not functioning + correctly and could not be written. + The firmware device may have been + partially erased. + @retval EFI_INVALID_PARAMETER One or more of the LBAs listed + in the variable argument list do + not exist in the firmware volume. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FVB_ERASE_BLOCKS)( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ); + +/// +/// The Firmware Volume Block Protocol is the low-level interface +/// to a firmware volume. File-level access to a firmware volume +/// should not be done using the Firmware Volume Block Protocol. +/// Normal access to a firmware volume must use the Firmware +/// Volume Protocol. Typically, only the file system driver that +/// produces the Firmware Volume Protocol will bind to the +/// Firmware Volume Block Protocol. +/// +struct _EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL { + EFI_FVB_GET_ATTRIBUTES GetAttributes; + EFI_FVB_SET_ATTRIBUTES SetAttributes; + EFI_FVB_GET_PHYSICAL_ADDRESS GetPhysicalAddress; + EFI_FVB_GET_BLOCK_SIZE GetBlockSize; + EFI_FVB_READ Read; + EFI_FVB_WRITE Write; + EFI_FVB_ERASE_BLOCKS EraseBlocks; + /// + /// The handle of the parent firmware volume. + /// + EFI_HANDLE ParentHandle; +}; + +extern EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid; +extern EFI_GUID gEfiFirmwareVolumeBlock2ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/FormBrowser2.h b/sys/contrib/edk2/Include/Protocol/FormBrowser2.h new file mode 100644 index 000000000000..9785adc08927 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/FormBrowser2.h @@ -0,0 +1,172 @@ +/** @file + This protocol is defined in UEFI spec. + + The EFI_FORM_BROWSER2_PROTOCOL is the interface to call for drivers to + leverage the EFI configuration driver interface. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_FORM_BROWSER2_H__ +#define __EFI_FORM_BROWSER2_H__ + +#include <Guid/HiiPlatformSetupFormset.h> + +#define EFI_FORM_BROWSER2_PROTOCOL_GUID \ + {0xb9d4c360, 0xbcfb, 0x4f9b, {0x92, 0x98, 0x53, 0xc1, 0x36, 0x98, 0x22, 0x58 }} + +typedef struct _EFI_FORM_BROWSER2_PROTOCOL EFI_FORM_BROWSER2_PROTOCOL; + +/** + + @param LeftColumn The value that designates the text column + where the browser window will begin from + the left-hand side of the screen + + @param RightColumn The value that designates the text + column where the browser window will end + on the right-hand side of the screen. + + @param TopRow The value that designates the text row from the + top of the screen where the browser window + will start. + + @param BottomRow The value that designates the text row from the + bottom of the screen where the browser + window will end. +**/ +typedef struct { + UINTN LeftColumn; + UINTN RightColumn; + UINTN TopRow; + UINTN BottomRow; +} EFI_SCREEN_DESCRIPTOR; + +typedef UINTN EFI_BROWSER_ACTION_REQUEST; + +#define EFI_BROWSER_ACTION_REQUEST_NONE 0 +#define EFI_BROWSER_ACTION_REQUEST_RESET 1 +#define EFI_BROWSER_ACTION_REQUEST_SUBMIT 2 +#define EFI_BROWSER_ACTION_REQUEST_EXIT 3 +#define EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT 4 +#define EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT 5 +#define EFI_BROWSER_ACTION_REQUEST_FORM_APPLY 6 +#define EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD 7 +#define EFI_BROWSER_ACTION_REQUEST_RECONNECT 8 +#define EFI_BROWSER_ACTION_REQUEST_QUESTION_APPLY 9 + +/** + Initialize the browser to display the specified configuration forms. + + This function is the primary interface to the internal forms-based browser. + The forms browser will display forms associated with the specified Handles. + The browser will select all forms in packages which have the specified Type + and (for EFI_HII_PACKAGE_TYPE_GUID) the specified PackageGuid. + + @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL instance + + @param Handles A pointer to an array of Handles. This value should correspond + to the value of the HII form package that is required to be displayed. + + @param HandleCount The number of Handles specified in Handle. + + @param FormSetGuid This field points to the EFI_GUID which must match the Guid field or one of the + elements of the ClassId field in the EFI_IFR_FORM_SET op-code. If + FormsetGuid is NULL, then this function will display the form set class + EFI_HII_PLATFORM_SETUP_FORMSET_GUID. + + @param FormId This field specifies the identifier of the form within the form set to render as the first + displayable page. If this field has a value of 0x0000, then the Forms Browser will + render the first enabled form in the form set. + + @param ScreenDimensions Points to recommended form dimensions, including any non-content area, in + characters. + + @param ActionRequest Points to the action recommended by the form. + + @retval EFI_SUCCESS The function completed successfully + + @retval EFI_NOT_FOUND The variable was not found. + + @retval EFI_INVALID_PARAMETER One of the parameters has an + invalid value. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SEND_FORM2)( + IN CONST EFI_FORM_BROWSER2_PROTOCOL *This, + IN EFI_HII_HANDLE *Handle, + IN UINTN HandleCount, + IN EFI_GUID *FormSetGuid OPTIONAL, + IN EFI_FORM_ID FormId OPTIONAL, + IN CONST EFI_SCREEN_DESCRIPTOR *ScreenDimensions OPTIONAL, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest OPTIONAL + ); + +/** + This function is called by a callback handler to retrieve uncommitted state data from the browser. + + This routine is called by a routine which was called by the + browser. This routine called this service in the browser to + retrieve or set certain uncommitted state information. + + @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL instance. + + @param ResultsDataSize A pointer to the size of the buffer + associated with ResultsData. On input, the size in + bytes of ResultsData. On output, the size of data + returned in ResultsData. + + @param ResultsData A string returned from an IFR browser or + equivalent. The results string will have + no routing information in them. + + @param RetrieveData A BOOLEAN field which allows an agent to + retrieve (if RetrieveData = TRUE) data + from the uncommitted browser state + information or set (if RetrieveData = + FALSE) data in the uncommitted browser + state information. + + @param VariableGuid An optional field to indicate the target + variable GUID name to use. + + @param VariableName An optional field to indicate the target + human-readable variable name. + + @retval EFI_SUCCESS The results have been distributed or are + awaiting distribution. + + @retval EFI_BUFFER_TOO_SMALL The ResultsDataSize specified + was too small to contain the + results data. + + @retval EFI_UNSUPPORTED Uncommitted browser state is not available + at the current stage of execution. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BROWSER_CALLBACK2)( + IN CONST EFI_FORM_BROWSER2_PROTOCOL *This, + IN OUT UINTN *ResultsDataSize, + IN OUT EFI_STRING ResultsData, + IN CONST BOOLEAN RetrieveData, + IN CONST EFI_GUID *VariableGuid OPTIONAL, + IN CONST CHAR16 *VariableName OPTIONAL + ); + +/// +/// This interface will allow the caller to direct the configuration +/// driver to use either the HII database or use the passed-in packet of data. +/// +struct _EFI_FORM_BROWSER2_PROTOCOL { + EFI_SEND_FORM2 SendForm; + EFI_BROWSER_CALLBACK2 BrowserCallback; +}; + +extern EFI_GUID gEfiFormBrowser2ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/GraphicsOutput.h b/sys/contrib/edk2/Include/Protocol/GraphicsOutput.h new file mode 100644 index 000000000000..edd5495e562f --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/GraphicsOutput.h @@ -0,0 +1,270 @@ +/** @file + Graphics Output Protocol from the UEFI 2.0 specification. + + Abstraction of a very simple graphics device. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __GRAPHICS_OUTPUT_H__ +#define __GRAPHICS_OUTPUT_H__ + +#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ + { \ + 0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } \ + } + +typedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL; + +typedef struct { + UINT32 RedMask; + UINT32 GreenMask; + UINT32 BlueMask; + UINT32 ReservedMask; +} EFI_PIXEL_BITMASK; + +typedef enum { + /// + /// A pixel is 32-bits and byte zero represents red, byte one represents green, + /// byte two represents blue, and byte three is reserved. This is the definition + /// for the physical frame buffer. The byte values for the red, green, and blue + /// components represent the color intensity. This color intensity value range + /// from a minimum intensity of 0 to maximum intensity of 255. + /// + PixelRedGreenBlueReserved8BitPerColor, + /// + /// A pixel is 32-bits and byte zero represents blue, byte one represents green, + /// byte two represents red, and byte three is reserved. This is the definition + /// for the physical frame buffer. The byte values for the red, green, and blue + /// components represent the color intensity. This color intensity value range + /// from a minimum intensity of 0 to maximum intensity of 255. + /// + PixelBlueGreenRedReserved8BitPerColor, + /// + /// The Pixel definition of the physical frame buffer. + /// + PixelBitMask, + /// + /// This mode does not support a physical frame buffer. + /// + PixelBltOnly, + /// + /// Valid EFI_GRAPHICS_PIXEL_FORMAT enum values are less than this value. + /// + PixelFormatMax +} EFI_GRAPHICS_PIXEL_FORMAT; + +typedef struct { + /// + /// The version of this data structure. A value of zero represents the + /// EFI_GRAPHICS_OUTPUT_MODE_INFORMATION structure as defined in this specification. + /// + UINT32 Version; + /// + /// The size of video screen in pixels in the X dimension. + /// + UINT32 HorizontalResolution; + /// + /// The size of video screen in pixels in the Y dimension. + /// + UINT32 VerticalResolution; + /// + /// Enumeration that defines the physical format of the pixel. A value of PixelBltOnly + /// implies that a linear frame buffer is not available for this mode. + /// + EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; + /// + /// This bit-mask is only valid if PixelFormat is set to PixelPixelBitMask. + /// A bit being set defines what bits are used for what purpose such as Red, Green, Blue, or Reserved. + /// + EFI_PIXEL_BITMASK PixelInformation; + /// + /// Defines the number of pixel elements per video memory line. + /// + UINT32 PixelsPerScanLine; +} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION; + +/** + Returns information for an available graphics mode that the graphics device + and the set of active video output devices supports. + + @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance. + @param ModeNumber The mode number to return information on. + @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer. + @param Info A pointer to callee allocated buffer that returns information about ModeNumber. + + @retval EFI_SUCCESS Valid mode information was returned. + @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode. + @retval EFI_INVALID_PARAMETER ModeNumber is not valid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE)( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ); + +/** + Set the video device into the specified mode and clears the visible portions of + the output display to black. + + @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance. + @param ModeNumber Abstraction that defines the current video mode. + + @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected. + @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. + @retval EFI_UNSUPPORTED ModeNumber is not supported by this device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE)( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber + ); + +typedef struct { + UINT8 Blue; + UINT8 Green; + UINT8 Red; + UINT8 Reserved; +} EFI_GRAPHICS_OUTPUT_BLT_PIXEL; + +typedef union { + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Pixel; + UINT32 Raw; +} EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION; + +/// +/// actions for BltOperations +/// +typedef enum { + /// + /// Write data from the BltBuffer pixel (0, 0) + /// directly to every pixel of the video display rectangle + /// (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). + /// Only one pixel will be used from the BltBuffer. Delta is NOT used. + /// + EfiBltVideoFill, + + /// + /// Read data from the video display rectangle + /// (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in + /// the BltBuffer rectangle (DestinationX, DestinationY ) + /// (DestinationX + Width, DestinationY + Height). If DestinationX or + /// DestinationY is not zero then Delta must be set to the length in bytes + /// of a row in the BltBuffer. + /// + EfiBltVideoToBltBuffer, + + /// + /// Write data from the BltBuffer rectangle + /// (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the + /// video display rectangle (DestinationX, DestinationY) + /// (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is + /// not zero then Delta must be set to the length in bytes of a row in the + /// BltBuffer. + /// + EfiBltBufferToVideo, + + /// + /// Copy from the video display rectangle (SourceX, SourceY) + /// (SourceX + Width, SourceY + Height) to the video display rectangle + /// (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). + /// The BltBuffer and Delta are not used in this mode. + /// + EfiBltVideoToVideo, + + EfiGraphicsOutputBltOperationMax +} EFI_GRAPHICS_OUTPUT_BLT_OPERATION; + +/** + Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer. + + @param This Protocol instance pointer. + @param BltBuffer The data to transfer to the graphics screen. + Size is at least Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL). + @param BltOperation The operation to perform when copying BltBuffer on to the graphics screen. + @param SourceX The X coordinate of source for the BltOperation. + @param SourceY The Y coordinate of source for the BltOperation. + @param DestinationX The X coordinate of destination for the BltOperation. + @param DestinationY The Y coordinate of destination for the BltOperation. + @param Width The width of a rectangle in the blt rectangle in pixels. + @param Height The height of a rectangle in the blt rectangle in pixels. + @param Delta Not used for EfiBltVideoFill or the EfiBltVideoToVideo operation. + If a Delta of zero is used, the entire BltBuffer is being operated on. + If a subrectangle of the BltBuffer is being used then Delta + represents the number of bytes in a row of the BltBuffer. + + @retval EFI_SUCCESS BltBuffer was drawn to the graphics screen. + @retval EFI_INVALID_PARAMETER BltOperation is not valid. + @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT)( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL + ); + +typedef struct { + /// + /// The number of modes supported by QueryMode() and SetMode(). + /// + UINT32 MaxMode; + /// + /// Current Mode of the graphics device. Valid mode numbers are 0 to MaxMode -1. + /// + UINT32 Mode; + /// + /// Pointer to read-only EFI_GRAPHICS_OUTPUT_MODE_INFORMATION data. + /// + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + /// + /// Size of Info structure in bytes. + /// + UINTN SizeOfInfo; + /// + /// Base address of graphics linear frame buffer. + /// Offset zero in FrameBufferBase represents the upper left pixel of the display. + /// + EFI_PHYSICAL_ADDRESS FrameBufferBase; + /// + /// Amount of frame buffer needed to support the active mode as defined by + /// PixelsPerScanLine xVerticalResolution x PixelElementSize. + /// + UINTN FrameBufferSize; +} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE; + +/// +/// Provides a basic abstraction to set video modes and copy pixels to and from +/// the graphics controller's frame buffer. The linear address of the hardware +/// frame buffer is also exposed so software can write directly to the video hardware. +/// +struct _EFI_GRAPHICS_OUTPUT_PROTOCOL { + EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode; + EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode; + EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt; + /// + /// Pointer to EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE data. + /// + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode; +}; + +extern EFI_GUID gEfiGraphicsOutputProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Hash.h b/sys/contrib/edk2/Include/Protocol/Hash.h new file mode 100644 index 000000000000..b76821fb4f0b --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Hash.h @@ -0,0 +1,169 @@ +/** @file
+ EFI_HASH_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.0.
+ EFI_HASH_PROTOCOL as defined in UEFI 2.0.
+ The EFI Hash Service Binding Protocol is used to locate hashing services support
+ provided by a driver and to create and destroy instances of the EFI Hash Protocol
+ so that a multiple drivers can use the underlying hashing services.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_HASH_PROTOCOL_H__
+#define __EFI_HASH_PROTOCOL_H__
+
+#define EFI_HASH_SERVICE_BINDING_PROTOCOL_GUID \
+ { \
+ 0x42881c98, 0xa4f3, 0x44b0, {0xa3, 0x9d, 0xdf, 0xa1, 0x86, 0x67, 0xd8, 0xcd } \
+ }
+
+#define EFI_HASH_PROTOCOL_GUID \
+ { \
+ 0xc5184932, 0xdba5, 0x46db, {0xa5, 0xba, 0xcc, 0x0b, 0xda, 0x9c, 0x14, 0x35 } \
+ }
+
+#define EFI_HASH_ALGORITHM_SHA1_GUID \
+ { \
+ 0x2ae9d80f, 0x3fb2, 0x4095, {0xb7, 0xb1, 0xe9, 0x31, 0x57, 0xb9, 0x46, 0xb6 } \
+ }
+
+#define EFI_HASH_ALGORITHM_SHA224_GUID \
+ { \
+ 0x8df01a06, 0x9bd5, 0x4bf7, {0xb0, 0x21, 0xdb, 0x4f, 0xd9, 0xcc, 0xf4, 0x5b } \
+ }
+
+#define EFI_HASH_ALGORITHM_SHA256_GUID \
+ { \
+ 0x51aa59de, 0xfdf2, 0x4ea3, {0xbc, 0x63, 0x87, 0x5f, 0xb7, 0x84, 0x2e, 0xe9 } \
+ }
+
+#define EFI_HASH_ALGORITHM_SHA384_GUID \
+ { \
+ 0xefa96432, 0xde33, 0x4dd2, {0xae, 0xe6, 0x32, 0x8c, 0x33, 0xdf, 0x77, 0x7a } \
+ }
+
+#define EFI_HASH_ALGORITHM_SHA512_GUID \
+ { \
+ 0xcaa4381e, 0x750c, 0x4770, {0xb8, 0x70, 0x7a, 0x23, 0xb4, 0xe4, 0x21, 0x30 } \
+ }
+
+#define EFI_HASH_ALGORTIHM_MD5_GUID \
+ { \
+ 0xaf7c79c, 0x65b5, 0x4319, {0xb0, 0xae, 0x44, 0xec, 0x48, 0x4e, 0x4a, 0xd7 } \
+ }
+
+#define EFI_HASH_ALGORITHM_SHA1_NOPAD_GUID \
+ { \
+ 0x24c5dc2f, 0x53e2, 0x40ca, {0x9e, 0xd6, 0xa5, 0xd9, 0xa4, 0x9f, 0x46, 0x3b } \
+ }
+
+#define EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID \
+ { \
+ 0x8628752a, 0x6cb7, 0x4814, {0x96, 0xfc, 0x24, 0xa8, 0x15, 0xac, 0x22, 0x26 } \
+ }
+
+//
+// Note: Use of the following algorithms with EFI_HASH_PROTOCOL is deprecated.
+// EFI_HASH_ALGORITHM_SHA1_GUID
+// EFI_HASH_ALGORITHM_SHA224_GUID
+// EFI_HASH_ALGORITHM_SHA256_GUID
+// EFI_HASH_ALGORITHM_SHA384_GUID
+// EFI_HASH_ALGORITHM_SHA512_GUID
+// EFI_HASH_ALGORTIHM_MD5_GUID
+//
+
+typedef struct _EFI_HASH_PROTOCOL EFI_HASH_PROTOCOL;
+
+typedef UINT8 EFI_MD5_HASH[16];
+typedef UINT8 EFI_SHA1_HASH[20];
+typedef UINT8 EFI_SHA224_HASH[28];
+typedef UINT8 EFI_SHA256_HASH[32];
+typedef UINT8 EFI_SHA384_HASH[48];
+typedef UINT8 EFI_SHA512_HASH[64];
+
+typedef union {
+ EFI_MD5_HASH *Md5Hash;
+ EFI_SHA1_HASH *Sha1Hash;
+ EFI_SHA224_HASH *Sha224Hash;
+ EFI_SHA256_HASH *Sha256Hash;
+ EFI_SHA384_HASH *Sha384Hash;
+ EFI_SHA512_HASH *Sha512Hash;
+} EFI_HASH_OUTPUT;
+
+/**
+ Returns the size of the hash which results from a specific algorithm.
+
+ @param[in] This Points to this instance of EFI_HASH_PROTOCOL.
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
+ @param[out] HashSize Holds the returned size of the algorithm's hash.
+
+ @retval EFI_SUCCESS Hash size returned successfully.
+ @retval EFI_INVALID_PARAMETER HashSize is NULL or HashAlgorithm is NULL.
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported
+ by this driver.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HASH_GET_HASH_SIZE)(
+ IN CONST EFI_HASH_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ OUT UINTN *HashSize
+ );
+
+/**
+ Creates a hash for the specified message text.
+
+ @param[in] This Points to this instance of EFI_HASH_PROTOCOL.
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
+ @param[in] Extend Specifies whether to create a new hash (FALSE) or extend the specified
+ existing hash (TRUE).
+ @param[in] Message Points to the start of the message.
+ @param[in] MessageSize The size of Message, in bytes.
+ @param[in,out] Hash On input, if Extend is TRUE, then this parameter holds a pointer
+ to a pointer to an array containing the hash to extend. If Extend
+ is FALSE, then this parameter holds a pointer to a pointer to a
+ caller-allocated array that will receive the result of the hash
+ computation. On output (regardless of the value of Extend), the
+ array will contain the result of the hash computation.
+
+ @retval EFI_SUCCESS Hash returned successfully.
+ @retval EFI_INVALID_PARAMETER Message or Hash, HashAlgorithm is NULL or MessageSize is 0.
+ MessageSize is not an integer multiple of block size.
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this
+ driver. Or, Extend is TRUE, and the algorithm doesn't support extending the hash.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HASH_HASH)(
+ IN CONST EFI_HASH_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN BOOLEAN Extend,
+ IN CONST UINT8 *Message,
+ IN UINT64 MessageSize,
+ IN OUT EFI_HASH_OUTPUT *Hash
+ );
+
+///
+/// This protocol allows creating a hash of an arbitrary message digest
+/// using one or more hash algorithms.
+///
+struct _EFI_HASH_PROTOCOL {
+ EFI_HASH_GET_HASH_SIZE GetHashSize;
+ EFI_HASH_HASH Hash;
+};
+
+extern EFI_GUID gEfiHashServiceBindingProtocolGuid;
+extern EFI_GUID gEfiHashProtocolGuid;
+extern EFI_GUID gEfiHashAlgorithmSha1Guid;
+extern EFI_GUID gEfiHashAlgorithmSha224Guid;
+extern EFI_GUID gEfiHashAlgorithmSha256Guid;
+extern EFI_GUID gEfiHashAlgorithmSha384Guid;
+extern EFI_GUID gEfiHashAlgorithmSha512Guid;
+extern EFI_GUID gEfiHashAlgorithmMD5Guid;
+extern EFI_GUID gEfiHashAlgorithmSha1NoPadGuid;
+extern EFI_GUID gEfiHashAlgorithmSha256NoPadGuid;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Protocol/Hash2.h b/sys/contrib/edk2/Include/Protocol/Hash2.h new file mode 100644 index 000000000000..59a41b45b575 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Hash2.h @@ -0,0 +1,196 @@ +/** @file
+ EFI_HASH2_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.5.
+ EFI_HASH2_PROTOCOL as defined in UEFI 2.5.
+ The EFI Hash2 Service Binding Protocol is used to locate hashing services support
+ provided by a driver and to create and destroy instances of the EFI Hash2 Protocol
+ so that a multiple drivers can use the underlying hashing services.
+ EFI_HASH2_PROTOCOL describes hashing functions for which the algorithm-required
+ message padding and finalization are performed by the supporting driver.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_HASH2_PROTOCOL_H__
+#define __EFI_HASH2_PROTOCOL_H__
+
+#define EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID \
+ { \
+ 0xda836f8d, 0x217f, 0x4ca0, { 0x99, 0xc2, 0x1c, 0xa4, 0xe1, 0x60, 0x77, 0xea } \
+ }
+
+#define EFI_HASH2_PROTOCOL_GUID \
+ { \
+ 0x55b1d734, 0xc5e1, 0x49db, { 0x96, 0x47, 0xb1, 0x6a, 0xfb, 0xe, 0x30, 0x5b } \
+ }
+
+#include <Protocol/Hash.h>
+
+//
+// NOTE:
+// Algorithms EFI_HASH_ALGORITHM_SHA1_NOPAD and
+// EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID are not compatible with
+// EFI_HASH2_PROTOCOL and will return EFI_UNSUPPORTED if used with any
+// EFI_HASH2_PROTOCOL function.
+//
+
+//
+// Note: SHA-1 and MD5 are included for backwards compatibility.
+// New driver implementations are encouraged to consider stronger algorithms.
+//
+
+typedef struct _EFI_HASH2_PROTOCOL EFI_HASH2_PROTOCOL;
+
+typedef UINT8 EFI_MD5_HASH2[16];
+typedef UINT8 EFI_SHA1_HASH2[20];
+typedef UINT8 EFI_SHA224_HASH2[28];
+typedef UINT8 EFI_SHA256_HASH2[32];
+typedef UINT8 EFI_SHA384_HASH2[48];
+typedef UINT8 EFI_SHA512_HASH2[64];
+
+typedef union {
+ EFI_MD5_HASH2 Md5Hash;
+ EFI_SHA1_HASH2 Sha1Hash;
+ EFI_SHA224_HASH2 Sha224Hash;
+ EFI_SHA256_HASH2 Sha256Hash;
+ EFI_SHA384_HASH2 Sha384Hash;
+ EFI_SHA512_HASH2 Sha512Hash;
+} EFI_HASH2_OUTPUT;
+
+/**
+ Returns the size of the hash which results from a specific algorithm.
+
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
+ @param[out] HashSize Holds the returned size of the algorithm's hash.
+
+ @retval EFI_SUCCESS Hash size returned successfully.
+ @retval EFI_INVALID_PARAMETER This or HashSize is NULL.
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
+ or HashAlgorithm is null.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HASH2_GET_HASH_SIZE)(
+ IN CONST EFI_HASH2_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ OUT UINTN *HashSize
+ );
+
+/**
+ Creates a hash for the specified message text. The hash is not extendable.
+ The output is final with any algorithm-required padding added by the function.
+
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
+ @param[in] Message Points to the start of the message.
+ @param[in] MessageSize The size of Message, in bytes.
+ @param[in,out] Hash On input, points to a caller-allocated buffer of the size
+ returned by GetHashSize() for the specified HashAlgorithm.
+ On output, the buffer holds the resulting hash computed from the message.
+
+ @retval EFI_SUCCESS Hash returned successfully.
+ @retval EFI_INVALID_PARAMETER This or Hash is NULL.
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
+ or HashAlgorithm is Null.
+ @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available
+ or MessageSize is greater than platform maximum.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HASH2_HASH)(
+ IN CONST EFI_HASH2_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN CONST UINT8 *Message,
+ IN UINTN MessageSize,
+ IN OUT EFI_HASH2_OUTPUT *Hash
+ );
+
+/**
+ This function must be called to initialize a digest calculation to be subsequently performed using the
+ EFI_HASH2_PROTOCOL functions HashUpdate() and HashFinal().
+
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
+
+ @retval EFI_SUCCESS Initialized successfully.
+ @retval EFI_INVALID_PARAMETER This is NULL.
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
+ or HashAlgorithm is Null.
+ @retval EFI_OUT_OF_RESOURCES Process failed due to lack of required resource.
+ @retval EFI_ALREADY_STARTED This function is called when the operation in progress is still in processing Hash(),
+ or HashInit() is already called before and not terminated by HashFinal() yet on the same instance.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HASH2_HASH_INIT)(
+ IN CONST EFI_HASH2_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm
+ );
+
+/**
+ Updates the hash of a computation in progress by adding a message text.
+
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
+ @param[in] Message Points to the start of the message.
+ @param[in] MessageSize The size of Message, in bytes.
+
+ @retval EFI_SUCCESS Digest in progress updated successfully.
+ @retval EFI_INVALID_PARAMETER This or Hash is NULL.
+ @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available
+ or MessageSize is greater than platform maximum.
+ @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit(),
+ or the operation in progress was terminated by a call to Hash() or HashFinal() on the same instance.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HASH2_HASH_UPDATE)(
+ IN CONST EFI_HASH2_PROTOCOL *This,
+ IN CONST UINT8 *Message,
+ IN UINTN MessageSize
+ );
+
+/**
+ Finalizes a hash operation in progress and returns calculation result.
+ The output is final with any necessary padding added by the function.
+ The hash may not be further updated or extended after HashFinal().
+
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
+ @param[in,out] Hash On input, points to a caller-allocated buffer of the size
+ returned by GetHashSize() for the specified HashAlgorithm specified in preceding HashInit().
+ On output, the buffer holds the resulting hash computed from the message.
+
+ @retval EFI_SUCCESS Hash returned successfully.
+ @retval EFI_INVALID_PARAMETER This or Hash is NULL.
+ @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit() and at least one call to HashUpdate(),
+ or the operation in progress was canceled by a call to Hash() on the same instance.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HASH2_HASH_FINAL)(
+ IN CONST EFI_HASH2_PROTOCOL *This,
+ IN OUT EFI_HASH2_OUTPUT *Hash
+ );
+
+///
+/// This protocol describes hashing functions for which the algorithm-required message padding and
+/// finalization are performed by the supporting driver.
+///
+struct _EFI_HASH2_PROTOCOL {
+ EFI_HASH2_GET_HASH_SIZE GetHashSize;
+ EFI_HASH2_HASH Hash;
+ EFI_HASH2_HASH_INIT HashInit;
+ EFI_HASH2_HASH_UPDATE HashUpdate;
+ EFI_HASH2_HASH_FINAL HashFinal;
+};
+
+extern EFI_GUID gEfiHash2ServiceBindingProtocolGuid;
+extern EFI_GUID gEfiHash2ProtocolGuid;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Protocol/HiiConfigRouting.h b/sys/contrib/edk2/Include/Protocol/HiiConfigRouting.h new file mode 100644 index 000000000000..908321966832 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/HiiConfigRouting.h @@ -0,0 +1,411 @@ +/** @file + The file provides services to manage the movement of + configuration data from drivers to configuration applications. + It then serves as the single point to receive configuration + information from configuration applications, routing the + results to the appropriate drivers. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol was introduced in UEFI Specification 2.1. + + +**/ + +#ifndef __HII_CONFIG_ROUTING_H__ +#define __HII_CONFIG_ROUTING_H__ + +#define EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \ + { 0x587e72d7, 0xcc50, 0x4f79, { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } } + +typedef struct _EFI_HII_CONFIG_ROUTING_PROTOCOL EFI_HII_CONFIG_ROUTING_PROTOCOL; + +/** + + This function allows the caller to request the current + configuration for one or more named elements from one or more + drivers. The resulting string is in the standard HII + configuration string format. If Successful, Results contains an + equivalent string with "=" and the values associated with all + names added in. The expected implementation is for each + <ConfigRequest> substring in the Request to call the HII + Configuration Routing Protocol ExtractProtocol function for the + driver corresponding to the <ConfigHdr> at the start of the + <ConfigRequest> substring. The request fails if no driver + matches the <ConfigRequest> substring. Note: Alternative + configuration strings may also be appended to the end of the + current configuration string. If they are, they must appear + after the current configuration. They must contain the same + routing (GUID, NAME, PATH) as the current configuration string. + They must have an additional description indicating the type of + alternative configuration the string represents, + "ALTCFG=<StringToken>". That <StringToken> (when converted from + hexadecimal (encoded as text) to binary) is a reference to a string in the + associated string pack. As an example, assume that the Request + string is: + GUID=...&NAME=00480050&PATH=...&Fred&George&Ron&Neville A result + might be: + GUID=...&NAME=00480050&PATH=...&Fred=16&George=16&Ron=12&Neville=11& + GUID=...&NAME=00480050&PATH=...&ALTCFG=0037&Fred=12&Neville=7 + + @param This Points to the EFI_HII_CONFIG_ROUTING_PROTOCOL + instance. + + @param Request A null-terminated string in <MultiConfigRequest> format. + + @param Progress On return, points to a character in the + Request string. Points to the string's null + terminator if the request was successful. Points + to the most recent '&' before the first + failing name / value pair (or the beginning + of the string if the failure is in the first + name / value pair) if the request was not + successful + + @param Results A null-terminated string in <MultiConfigAltResp> format + which has all values filled in for the names in the + Request string. + + @retval EFI_SUCCESS The Results string is filled with the + values corresponding to all requested + names. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the + parts of the results that must be + stored awaiting possible future + protocols. + + @retval EFI_INVALID_PARAMETER For example, passing in a NULL + for the Request parameter + would result in this type of + error. The Progress parameter + is set to NULL. + + @retval EFI_NOT_FOUND Routing data doesn't match any + known driver. Progress set to + the "G" in "GUID" of the + routing header that doesn't + match. Note: There is no + requirement that all routing + data be validated before any + configuration extraction. + + @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set + to the most recent & before the + error, or the beginning of the + string. + @retval EFI_INVALID_PARAMETER The ExtractConfig function of the + underlying HII Configuration + Access Protocol returned + EFI_INVALID_PARAMETER. Progress + set to most recent & before the + error or the beginning of the + string. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_EXTRACT_CONFIG)( + IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ); + +/** + This function allows the caller to request the current configuration + for the entirety of the current HII database and returns the data in + a null-terminated string. + + This function allows the caller to request the current + configuration for all of the current HII database. The results + include both the current and alternate configurations as + described in ExtractConfig() above. + + @param This Points to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance. + + @param Results Null-terminated Unicode string in + <MultiConfigAltResp> format which has all values + filled in for the entirety of the current HII + database. String to be allocated by the called + function. De-allocation is up to the caller. + + @retval EFI_SUCCESS The Results string is filled with the + values corresponding to all requested + names. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the + parts of the results that must be + stored awaiting possible future + protocols. + + @retval EFI_INVALID_PARAMETERS For example, passing in a NULL + for the Results parameter + would result in this type of + error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_EXPORT_CONFIG)( + IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, + OUT EFI_STRING *Results + ); + +/** + + This function routes the results of processing forms to the + appropriate targets. It scans for <ConfigHdr> within the string + and passes the header and subsequent body to the driver whose + location is described in the <ConfigHdr>. Many <ConfigHdr>s may + appear as a single request. The expected implementation is to + hand off the various <ConfigResp> substrings to the + Configuration Access Protocol RouteConfig routine corresponding + to the driver whose routing information is defined by the + <ConfigHdr> in turn. + + @param This Points to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance. + + @param Configuration A null-terminated string in <MulltiConfigResp> format. + + @param Progress A pointer to a string filled in with the + offset of the most recent '&' before the + first failing name / value pair (or the + beginning of the string if the failure is in + the first name / value pair), or the + terminating NULL if all was successful. + + @retval EFI_SUCCESS The results have been distributed or are + awaiting distribution. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the + parts of the results that must be + stored awaiting possible future + protocols. + + @retval EFI_INVALID_PARAMETERS Passing in a NULL for the + Results parameter would result + in this type of error. + + @retval EFI_NOT_FOUND The target for the specified routing data + was not found. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_ROUTE_CONFIG)( + IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ); + +/** + + This function extracts the current configuration from a block of + bytes. To do so, it requires that the ConfigRequest string + consists of a list of <BlockName> formatted names. It uses the + offset in the name to determine the index into the Block to + start the extraction and the width of each name to determine the + number of bytes to extract. These are mapped to a string + using the equivalent of the C "%x" format (with optional leading + spaces). The call fails if, for any (offset, width) pair in + ConfigRequest, offset+value >= BlockSize. + + @param This Points to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance. + + @param ConfigRequest A null-terminated string in <ConfigRequest> format. + + @param Block An array of bytes defining the block's + configuration. + + @param BlockSize The length in bytes of Block. + + @param Config The filled-in configuration string. String + allocated by the function. Returned only if + call is successful. The null-terminated string + will be <ConfigResp> format. + + @param Progress A pointer to a string filled in with the + offset of the most recent '&' before the + first failing name / value pair (or the + beginning of the string if the failure is in + the first name / value pair), or the + terminating NULL if all was successful. + + @retval EFI_SUCCESS The request succeeded. Progress points + to the null terminator at the end of the + ConfigRequest string. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate + Config. Progress points to the + first character of ConfigRequest. + + @retval EFI_INVALID_PARAMETERS Passing in a NULL for the + ConfigRequest or Block + parameter would result in this + type of error. Progress points + to the first character of + ConfigRequest. + + @retval EFI_NOT_FOUND The target for the specified routing data + was not found. Progress points to the + 'G' in "GUID" of the errant routing + data. + @retval EFI_DEVICE_ERROR The block is not large enough. Progress undefined. + + @retval EFI_INVALID_PARAMETER Encountered non <BlockName> + formatted string. Block is + left updated and Progress + points at the '&' preceding + the first non-<BlockName>. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_BLOCK_TO_CONFIG)( + IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, + IN CONST EFI_STRING ConfigRequest, + IN CONST UINT8 *Block, + IN CONST UINTN BlockSize, + OUT EFI_STRING *Config, + OUT EFI_STRING *Progress + ); + +/** + This function maps a configuration containing a series of + <BlockConfig> formatted name value pairs in ConfigResp into a + Block so it may be stored in a linear mapped storage such as a + UEFI Variable. If present, the function skips GUID, NAME, and + PATH in <ConfigResp>. It stops when it finds a non-<BlockConfig> + name / value pair (after skipping the routing header) or when it + reaches the end of the string. + Example Assume an existing block containing: 00 01 02 03 04 05 + And the ConfigResp string is: + OFFSET=4&WIDTH=1&VALUE=7&OFFSET=0&WIDTH=2&VALUE=AA55 + The results are + 55 AA 02 07 04 05 + + @param This Points to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance. + + @param ConfigResp A null-terminated string in <ConfigResp> format. + + @param Block A possibly null array of bytes + representing the current block. Only + bytes referenced in the ConfigResp + string in the block are modified. If + this parameter is null or if the + BlockLength parameter is (on input) + shorter than required by the + Configuration string, only the BlockSize + parameter is updated, and an appropriate + status (see below) is returned. + + @param BlockSize The length of the Block in units of UINT8. + On input, this is the size of the Block. On + output, if successful, contains the largest + index of the modified byte in the Block, or + the required buffer size if the Block is not + large enough. + + @param Progress On return, points to an element of the + ConfigResp string filled in with the offset + of the most recent "&" before the first + failing name / value pair (or the beginning + of the string if the failure is in the first + name / value pair), or the terminating NULL + if all was successful. + + @retval EFI_SUCCESS The request succeeded. Progress points to the null + terminator at the end of the ConfigResp string. + @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate Config. Progress + points to the first character of ConfigResp. + @retval EFI_INVALID_PARAMETER Passing in a NULL for the ConfigResp or + Block parameter would result in this type of + error. Progress points to the first character of + ConfigResp. + @retval EFI_INVALID_PARAMETER Encountered non <BlockName> formatted name / + value pair. Block is left updated and + Progress points at the '&' preceding the first + non-<BlockName>. + @retval EFI_DEVICE_ERROR Block not large enough. Progress undefined. + @retval EFI_NOT_FOUND Target for the specified routing data was not found. + Progress points to the "G" in "GUID" of the errant + routing data. + @retval EFI_BUFFER_TOO_SMALL Block not large enough. Progress undefined. + BlockSize is updated with the required buffer size. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_CONFIG_TO_BLOCK)( + IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, + IN CONST EFI_STRING ConfigResp, + IN OUT UINT8 *Block, + IN OUT UINTN *BlockSize, + OUT EFI_STRING *Progress + ); + +/** + This helper function is to be called by drivers to extract portions of + a larger configuration string. + + @param This A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance. + @param ConfigResp A null-terminated string in <ConfigAltResp> format. + @param Guid A pointer to the GUID value to search for in the + routing portion of the ConfigResp string when retrieving + the requested data. If Guid is NULL, then all GUID + values will be searched for. + @param Name A pointer to the NAME value to search for in the + routing portion of the ConfigResp string when retrieving + the requested data. If Name is NULL, then all Name + values will be searched for. + @param DevicePath A pointer to the PATH value to search for in the + routing portion of the ConfigResp string when retrieving + the requested data. If DevicePath is NULL, then all + DevicePath values will be searched for. + @param AltCfgId A pointer to the ALTCFG value to search for in the + routing portion of the ConfigResp string when retrieving + the requested data. If this parameter is NULL, + then the current setting will be retrieved. + @param AltCfgResp A pointer to a buffer which will be allocated by the + function which contains the retrieved string as requested. + This buffer is only allocated if the call was successful. + The null-terminated string will be <ConfigResp> format. + + @retval EFI_SUCCESS The request succeeded. The requested data was extracted + and placed in the newly allocated AltCfgResp buffer. + @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate AltCfgResp. + @retval EFI_INVALID_PARAMETER Any parameter is invalid. + @retval EFI_NOT_FOUND The target for the specified routing data was not found. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_ALT_CFG)( + IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, + IN CONST EFI_STRING ConfigResp, + IN CONST EFI_GUID *Guid, + IN CONST EFI_STRING Name, + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CONST UINT16 *AltCfgId, + OUT EFI_STRING *AltCfgResp + ); + +/// +/// This protocol defines the configuration routing interfaces +/// between external applications and the HII. There may only be one +/// instance of this protocol in the system. +/// +struct _EFI_HII_CONFIG_ROUTING_PROTOCOL { + EFI_HII_EXTRACT_CONFIG ExtractConfig; + EFI_HII_EXPORT_CONFIG ExportConfig; + EFI_HII_ROUTE_CONFIG RouteConfig; + EFI_HII_BLOCK_TO_CONFIG BlockToConfig; + EFI_HII_CONFIG_TO_BLOCK ConfigToBlock; + EFI_HII_GET_ALT_CFG GetAltConfig; +}; + +extern EFI_GUID gEfiHiiConfigRoutingProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/HiiDatabase.h b/sys/contrib/edk2/Include/Protocol/HiiDatabase.h new file mode 100644 index 000000000000..f6d6f2c0fea7 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/HiiDatabase.h @@ -0,0 +1,518 @@ +/** @file + The file provides Database manager for HII-related data + structures. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol was introduced in UEFI Specification 2.1. + +**/ + +#ifndef __HII_DATABASE_H__ +#define __HII_DATABASE_H__ + +#define EFI_HII_DATABASE_PROTOCOL_GUID \ + { 0xef9fc172, 0xa1b2, 0x4693, { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } } + +typedef struct _EFI_HII_DATABASE_PROTOCOL EFI_HII_DATABASE_PROTOCOL; + +/// +/// EFI_HII_DATABASE_NOTIFY_TYPE. +/// +typedef UINTN EFI_HII_DATABASE_NOTIFY_TYPE; + +#define EFI_HII_DATABASE_NOTIFY_NEW_PACK 0x00000001 +#define EFI_HII_DATABASE_NOTIFY_REMOVE_PACK 0x00000002 +#define EFI_HII_DATABASE_NOTIFY_EXPORT_PACK 0x00000004 +#define EFI_HII_DATABASE_NOTIFY_ADD_PACK 0x00000008 + +/** + + Functions which are registered to receive notification of + database events have this prototype. The actual event is encoded + in NotifyType. The following table describes how PackageType, + PackageGuid, Handle, and Package are used for each of the + notification types. + + @param PackageType Package type of the notification. + + @param PackageGuid If PackageType is + EFI_HII_PACKAGE_TYPE_GUID, then this is + the pointer to the GUID from the Guid + field of EFI_HII_PACKAGE_GUID_HEADER. + Otherwise, it must be NULL. + + @param Package Points to the package referred to by the notification. + + @param Handle The handle of the package + list which contains the specified package. + + @param NotifyType The type of change concerning the + database. See + EFI_HII_DATABASE_NOTIFY_TYPE. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_DATABASE_NOTIFY)( + IN UINT8 PackageType, + IN CONST EFI_GUID *PackageGuid, + IN CONST EFI_HII_PACKAGE_HEADER *Package, + IN EFI_HII_HANDLE Handle, + IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType + ); + +/** + + This function adds the packages in the package list to the + database and returns a handle. If there is a + EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then + this function will create a package of type + EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list. For + each package in the package list, registered functions with the + notification type NEW_PACK and having the same package type will + be called. For each call to NewPackageList(), there should be a + corresponding call to + EFI_HII_DATABASE_PROTOCOL.RemovePackageList(). + + @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. + + @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER structure. + + @param DriverHandle Associate the package list with this EFI handle. + If a NULL is specified, this data will not be associate + with any drivers and cannot have a callback induced. + + @param Handle A pointer to the EFI_HII_HANDLE instance. + + @retval EFI_SUCCESS The package list associated with the + Handle was added to the HII database. + + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary + resources for the new database + contents. + + @retval EFI_INVALID_PARAMETER PackageList is NULL, or Handle is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_DATABASE_NEW_PACK)( + IN CONST EFI_HII_DATABASE_PROTOCOL *This, + IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList, + IN EFI_HANDLE DriverHandle OPTIONAL, + OUT EFI_HII_HANDLE *Handle + ); + +/** + + This function removes the package list that is associated with a + handle Handle from the HII database. Before removing the + package, any registered functions with the notification type + REMOVE_PACK and the same package type will be called. For each + call to EFI_HII_DATABASE_PROTOCOL.NewPackageList(), there should + be a corresponding call to RemovePackageList. + + @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. + + @param Handle The handle that was registered to the data + that is requested for removal. + + @retval EFI_SUCCESS The data associated with the Handle was + removed from the HII database. + @retval EFI_NOT_FOUND The specified Handle is not in database. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_DATABASE_REMOVE_PACK)( + IN CONST EFI_HII_DATABASE_PROTOCOL *This, + IN EFI_HII_HANDLE Handle + ); + +/** + + This function updates the existing package list (which has the + specified Handle) in the HII databases, using the new package + list specified by PackageList. The update process has the + following steps: Collect all the package types in the package + list specified by PackageList. A package type consists of the + Type field of EFI_HII_PACKAGE_HEADER and, if the Type is + EFI_HII_PACKAGE_TYPE_GUID, the Guid field, as defined in + EFI_HII_PACKAGE_GUID_HEADER. Iterate through the packages within + the existing package list in the HII database specified by + Handle. If a package's type matches one of the collected types collected + in step 1, then perform the following steps: + - Call any functions registered with the notification type + REMOVE_PACK. + - Remove the package from the package list and the HII + database. + Add all of the packages within the new package list specified + by PackageList, using the following steps: + - Add the package to the package list and the HII database. + - Call any functions registered with the notification type + ADD_PACK. + + @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. + + @param Handle The handle that was registered to the data + that is requested for removal. + + @param PackageList A pointer to an EFI_HII_PACKAGE_LIST + package. + + @retval EFI_SUCCESS The HII database was successfully updated. + + @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory + for the updated database. + + @retval EFI_INVALID_PARAMETER PackageList was NULL. + @retval EFI_NOT_FOUND The specified Handle is not in database. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_DATABASE_UPDATE_PACK)( + IN CONST EFI_HII_DATABASE_PROTOCOL *This, + IN EFI_HII_HANDLE Handle, + IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList + ); + +/** + + This function returns a list of the package handles of the + specified type that are currently active in the database. The + pseudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package + handles to be listed. + + @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. + + @param PackageType Specifies the package type of the packages + to list or EFI_HII_PACKAGE_TYPE_ALL for + all packages to be listed. + + @param PackageGuid If PackageType is + EFI_HII_PACKAGE_TYPE_GUID, then this is + the pointer to the GUID which must match + the Guid field of + EFI_HII_PACKAGE_GUID_HEADER. Otherwise, it + must be NULL. + + @param HandleBufferLength On input, a pointer to the length + of the handle buffer. On output, + the length of the handle buffer + that is required for the handles found. + + @param Handle An array of EFI_HII_HANDLE instances returned. + + @retval EFI_SUCCESS The matching handles are outputted successfully. + HandleBufferLength is updated with the actual length. + @retval EFI_BUFFER_TOO_SMALL The HandleBufferLength parameter + indicates that Handle is too + small to support the number of + handles. HandleBufferLength is + updated with a value that will + enable the data to fit. + @retval EFI_NOT_FOUND No matching handle could be found in database. + @retval EFI_INVALID_PARAMETER HandleBufferLength was NULL. + @retval EFI_INVALID_PARAMETER The value referenced by HandleBufferLength was not + zero and Handle was NULL. + @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but + PackageGuid is not NULL, PackageType is a EFI_HII_ + PACKAGE_TYPE_GUID but PackageGuid is NULL. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_DATABASE_LIST_PACKS)( + IN CONST EFI_HII_DATABASE_PROTOCOL *This, + IN UINT8 PackageType, + IN CONST EFI_GUID *PackageGuid, + IN OUT UINTN *HandleBufferLength, + OUT EFI_HII_HANDLE *Handle + ); + +/** + + This function will export one or all package lists in the + database to a buffer. For each package list exported, this + function will call functions registered with EXPORT_PACK and + then copy the package list to the buffer. The registered + functions may call EFI_HII_DATABASE_PROTOCOL.UpdatePackageList() + to modify the package list before it is copied to the buffer. If + the specified BufferSize is too small, then the status + EFI_OUT_OF_RESOURCES will be returned and the actual package + size will be returned in BufferSize. + + @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. + + + @param Handle An EFI_HII_HANDLE that corresponds to the + desired package list in the HII database to + export or NULL to indicate all package lists + should be exported. + + @param BufferSize On input, a pointer to the length of the + buffer. On output, the length of the + buffer that is required for the exported + data. + + @param Buffer A pointer to a buffer that will contain the + results of the export function. + + + @retval EFI_SUCCESS Package exported. + + @retval EFI_OUT_OF_RESOURCES BufferSize is too small to hold the package. + + @retval EFI_NOT_FOUND The specified Handle could not be found in the + current database. + + @retval EFI_INVALID_PARAMETER BufferSize was NULL. + + @retval EFI_INVALID_PARAMETER The value referenced by BufferSize was not zero + and Buffer was NULL. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_DATABASE_EXPORT_PACKS)( + IN CONST EFI_HII_DATABASE_PROTOCOL *This, + IN EFI_HII_HANDLE Handle, + IN OUT UINTN *BufferSize, + OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer + ); + +/** + + + This function registers a function which will be called when + specified actions related to packages of the specified type + occur in the HII database. By registering a function, other + HII-related drivers are notified when specific package types + are added, removed or updated in the HII database. Each driver + or application which registers a notification should use + EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before + exiting. + + + @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. + + @param PackageType The package type. See + EFI_HII_PACKAGE_TYPE_x in EFI_HII_PACKAGE_HEADER. + + @param PackageGuid If PackageType is + EFI_HII_PACKAGE_TYPE_GUID, then this is + the pointer to the GUID which must match + the Guid field of + EFI_HII_PACKAGE_GUID_HEADER. Otherwise, it + must be NULL. + + @param PackageNotifyFn Points to the function to be called + when the event specified by + NotificationType occurs. See + EFI_HII_DATABASE_NOTIFY. + + @param NotifyType Describes the types of notification which + this function will be receiving. See + EFI_HII_DATABASE_NOTIFY_TYPE for a + list of types. + + @param NotifyHandle Points to the unique handle assigned to + the registered notification. Can be used + in EFI_HII_DATABASE_PROTOCOL.UnregisterPack + to stop notifications. + + + @retval EFI_SUCCESS Notification registered successfully. + + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary + data structures. + + @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when + PackageType is not + EFI_HII_PACKAGE_TYPE_GUID. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_DATABASE_REGISTER_NOTIFY)( + IN CONST EFI_HII_DATABASE_PROTOCOL *This, + IN UINT8 PackageType, + IN CONST EFI_GUID *PackageGuid, + IN EFI_HII_DATABASE_NOTIFY PackageNotifyFn, + IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, + OUT EFI_HANDLE *NotifyHandle + ); + +/** + + Removes the specified HII database package-related notification. + + @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance. + + @param NotificationHandle The handle of the notification + function being unregistered. + + @retval EFI_SUCCESS Successsfully unregistered the notification. + + @retval EFI_NOT_FOUND The incoming notification handle does not exist + in the current hii database. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_DATABASE_UNREGISTER_NOTIFY)( + IN CONST EFI_HII_DATABASE_PROTOCOL *This, + IN EFI_HANDLE NotificationHandle + ); + +/** + + This routine retrieves an array of GUID values for each keyboard + layout that was previously registered in the system. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param KeyGuidBufferLength On input, a pointer to the length + of the keyboard GUID buffer. On + output, the length of the handle + buffer that is required for the + handles found. + + @param KeyGuidBuffer An array of keyboard layout GUID + instances returned. + + @retval EFI_SUCCESS KeyGuidBuffer was updated successfully. + + @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength + parameter indicates that + KeyGuidBuffer is too small to + support the number of GUIDs. + KeyGuidBufferLength is updated + with a value that will enable + the data to fit. + @retval EFI_INVALID_PARAMETER The KeyGuidBufferLength is NULL. + @retval EFI_INVALID_PARAMETER The value referenced by + KeyGuidBufferLength is not + zero and KeyGuidBuffer is NULL. + @retval EFI_NOT_FOUND There was no keyboard layout. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_FIND_KEYBOARD_LAYOUTS)( + IN CONST EFI_HII_DATABASE_PROTOCOL *This, + IN OUT UINT16 *KeyGuidBufferLength, + OUT EFI_GUID *KeyGuidBuffer + ); + +/** + + This routine retrieves the requested keyboard layout. The layout + is a physical description of the keys on a keyboard, and the + character(s) that are associated with a particular set of key + strokes. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param KeyGuid A pointer to the unique ID associated with a + given keyboard layout. If KeyGuid is NULL then + the current layout will be retrieved. + + @param KeyboardLayoutLength On input, a pointer to the length of the + KeyboardLayout buffer. On output, the length of + the data placed into KeyboardLayout. + + @param KeyboardLayout A pointer to a buffer containing the + retrieved keyboard layout. + + @retval EFI_SUCCESS The keyboard layout was retrieved + successfully. + + @retval EFI_NOT_FOUND The requested keyboard layout was not found. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_KEYBOARD_LAYOUT)( + IN CONST EFI_HII_DATABASE_PROTOCOL *This, + IN CONST EFI_GUID *KeyGuid, + IN OUT UINT16 *KeyboardLayoutLength, + OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout + ); + +/** + + This routine sets the default keyboard layout to the one + referenced by KeyGuid. When this routine is called, an event + will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID + group type. This is so that agents which are sensitive to the + current keyboard layout being changed can be notified of this + change. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param KeyGuid A pointer to the unique ID associated with a + given keyboard layout. + + @retval EFI_SUCCESS The current keyboard layout was successfully set. + + @retval EFI_NOT_FOUND The referenced keyboard layout was not + found, so action was taken. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_SET_KEYBOARD_LAYOUT)( + IN CONST EFI_HII_DATABASE_PROTOCOL *This, + IN CONST EFI_GUID *KeyGuid + ); + +/** + + Return the EFI handle associated with a package list. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param PackageListHandle An EFI_HII_HANDLE that corresponds + to the desired package list in the + HIIdatabase. + + @param DriverHandle On return, contains the EFI_HANDLE which + was registered with the package list in + NewPackageList(). + + @retval EFI_SUCCESS The DriverHandle was returned successfully. + + @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_DATABASE_GET_PACK_HANDLE)( + IN CONST EFI_HII_DATABASE_PROTOCOL *This, + IN EFI_HII_HANDLE PackageListHandle, + OUT EFI_HANDLE *DriverHandle + ); + +/// +/// Database manager for HII-related data structures. +/// +struct _EFI_HII_DATABASE_PROTOCOL { + EFI_HII_DATABASE_NEW_PACK NewPackageList; + EFI_HII_DATABASE_REMOVE_PACK RemovePackageList; + EFI_HII_DATABASE_UPDATE_PACK UpdatePackageList; + EFI_HII_DATABASE_LIST_PACKS ListPackageLists; + EFI_HII_DATABASE_EXPORT_PACKS ExportPackageLists; + EFI_HII_DATABASE_REGISTER_NOTIFY RegisterPackageNotify; + EFI_HII_DATABASE_UNREGISTER_NOTIFY UnregisterPackageNotify; + EFI_HII_FIND_KEYBOARD_LAYOUTS FindKeyboardLayouts; + EFI_HII_GET_KEYBOARD_LAYOUT GetKeyboardLayout; + EFI_HII_SET_KEYBOARD_LAYOUT SetKeyboardLayout; + EFI_HII_DATABASE_GET_PACK_HANDLE GetPackageListHandle; +}; + +extern EFI_GUID gEfiHiiDatabaseProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/HiiFont.h b/sys/contrib/edk2/Include/Protocol/HiiFont.h new file mode 100644 index 000000000000..392352d6b3fc --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/HiiFont.h @@ -0,0 +1,464 @@ +/** @file + The file provides services to retrieve font information. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol was introduced in UEFI Specification 2.1. + +**/ + +#ifndef __HII_FONT_H__ +#define __HII_FONT_H__ + +#include <Protocol/GraphicsOutput.h> +#include <Protocol/HiiImage.h> + +#define EFI_HII_FONT_PROTOCOL_GUID \ +{ 0xe9ca4775, 0x8657, 0x47fc, { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } } + +typedef struct _EFI_HII_FONT_PROTOCOL EFI_HII_FONT_PROTOCOL; + +typedef VOID *EFI_FONT_HANDLE; + +/// +/// EFI_HII_OUT_FLAGS. +/// +typedef UINT32 EFI_HII_OUT_FLAGS; + +#define EFI_HII_OUT_FLAG_CLIP 0x00000001 +#define EFI_HII_OUT_FLAG_WRAP 0x00000002 +#define EFI_HII_OUT_FLAG_CLIP_CLEAN_Y 0x00000004 +#define EFI_HII_OUT_FLAG_CLIP_CLEAN_X 0x00000008 +#define EFI_HII_OUT_FLAG_TRANSPARENT 0x00000010 +#define EFI_HII_IGNORE_IF_NO_GLYPH 0x00000020 +#define EFI_HII_IGNORE_LINE_BREAK 0x00000040 +#define EFI_HII_DIRECT_TO_SCREEN 0x00000080 + +/** + Definition of EFI_HII_ROW_INFO. +**/ +typedef struct _EFI_HII_ROW_INFO { + /// + /// The index of the first character in the string which is displayed on the line. + /// + UINTN StartIndex; + /// + /// The index of the last character in the string which is displayed on the line. + /// If this is the same as StartIndex, then no characters are displayed. + /// + UINTN EndIndex; + UINTN LineHeight; ///< The height of the line, in pixels. + UINTN LineWidth; ///< The width of the text on the line, in pixels. + + /// + /// The font baseline offset in pixels from the bottom of the row, or 0 if none. + /// + UINTN BaselineOffset; +} EFI_HII_ROW_INFO; + +/// +/// Font info flag. All flags (FONT, SIZE, STYLE, and COLOR) are defined. +/// They are defined as EFI_FONT_INFO_*** +/// +typedef UINT32 EFI_FONT_INFO_MASK; + +#define EFI_FONT_INFO_SYS_FONT 0x00000001 +#define EFI_FONT_INFO_SYS_SIZE 0x00000002 +#define EFI_FONT_INFO_SYS_STYLE 0x00000004 +#define EFI_FONT_INFO_SYS_FORE_COLOR 0x00000010 +#define EFI_FONT_INFO_SYS_BACK_COLOR 0x00000020 +#define EFI_FONT_INFO_RESIZE 0x00001000 +#define EFI_FONT_INFO_RESTYLE 0x00002000 +#define EFI_FONT_INFO_ANY_FONT 0x00010000 +#define EFI_FONT_INFO_ANY_SIZE 0x00020000 +#define EFI_FONT_INFO_ANY_STYLE 0x00040000 + +// +// EFI_FONT_INFO +// +typedef struct { + EFI_HII_FONT_STYLE FontStyle; + UINT16 FontSize; ///< character cell height in pixels + CHAR16 FontName[1]; +} EFI_FONT_INFO; + +/** + Describes font output-related information. + + This structure is used for describing the way in which a string + should be rendered in a particular font. FontInfo specifies the + basic font information and ForegroundColor and BackgroundColor + specify the color in which they should be displayed. The flags + in FontInfoMask describe where the system default should be + supplied instead of the specified information. The flags also + describe what options can be used to make a match between the + font requested and the font available. +**/ +typedef struct _EFI_FONT_DISPLAY_INFO { + EFI_GRAPHICS_OUTPUT_BLT_PIXEL ForegroundColor; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL BackgroundColor; + EFI_FONT_INFO_MASK FontInfoMask; + EFI_FONT_INFO FontInfo; +} EFI_FONT_DISPLAY_INFO; + +/** + + This function renders a string to a bitmap or the screen using + the specified font, color and options. It either draws the + string and glyphs on an existing bitmap, allocates a new bitmap, + or uses the screen. The strings can be clipped or wrapped. + Optionally, the function also returns the information about each + row and the character position on that row. If + EFI_HII_OUT_FLAG_CLIP is set, then text will be formatted only + based on explicit line breaks and all pixels which would lie + outside the bounding box specified by Width and Height are + ignored. The information in the RowInfoArray only describes + characters which are at least partially displayed. For the final + row, the LineHeight and BaseLine may describe pixels that are + outside the limit specified by Height (unless + EFI_HII_OUT_FLAG_CLIP_CLEAN_Y is specified) even though those + pixels were not drawn. The LineWidth may describe pixels which + are outside the limit specified by Width (unless + EFI_HII_OUT_FLAG_CLIP_CLEAN_X is specified) even though those + pixels were not drawn. If EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set, + then it modifies the behavior of EFI_HII_OUT_FLAG_CLIP so that + if a character's right-most on pixel cannot fit, then it will + not be drawn at all. This flag requires that + EFI_HII_OUT_FLAG_CLIP be set. If EFI_HII_OUT_FLAG_CLIP_CLEAN_Y + is set, then it modifies the behavior of EFI_HII_OUT_FLAG_CLIP + so that if a row's bottom-most pixel cannot fit, then it will + not be drawn at all. This flag requires that + EFI_HII_OUT_FLAG_CLIP be set. If EFI_HII_OUT_FLAG_WRAP is set, + then text will be wrapped at the right-most line-break + opportunity prior to a character whose right-most extent would + exceed Width. If no line-break opportunity can be found, then + the text will behave as if EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set. + This flag cannot be used with EFI_HII_OUT_FLAG_CLIP_CLEAN_X. If + EFI_HII_OUT_FLAG_TRANSPARENT is set, then BackgroundColor is + ignored and all 'off' pixels in the character's drawn + will use the pixel value from Blt. This flag cannot be used if + Blt is NULL upon entry. If EFI_HII_IGNORE_IF_NO_GLYPH is set, + then characters which have no glyphs are not drawn. Otherwise, + they are replaced with Unicode character code 0xFFFD (REPLACEMENT + CHARACTER). If EFI_HII_IGNORE_LINE_BREAK is set, then explicit + line break characters will be ignored. If + EFI_HII_DIRECT_TO_SCREEN is set, then the string will be written + directly to the output device specified by Screen. Otherwise the + string will be rendered to the bitmap specified by Bitmap. + + @param This A pointer to the EFI_HII_FONT_PROTOCOL instance. + + @param Flags Describes how the string is to be drawn. + + @param String Points to the null-terminated string to be + + @param StringInfo Points to the string output information, + including the color and font. If NULL, then + the string will be output in the default + system font and color. + + @param Blt If this points to a non-NULL on entry, this points + to the image, which is Width pixels wide and + Height pixels high. The string will be drawn onto + this image and EFI_HII_OUT_FLAG_CLIP is implied. + If this points to a NULL on entry, then a buffer + will be allocated to hold the generated image and + the pointer updated on exit. It is the caller's + responsibility to free this buffer. + + @param BltX, BltY Specifies the offset from the left and top + edge of the image of the first character + cell in the image. + + @param RowInfoArray If this is non-NULL on entry, then on + exit, this will point to an allocated buffer + containing row information and + RowInfoArraySize will be updated to contain + the number of elements. This array describes + the characters that were at least partially + drawn and the heights of the rows. It is the + caller's responsibility to free this buffer. + + @param RowInfoArraySize If this is non-NULL on entry, then on + exit it contains the number of + elements in RowInfoArray. + + @param ColumnInfoArray If this is non-NULL, then on return it + will be filled with the horizontal + offset for each character in the + string on the row where it is + displayed. Non-printing characters + will have the offset ~0. The caller is + responsible for allocating a buffer large + enough so that there is one entry for + each character in the string, not + including the null-terminator. It is + possible when character display is + normalized that some character cells + overlap. + + @retval EFI_SUCCESS The string was successfully updated. + + @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for RowInfoArray or Blt. + + @retval EFI_INVALID_PARAMETER The String or Blt was NULL. + + @retval EFI_INVALID_PARAMETER Flags were invalid combination. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_STRING_TO_IMAGE)( + IN CONST EFI_HII_FONT_PROTOCOL *This, + IN EFI_HII_OUT_FLAGS Flags, + IN CONST EFI_STRING String, + IN CONST EFI_FONT_DISPLAY_INFO *StringInfo, + IN OUT EFI_IMAGE_OUTPUT **Blt, + IN UINTN BltX, + IN UINTN BltY, + OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL, + OUT UINTN *RowInfoArraySize OPTIONAL, + OUT UINTN *ColumnInfoArray OPTIONAL + ); + +/** + + This function renders a string as a bitmap or to the screen + and can clip or wrap the string. The bitmap is either supplied + by the caller or allocated by the function. The + strings are drawn with the font, size and style specified and + can be drawn transparently or opaquely. The function can also + return information about each row and each character's + position on the row. If EFI_HII_OUT_FLAG_CLIP is set, then + text will be formatted based only on explicit line breaks, and + all pixels that would lie outside the bounding box specified + by Width and Height are ignored. The information in the + RowInfoArray only describes characters which are at least + partially displayed. For the final row, the LineHeight and + BaseLine may describe pixels which are outside the limit + specified by Height (unless EFI_HII_OUT_FLAG_CLIP_CLEAN_Y is + specified) even though those pixels were not drawn. If + EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set, then it modifies the + behavior of EFI_HII_OUT_FLAG_CLIP so that if a character's + right-most on pixel cannot fit, then it will not be drawn at + all. This flag requires that EFI_HII_OUT_FLAG_CLIP be set. If + EFI_HII_OUT_FLAG_CLIP_CLEAN_Y is set, then it modifies the + behavior of EFI_HII_OUT_FLAG_CLIP so that if a row's bottom + most pixel cannot fit, then it will not be drawn at all. This + flag requires that EFI_HII_OUT_FLAG_CLIP be set. If + EFI_HII_OUT_FLAG_WRAP is set, then text will be wrapped at the + right-most line-break opportunity prior to a character whose + right-most extent would exceed Width. If no line-break + opportunity can be found, then the text will behave as if + EFI_HII_OUT_FLAG_CLIP_CLEAN_X is set. This flag cannot be used + with EFI_HII_OUT_FLAG_CLIP_CLEAN_X. If + EFI_HII_OUT_FLAG_TRANSPARENT is set, then BackgroundColor is + ignored and all off" pixels in the character's glyph will + use the pixel value from Blt. This flag cannot be used if Blt + is NULL upon entry. If EFI_HII_IGNORE_IF_NO_GLYPH is set, then + characters which have no glyphs are not drawn. Otherwise, they + are replaced with Unicode character code 0xFFFD (REPLACEMENT + CHARACTER). If EFI_HII_IGNORE_LINE_BREAK is set, then explicit + line break characters will be ignored. If + EFI_HII_DIRECT_TO_SCREEN is set, then the string will be + written directly to the output device specified by Screen. + Otherwise the string will be rendered to the bitmap specified + by Bitmap. + + + @param This A pointer to the EFI_HII_FONT_PROTOCOL instance. + + @param Flags Describes how the string is to be drawn. + + @param PackageList + The package list in the HII database to + search for the specified string. + + @param StringId The string's id, which is unique within + PackageList. + + @param Language Points to the language for the retrieved + string. If NULL, then the current system + language is used. + + @param StringInfo Points to the string output information, + including the color and font. If NULL, then + the string will be output in the default + system font and color. + + @param Blt If this points to a non-NULL on entry, this points + to the image, which is Width pixels wide and + Height pixels high. The string will be drawn onto + this image and EFI_HII_OUT_FLAG_CLIP is implied. + If this points to a NULL on entry, then a buffer + will be allocated to hold the generated image and + the pointer updated on exit. It is the caller's + responsibility to free this buffer. + + @param BltX, BltY Specifies the offset from the left and top + edge of the output image of the first + character cell in the image. + + @param RowInfoArray If this is non-NULL on entry, then on + exit, this will point to an allocated + buffer containing row information and + RowInfoArraySize will be updated to + contain the number of elements. This array + describes the characters which were at + least partially drawn and the heights of + the rows. It is the caller's + responsibility to free this buffer. + + @param RowInfoArraySize If this is non-NULL on entry, then on + exit it contains the number of + elements in RowInfoArray. + + @param ColumnInfoArray If non-NULL, on return it is filled + with the horizontal offset for each + character in the string on the row + where it is displayed. Non-printing + characters will have the offset ~0. + The caller is responsible to allocate + a buffer large enough so that there is + one entry for each character in the + string, not including the + null-terminator. It is possible when + character display is normalized that + some character cells overlap. + + + @retval EFI_SUCCESS The string was successfully updated. + + @retval EFI_OUT_OF_RESOURCES Unable to allocate an output + buffer for RowInfoArray or Blt. + + @retval EFI_INVALID_PARAMETER The String, or Blt, or Height, or + Width was NULL. + @retval EFI_INVALID_PARAMETER The Blt or PackageList was NULL. + @retval EFI_INVALID_PARAMETER Flags were invalid combination. + @retval EFI_NOT_FOUND The specified PackageList is not in the Database, + or the stringid is not in the specified PackageList. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_STRING_ID_TO_IMAGE)( + IN CONST EFI_HII_FONT_PROTOCOL *This, + IN EFI_HII_OUT_FLAGS Flags, + IN EFI_HII_HANDLE PackageList, + IN EFI_STRING_ID StringId, + IN CONST CHAR8 *Language, + IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL, + IN OUT EFI_IMAGE_OUTPUT **Blt, + IN UINTN BltX, + IN UINTN BltY, + OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL, + OUT UINTN *RowInfoArraySize OPTIONAL, + OUT UINTN *ColumnInfoArray OPTIONAL + ); + +/** + + Convert the glyph for a single character into a bitmap. + + @param This A pointer to the EFI_HII_FONT_PROTOCOL instance. + + @param Char The character to retrieve. + + @param StringInfo Points to the string font and color + information or NULL if the string should use + the default system font and color. + + @param Blt This must point to a NULL on entry. A buffer will + be allocated to hold the output and the pointer + updated on exit. It is the caller's responsibility + to free this buffer. + + @param Baseline The number of pixels from the bottom of the bitmap + to the baseline. + + + @retval EFI_SUCCESS The glyph bitmap created. + + @retval EFI_OUT_OF_RESOURCES Unable to allocate the output buffer Blt. + + @retval EFI_WARN_UNKNOWN_GLYPH The glyph was unknown and was + replaced with the glyph for + Unicode character code 0xFFFD. + + @retval EFI_INVALID_PARAMETER Blt is NULL, or Width is NULL, or + Height is NULL + + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_GLYPH)( + IN CONST EFI_HII_FONT_PROTOCOL *This, + IN CONST CHAR16 Char, + IN CONST EFI_FONT_DISPLAY_INFO *StringInfo, + OUT EFI_IMAGE_OUTPUT **Blt, + OUT UINTN *Baseline OPTIONAL + ); + +/** + + This function iterates through fonts which match the specified + font, using the specified criteria. If String is non-NULL, then + all of the characters in the string must exist in order for a + candidate font to be returned. + + @param This A pointer to the EFI_HII_FONT_PROTOCOL instance. + + @param FontHandle On entry, points to the font handle returned + by a previous call to GetFontInfo() or NULL + to start with the first font. On return, + points to the returned font handle or points + to NULL if there are no more matching fonts. + + @param StringInfoIn Upon entry, points to the font to return + information about. If NULL, then the information + about the system default font will be returned. + + @param StringInfoOut Upon return, contains the matching font's information. + If NULL, then no information is returned. This buffer + is allocated with a call to the Boot Service AllocatePool(). + It is the caller's responsibility to call the Boot + Service FreePool() when the caller no longer requires + the contents of StringInfoOut. + + @param String Points to the string which will be tested to + determine if all characters are available. If + NULL, then any font is acceptable. + + @retval EFI_SUCCESS Matching font returned successfully. + + @retval EFI_NOT_FOUND No matching font was found. + + @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the request. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_FONT_INFO)( + IN CONST EFI_HII_FONT_PROTOCOL *This, + IN OUT EFI_FONT_HANDLE *FontHandle, + IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn OPTIONAL, + OUT EFI_FONT_DISPLAY_INFO **StringInfoOut, + IN CONST EFI_STRING String OPTIONAL + ); + +/// +/// The protocol provides the service to retrieve the font informations. +/// +struct _EFI_HII_FONT_PROTOCOL { + EFI_HII_STRING_TO_IMAGE StringToImage; + EFI_HII_STRING_ID_TO_IMAGE StringIdToImage; + EFI_HII_GET_GLYPH GetGlyph; + EFI_HII_GET_FONT_INFO GetFontInfo; +}; + +extern EFI_GUID gEfiHiiFontProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/HiiImage.h b/sys/contrib/edk2/Include/Protocol/HiiImage.h new file mode 100644 index 000000000000..34e5acc1ec85 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/HiiImage.h @@ -0,0 +1,346 @@ +/** @file + The file provides services to access to images in the images database. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol was introduced in UEFI Specification 2.1. + +**/ + +#ifndef __HII_IMAGE_H__ +#define __HII_IMAGE_H__ + +#include <Protocol/GraphicsOutput.h> + +#define EFI_HII_IMAGE_PROTOCOL_GUID \ + { 0x31a6406a, 0x6bdf, 0x4e46, { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } } + +typedef struct _EFI_HII_IMAGE_PROTOCOL EFI_HII_IMAGE_PROTOCOL; + +/// +/// Flags in EFI_IMAGE_INPUT +/// +#define EFI_IMAGE_TRANSPARENT 0x00000001 + +/** + + Definition of EFI_IMAGE_INPUT. + + @param Flags Describe image characteristics. If + EFI_IMAGE_TRANSPARENT is set, then the image was + designed for transparent display. + + @param Width Image width, in pixels. + + @param Height Image height, in pixels. + + @param Bitmap A pointer to the actual bitmap, organized left-to-right, + top-to-bottom. The size of the bitmap is + Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL). + + +**/ +typedef struct _EFI_IMAGE_INPUT { + UINT32 Flags; + UINT16 Width; + UINT16 Height; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Bitmap; +} EFI_IMAGE_INPUT; + +/** + + This function adds the image Image to the group of images + owned by PackageList, and returns a new image identifier + (ImageId). + + @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance. + + @param PackageList Handle of the package list where this image will be added. + + @param ImageId On return, contains the new image id, which is + unique within PackageList. + + @param Image Points to the image. + + @retval EFI_SUCCESS The new image was added + successfully + + @retval EFI_OUT_OF_RESOURCES Could not add the image. + + @retval EFI_INVALID_PARAMETER Image is NULL or ImageId is + NULL. + + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_NEW_IMAGE)( + IN CONST EFI_HII_IMAGE_PROTOCOL *This, + IN EFI_HII_HANDLE PackageList, + OUT EFI_IMAGE_ID *ImageId, + IN CONST EFI_IMAGE_INPUT *Image + ); + +/** + + This function retrieves the image specified by ImageId which + is associated with the specified PackageList and copies it + into the buffer specified by Image. If the image specified by + ImageId is not present in the specified PackageList, then + EFI_NOT_FOUND is returned. If the buffer specified by + ImageSize is too small to hold the image, then + EFI_BUFFER_TOO_SMALL will be returned. ImageSize will be + updated to the size of buffer actually required to hold the + image. + + @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance. + + @param PackageList The package list in the HII database to + search for the specified image. + + @param ImageId The image's id, which is unique within + PackageList. + + @param Image Points to the new image. + + @retval EFI_SUCCESS The image was returned successfully. + + @retval EFI_NOT_FOUND The image specified by ImageId is not + available. Or The specified PackageList is not in the database. + + @retval EFI_INVALID_PARAMETER The Image or Langugae was NULL. + @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not + enough memory. + + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_IMAGE)( + IN CONST EFI_HII_IMAGE_PROTOCOL *This, + IN EFI_HII_HANDLE PackageList, + IN EFI_IMAGE_ID ImageId, + OUT EFI_IMAGE_INPUT *Image + ); + +/** + + This function updates the image specified by ImageId in the + specified PackageListHandle to the image specified by Image. + + + @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance. + + @param PackageList The package list containing the images. + + @param ImageId The image id, which is unique within PackageList. + + @param Image Points to the image. + + @retval EFI_SUCCESS The image was successfully updated. + + @retval EFI_NOT_FOUND The image specified by ImageId is not in the database. + The specified PackageList is not in the database. + + @retval EFI_INVALID_PARAMETER The Image or Language was NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_SET_IMAGE)( + IN CONST EFI_HII_IMAGE_PROTOCOL *This, + IN EFI_HII_HANDLE PackageList, + IN EFI_IMAGE_ID ImageId, + IN CONST EFI_IMAGE_INPUT *Image + ); + +/// +/// EFI_HII_DRAW_FLAGS describes how the image is to be drawn. +/// These flags are defined as EFI_HII_DRAW_FLAG_*** +/// +typedef UINT32 EFI_HII_DRAW_FLAGS; + +#define EFI_HII_DRAW_FLAG_CLIP 0x00000001 +#define EFI_HII_DRAW_FLAG_TRANSPARENT 0x00000030 +#define EFI_HII_DRAW_FLAG_DEFAULT 0x00000000 +#define EFI_HII_DRAW_FLAG_FORCE_TRANS 0x00000010 +#define EFI_HII_DRAW_FLAG_FORCE_OPAQUE 0x00000020 +#define EFI_HII_DIRECT_TO_SCREEN 0x00000080 + +/** + + Definition of EFI_IMAGE_OUTPUT. + + @param Width Width of the output image. + + @param Height Height of the output image. + + @param Bitmap Points to the output bitmap. + + @param Screen Points to the EFI_GRAPHICS_OUTPUT_PROTOCOL which + describes the screen on which to draw the + specified image. + +**/ +typedef struct _EFI_IMAGE_OUTPUT { + UINT16 Width; + UINT16 Height; + union { + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Bitmap; + EFI_GRAPHICS_OUTPUT_PROTOCOL *Screen; + } Image; +} EFI_IMAGE_OUTPUT; + +/** + + This function renders an image to a bitmap or the screen using + the specified color and options. It draws the image on an + existing bitmap, allocates a new bitmap or uses the screen. The + images can be clipped. If EFI_HII_DRAW_FLAG_CLIP is set, then + all pixels drawn outside the bounding box specified by Width and + Height are ignored. If EFI_HII_DRAW_FLAG_TRANSPARENT is set, + then all 'off' pixels in the images drawn will use the + pixel value from Blt. This flag cannot be used if Blt is NULL + upon entry. If EFI_HII_DIRECT_TO_SCREEN is set, then the image + will be written directly to the output device specified by + Screen. Otherwise the image will be rendered to the bitmap + specified by Bitmap. + + + @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance. + + @param Flags Describes how the image is to be drawn. + EFI_HII_DRAW_FLAGS is defined in Related + Definitions, below. + + @param Image Points to the image to be displayed. + + @param Blt If this points to a non-NULL on entry, this points + to the image, which is Width pixels wide and + Height pixels high. The image will be drawn onto + this image and EFI_HII_DRAW_FLAG_CLIP is implied. + If this points to a NULL on entry, then a buffer + will be allocated to hold the generated image and + the pointer updated on exit. It is the caller's + responsibility to free this buffer. + + @param BltX, BltY Specifies the offset from the left and top + edge of the image of the first pixel in + the image. + + @retval EFI_SUCCESS The image was successfully updated. + + @retval EFI_OUT_OF_RESOURCES Unable to allocate an output + buffer for RowInfoArray or Blt. + + @retval EFI_INVALID_PARAMETER The Image or Blt or Height or + Width was NULL. + + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_DRAW_IMAGE)( + IN CONST EFI_HII_IMAGE_PROTOCOL *This, + IN EFI_HII_DRAW_FLAGS Flags, + IN CONST EFI_IMAGE_INPUT *Image, + IN OUT EFI_IMAGE_OUTPUT **Blt, + IN UINTN BltX, + IN UINTN BltY + ); + +/** + + This function renders an image as a bitmap or to the screen and + can clip the image. The bitmap is either supplied by the caller + or else is allocated by the function. The images can be drawn + transparently or opaquely. If EFI_HII_DRAW_FLAG_CLIP is set, + then all pixels drawn outside the bounding box specified by + Width and Height are ignored. If EFI_HII_DRAW_FLAG_TRANSPARENT + is set, then all "off" pixels in the character's glyph will + use the pixel value from Blt. This flag cannot be used if Blt + is NULL upon entry. If EFI_HII_DIRECT_TO_SCREEN is set, then + the image will be written directly to the output device + specified by Screen. Otherwise the image will be rendered to + the bitmap specified by Bitmap. + This function renders an image to a bitmap or the screen using + the specified color and options. It draws the image on an + existing bitmap, allocates a new bitmap or uses the screen. The + images can be clipped. If EFI_HII_DRAW_FLAG_CLIP is set, then + all pixels drawn outside the bounding box specified by Width and + Height are ignored. The EFI_HII_DRAW_FLAG_TRANSPARENT flag + determines whether the image will be drawn transparent or + opaque. If EFI_HII_DRAW_FLAG_FORCE_TRANS is set, then the image + will be drawn so that all 'off' pixels in the image will + be drawn using the pixel value from Blt and all other pixels + will be copied. If EFI_HII_DRAW_FLAG_FORCE_OPAQUE is set, then + the image's pixels will be copied directly to the + destination. If EFI_HII_DRAW_FLAG_DEFAULT is set, then the image + will be drawn transparently or opaque, depending on the + image's transparency setting (see EFI_IMAGE_TRANSPARENT). + Images cannot be drawn transparently if Blt is NULL. If + EFI_HII_DIRECT_TO_SCREEN is set, then the image will be written + directly to the output device specified by Screen. Otherwise the + image will be rendered to the bitmap specified by Bitmap. + + @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance. + + @param Flags Describes how the image is to be drawn. + + @param PackageList The package list in the HII database to + search for the specified image. + + @param ImageId The image's id, which is unique within PackageList. + + @param Blt If this points to a non-NULL on entry, this points + to the image, which is Width pixels wide and + Height pixels high. The image will be drawn onto + this image and EFI_HII_DRAW_FLAG_CLIP is implied. + If this points to a NULL on entry, then a buffer + will be allocated to hold the generated image and + the pointer updated on exit. It is the caller's + responsibility to free this buffer. + + @param BltX, BltY Specifies the offset from the left and top + edge of the output image of the first + pixel in the image. + + @retval EFI_SUCCESS The image was successfully updated. + + @retval EFI_OUT_OF_RESOURCES Unable to allocate an output + buffer for RowInfoArray or Blt. + + @retval EFI_NOT_FOUND The image specified by ImageId is not in the database. + Or The specified PackageList is not in the database. + + @retval EFI_INVALID_PARAMETER The Blt was NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_DRAW_IMAGE_ID)( + IN CONST EFI_HII_IMAGE_PROTOCOL *This, + IN EFI_HII_DRAW_FLAGS Flags, + IN EFI_HII_HANDLE PackageList, + IN EFI_IMAGE_ID ImageId, + IN OUT EFI_IMAGE_OUTPUT **Blt, + IN UINTN BltX, + IN UINTN BltY + ); + +/// +/// Services to access to images in the images database. +/// +struct _EFI_HII_IMAGE_PROTOCOL { + EFI_HII_NEW_IMAGE NewImage; + EFI_HII_GET_IMAGE GetImage; + EFI_HII_SET_IMAGE SetImage; + EFI_HII_DRAW_IMAGE DrawImage; + EFI_HII_DRAW_IMAGE_ID DrawImageId; +}; + +extern EFI_GUID gEfiHiiImageProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/HiiString.h b/sys/contrib/edk2/Include/Protocol/HiiString.h new file mode 100644 index 000000000000..6801eb4ec1fb --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/HiiString.h @@ -0,0 +1,232 @@ +/** @file + The file provides services to manipulate string data. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol was introduced in UEFI Specification 2.1. + +**/ + +#ifndef __HII_STRING_H__ +#define __HII_STRING_H__ + +#include <Protocol/HiiFont.h> + +#define EFI_HII_STRING_PROTOCOL_GUID \ + { 0xfd96974, 0x23aa, 0x4cdc, { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } } + +typedef struct _EFI_HII_STRING_PROTOCOL EFI_HII_STRING_PROTOCOL; + +/** + This function adds the string String to the group of strings owned by PackageList, with the + specified font information StringFontInfo, and returns a new string id. + The new string identifier is guaranteed to be unique within the package list. + That new string identifier is reserved for all languages in the package list. + + @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. + @param PackageList The handle of the package list where this string will + be added. + @param StringId On return, contains the new strings id, which is + unique within PackageList. + @param Language Points to the language for the new string. + @param LanguageName Points to the printable language name to associate + with the passed in Language field.If LanguageName + is not NULL and the string package header's + LanguageName associated with a given Language is + not zero, the LanguageName being passed in will + be ignored. + @param String Points to the new null-terminated string. + @param StringFontInfo Points to the new string's font information or + NULL if the string should have the default system + font, size and style. + + @retval EFI_SUCCESS The new string was added successfully. + @retval EFI_NOT_FOUND The specified PackageList could not be found in + database. + @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources. + @retval EFI_INVALID_PARAMETER String is NULL, or StringId is NULL, or Language is NULL. + @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in + current database. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_NEW_STRING)( + IN CONST EFI_HII_STRING_PROTOCOL *This, + IN EFI_HII_HANDLE PackageList, + OUT EFI_STRING_ID *StringId, + IN CONST CHAR8 *Language, + IN CONST CHAR16 *LanguageName OPTIONAL, + IN CONST EFI_STRING String, + IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL + ); + +/** + This function retrieves the string specified by StringId which is associated + with the specified PackageList in the language Language and copies it into + the buffer specified by String. + + @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. + @param Language Points to the language for the retrieved string. + @param PackageList The package list in the HII database to search for + the specified string. + @param StringId The string's id, which is unique within + PackageList. + @param String Points to the new null-terminated string. + @param StringSize On entry, points to the size of the buffer pointed + to by String, in bytes. On return, points to the + length of the string, in bytes. + @param StringFontInfo If not NULL, points to the string's font + information. It's caller's responsibility to free + this buffer. + + @retval EFI_SUCCESS The string was returned successfully. + @retval EFI_NOT_FOUND The string specified by StringId is not available. + The specified PackageList is not in the database. + @retval EFI_INVALID_LANGUAGE The string specified by StringId is available but + not in the specified language. + @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to + hold the string. + @retval EFI_INVALID_PARAMETER The Language or StringSize was NULL. + @retval EFI_INVALID_PARAMETER The value referenced by StringSize was not zero and + String was NULL. + @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the + request. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_STRING)( + IN CONST EFI_HII_STRING_PROTOCOL *This, + IN CONST CHAR8 *Language, + IN EFI_HII_HANDLE PackageList, + IN EFI_STRING_ID StringId, + OUT EFI_STRING String, + IN OUT UINTN *StringSize, + OUT EFI_FONT_INFO **StringFontInfo OPTIONAL + ); + +/** + This function updates the string specified by StringId in the specified PackageList to the text + specified by String and, optionally, the font information specified by StringFontInfo. + + @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. + @param PackageList The package list containing the strings. + @param StringId The string's id, which is unique within + PackageList. + @param Language Points to the language for the updated string. + @param String Points to the new null-terminated string. + @param StringFontInfo Points to the string's font information or NULL if + the string font information is not changed. + + @retval EFI_SUCCESS The string was updated successfully. + @retval EFI_NOT_FOUND The string specified by StringId is not in the + database. + @retval EFI_INVALID_PARAMETER The String or Language was NULL. + @retval EFI_INVALID_PARAMETER The specified StringFontInfo does not exist in + current database. + @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the + task. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_SET_STRING)( + IN CONST EFI_HII_STRING_PROTOCOL *This, + IN EFI_HII_HANDLE PackageList, + IN EFI_STRING_ID StringId, + IN CONST CHAR8 *Language, + IN EFI_STRING String, + IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL + ); + +/** + This function returns the list of supported languages. + + @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. + @param PackageList The package list to examine. + @param Languages Points to the buffer to hold the returned + null-terminated ASCII string. + @param LanguagesSize On entry, points to the size of the buffer pointed + to by Languages, in bytes. On return, points to + the length of Languages, in bytes. + + @retval EFI_SUCCESS The languages were returned successfully. + @retval EFI_INVALID_PARAMETER The LanguagesSize was NULL. + @retval EFI_INVALID_PARAMETER The value referenced by LanguagesSize is not zero + and Languages is NULL. + @retval EFI_BUFFER_TOO_SMALL The LanguagesSize is too small to hold the list of + supported languages. LanguageSize is updated to + contain the required size. + @retval EFI_NOT_FOUND Could not find string package in specified + packagelist. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_LANGUAGES)( + IN CONST EFI_HII_STRING_PROTOCOL *This, + IN EFI_HII_HANDLE PackageList, + IN OUT CHAR8 *Languages, + IN OUT UINTN *LanguagesSize + ); + +/** + Each string package has associated with it a single primary language and zero + or more secondary languages. This routine returns the secondary languages + associated with a package list. + + @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. + @param PackageList The package list to examine. + @param PrimaryLanguage Points to the null-terminated ASCII string that specifies + the primary language. Languages are specified in the + format specified in Appendix M of the UEFI 2.0 specification. + @param SecondaryLanguages Points to the buffer to hold the returned null-terminated + ASCII string that describes the list of + secondary languages for the specified + PrimaryLanguage. If there are no secondary + languages, the function returns successfully, but + this is set to NULL. + @param SecondaryLanguagesSize On entry, points to the size of the buffer pointed + to by SecondaryLanguages, in bytes. On return, + points to the length of SecondaryLanguages in bytes. + + @retval EFI_SUCCESS Secondary languages were correctly returned. + @retval EFI_INVALID_PARAMETER PrimaryLanguage or SecondaryLanguagesSize was NULL. + @retval EFI_INVALID_PARAMETER The value referenced by SecondaryLanguagesSize is not + zero and SecondaryLanguages is NULL. + @retval EFI_BUFFER_TOO_SMALL The buffer specified by SecondaryLanguagesSize is + too small to hold the returned information. + SecondaryLanguageSize is updated to hold the size of + the buffer required. + @retval EFI_INVALID_LANGUAGE The language specified by PrimaryLanguage is not + present in the specified package list. + @retval EFI_NOT_FOUND The specified PackageList is not in the Database. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_2ND_LANGUAGES)( + IN CONST EFI_HII_STRING_PROTOCOL *This, + IN EFI_HII_HANDLE PackageList, + IN CONST CHAR8 *PrimaryLanguage, + IN OUT CHAR8 *SecondaryLanguages, + IN OUT UINTN *SecondaryLanguagesSize + ); + +/// +/// Services to manipulate the string. +/// +struct _EFI_HII_STRING_PROTOCOL { + EFI_HII_NEW_STRING NewString; + EFI_HII_GET_STRING GetString; + EFI_HII_SET_STRING SetString; + EFI_HII_GET_LANGUAGES GetLanguages; + EFI_HII_GET_2ND_LANGUAGES GetSecondaryLanguages; +}; + +extern EFI_GUID gEfiHiiStringProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Http.h b/sys/contrib/edk2/Include/Protocol/Http.h new file mode 100644 index 000000000000..fb245db41a94 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Http.h @@ -0,0 +1,515 @@ +/** @file + This file defines the EFI HTTP Protocol interface. It is split into + the following two main sections: + HTTP Service Binding Protocol (HTTPSB) + HTTP Protocol (HTTP) + + Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR> + (C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.5 + +**/ + +#ifndef __EFI_HTTP_PROTOCOL_H__ +#define __EFI_HTTP_PROTOCOL_H__ + +#define EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0xbdc8e6af, 0xd9bc, 0x4379, {0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c } \ + } + +#define EFI_HTTP_PROTOCOL_GUID \ + { \ + 0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b } \ + } + +typedef struct _EFI_HTTP_PROTOCOL EFI_HTTP_PROTOCOL; + +/// +/// EFI_HTTP_VERSION +/// +typedef enum { + HttpVersion10, + HttpVersion11, + HttpVersionUnsupported +} EFI_HTTP_VERSION; + +/// +/// EFI_HTTP_METHOD +/// +typedef enum { + HttpMethodGet, + HttpMethodPost, + HttpMethodPatch, + HttpMethodOptions, + HttpMethodConnect, + HttpMethodHead, + HttpMethodPut, + HttpMethodDelete, + HttpMethodTrace, + HttpMethodMax +} EFI_HTTP_METHOD; + +/// +/// EFI_HTTP_STATUS_CODE +/// +typedef enum { + HTTP_STATUS_UNSUPPORTED_STATUS = 0, + HTTP_STATUS_100_CONTINUE, + HTTP_STATUS_101_SWITCHING_PROTOCOLS, + HTTP_STATUS_200_OK, + HTTP_STATUS_201_CREATED, + HTTP_STATUS_202_ACCEPTED, + HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION, + HTTP_STATUS_204_NO_CONTENT, + HTTP_STATUS_205_RESET_CONTENT, + HTTP_STATUS_206_PARTIAL_CONTENT, + HTTP_STATUS_300_MULTIPLE_CHOICES, + HTTP_STATUS_301_MOVED_PERMANENTLY, + HTTP_STATUS_302_FOUND, + HTTP_STATUS_303_SEE_OTHER, + HTTP_STATUS_304_NOT_MODIFIED, + HTTP_STATUS_305_USE_PROXY, + HTTP_STATUS_307_TEMPORARY_REDIRECT, + HTTP_STATUS_400_BAD_REQUEST, + HTTP_STATUS_401_UNAUTHORIZED, + HTTP_STATUS_402_PAYMENT_REQUIRED, + HTTP_STATUS_403_FORBIDDEN, + HTTP_STATUS_404_NOT_FOUND, + HTTP_STATUS_405_METHOD_NOT_ALLOWED, + HTTP_STATUS_406_NOT_ACCEPTABLE, + HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED, + HTTP_STATUS_408_REQUEST_TIME_OUT, + HTTP_STATUS_409_CONFLICT, + HTTP_STATUS_410_GONE, + HTTP_STATUS_411_LENGTH_REQUIRED, + HTTP_STATUS_412_PRECONDITION_FAILED, + HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE, + HTTP_STATUS_414_REQUEST_URI_TOO_LARGE, + HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE, + HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED, + HTTP_STATUS_417_EXPECTATION_FAILED, + HTTP_STATUS_500_INTERNAL_SERVER_ERROR, + HTTP_STATUS_501_NOT_IMPLEMENTED, + HTTP_STATUS_502_BAD_GATEWAY, + HTTP_STATUS_503_SERVICE_UNAVAILABLE, + HTTP_STATUS_504_GATEWAY_TIME_OUT, + HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED, + HTTP_STATUS_308_PERMANENT_REDIRECT, + HTTP_STATUS_429_TOO_MANY_REQUESTS +} EFI_HTTP_STATUS_CODE; + +/// +/// EFI_HTTPv4_ACCESS_POINT +/// +typedef struct { + /// + /// Set to TRUE to instruct the EFI HTTP instance to use the default address + /// information in every TCP connection made by this instance. In addition, when set + /// to TRUE, LocalAddress and LocalSubnet are ignored. + /// + BOOLEAN UseDefaultAddress; + /// + /// If UseDefaultAddress is set to FALSE, this defines the local IP address to be + /// used in every TCP connection opened by this instance. + /// + EFI_IPv4_ADDRESS LocalAddress; + /// + /// If UseDefaultAddress is set to FALSE, this defines the local subnet to be used + /// in every TCP connection opened by this instance. + /// + EFI_IPv4_ADDRESS LocalSubnet; + /// + /// This defines the local port to be used in + /// every TCP connection opened by this instance. + /// + UINT16 LocalPort; +} EFI_HTTPv4_ACCESS_POINT; + +/// +/// EFI_HTTPv6_ACCESS_POINT +/// +typedef struct { + /// + /// Local IP address to be used in every TCP connection opened by this instance. + /// + EFI_IPv6_ADDRESS LocalAddress; + /// + /// Local port to be used in every TCP connection opened by this instance. + /// + UINT16 LocalPort; +} EFI_HTTPv6_ACCESS_POINT; + +/// +/// EFI_HTTP_CONFIG_DATA_ACCESS_POINT +/// + +typedef struct { + /// + /// HTTP version that this instance will support. + /// + EFI_HTTP_VERSION HttpVersion; + /// + /// Time out (in milliseconds) when blocking for requests. + /// + UINT32 TimeOutMillisec; + /// + /// Defines behavior of EFI DNS and TCP protocols consumed by this instance. If + /// FALSE, this instance will use EFI_DNS4_PROTOCOL and EFI_TCP4_PROTOCOL. If TRUE, + /// this instance will use EFI_DNS6_PROTOCOL and EFI_TCP6_PROTOCOL. + /// + BOOLEAN LocalAddressIsIPv6; + + union { + /// + /// When LocalAddressIsIPv6 is FALSE, this points to the local address, subnet, and + /// port used by the underlying TCP protocol. + /// + EFI_HTTPv4_ACCESS_POINT *IPv4Node; + /// + /// When LocalAddressIsIPv6 is TRUE, this points to the local IPv6 address and port + /// used by the underlying TCP protocol. + /// + EFI_HTTPv6_ACCESS_POINT *IPv6Node; + } AccessPoint; +} EFI_HTTP_CONFIG_DATA; + +/// +/// EFI_HTTP_REQUEST_DATA +/// +typedef struct { + /// + /// The HTTP method (e.g. GET, POST) for this HTTP Request. + /// + EFI_HTTP_METHOD Method; + /// + /// The URI of a remote host. From the information in this field, the HTTP instance + /// will be able to determine whether to use HTTP or HTTPS and will also be able to + /// determine the port number to use. If no port number is specified, port 80 (HTTP) + /// is assumed. See RFC 3986 for more details on URI syntax. + /// + CHAR16 *Url; +} EFI_HTTP_REQUEST_DATA; + +/// +/// EFI_HTTP_RESPONSE_DATA +/// +typedef struct { + /// + /// Response status code returned by the remote host. + /// + EFI_HTTP_STATUS_CODE StatusCode; +} EFI_HTTP_RESPONSE_DATA; + +/// +/// EFI_HTTP_HEADER +/// +typedef struct { + /// + /// Null terminated string which describes a field name. See RFC 2616 Section 14 for + /// detailed information about field names. + /// + CHAR8 *FieldName; + /// + /// Null terminated string which describes the corresponding field value. See RFC 2616 + /// Section 14 for detailed information about field values. + /// + CHAR8 *FieldValue; +} EFI_HTTP_HEADER; + +/// +/// EFI_HTTP_MESSAGE +/// +typedef struct { + /// + /// HTTP message data. + /// + union { + /// + /// When the token is used to send a HTTP request, Request is a pointer to storage that + /// contains such data as URL and HTTP method. + /// + EFI_HTTP_REQUEST_DATA *Request; + /// + /// When used to await a response, Response points to storage containing HTTP response + /// status code. + /// + EFI_HTTP_RESPONSE_DATA *Response; + } Data; + /// + /// Number of HTTP header structures in Headers list. On request, this count is + /// provided by the caller. On response, this count is provided by the HTTP driver. + /// + UINTN HeaderCount; + /// + /// Array containing list of HTTP headers. On request, this array is populated by the + /// caller. On response, this array is allocated and populated by the HTTP driver. It + /// is the responsibility of the caller to free this memory on both request and + /// response. + /// + EFI_HTTP_HEADER *Headers; + /// + /// Length in bytes of the HTTP body. This can be zero depending on the HttpMethod type. + /// + UINTN BodyLength; + /// + /// Body associated with the HTTP request or response. This can be NULL depending on + /// the HttpMethod type. + /// + VOID *Body; +} EFI_HTTP_MESSAGE; + +/// +/// EFI_HTTP_TOKEN +/// +typedef struct { + /// + /// This Event will be signaled after the Status field is updated by the EFI HTTP + /// Protocol driver. The type of Event must be EFI_NOTIFY_SIGNAL. The Task Priority + /// Level (TPL) of Event must be lower than or equal to TPL_CALLBACK. + /// + EFI_EVENT Event; + /// + /// Status will be set to one of the following value if the HTTP request is + /// successfully sent or if an unexpected error occurs: + /// EFI_SUCCESS: The HTTP request was successfully sent to the remote host. + /// EFI_HTTP_ERROR: The response message was successfully received but contains a + /// HTTP error. The response status code is returned in token. + /// EFI_ABORTED: The HTTP request was cancelled by the caller and removed from + /// the transmit queue. + /// EFI_TIMEOUT: The HTTP request timed out before reaching the remote host. + /// EFI_DEVICE_ERROR: An unexpected system or network error occurred. + /// + EFI_STATUS Status; + /// + /// Pointer to storage containing HTTP message data. + /// + EFI_HTTP_MESSAGE *Message; +} EFI_HTTP_TOKEN; + +/** + Returns the operational parameters for the current HTTP child instance. + + The GetModeData() function is used to read the current mode data (operational + parameters) for this HTTP protocol instance. + + @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. + @param[out] HttpConfigData Point to buffer for operational parameters of this + HTTP instance. It is the responsibility of the caller + to allocate the memory for HttpConfigData and + HttpConfigData->AccessPoint.IPv6Node/IPv4Node. In fact, + it is recommended to allocate sufficient memory to record + IPv6Node since it is big enough for all possibilities. + + @retval EFI_SUCCESS Operation succeeded. + @retval EFI_INVALID_PARAMETER This is NULL. + HttpConfigData is NULL. + HttpConfigData->AccessPoint.IPv4Node or + HttpConfigData->AccessPoint.IPv6Node is NULL. + @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HTTP_GET_MODE_DATA)( + IN EFI_HTTP_PROTOCOL *This, + OUT EFI_HTTP_CONFIG_DATA *HttpConfigData + ); + +/** + Initialize or brutally reset the operational parameters for this EFI HTTP instance. + + The Configure() function does the following: + When HttpConfigData is not NULL Initialize this EFI HTTP instance by configuring + timeout, local address, port, etc. + When HttpConfigData is NULL, reset this EFI HTTP instance by closing all active + connections with remote hosts, canceling all asynchronous tokens, and flush request + and response buffers without informing the appropriate hosts. + + No other EFI HTTP function can be executed by this instance until the Configure() + function is executed and returns successfully. + + @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. + @param[in] HttpConfigData Pointer to the configure data to configure the instance. + + @retval EFI_SUCCESS Operation succeeded. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + HttpConfigData->LocalAddressIsIPv6 is FALSE and + HttpConfigData->AccessPoint.IPv4Node is NULL. + HttpConfigData->LocalAddressIsIPv6 is TRUE and + HttpConfigData->AccessPoint.IPv6Node is NULL. + @retval EFI_ALREADY_STARTED Reinitialize this HTTP instance without calling + Configure() with NULL to reset it. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources when + executing Configure(). + @retval EFI_UNSUPPORTED One or more options in ConfigData are not supported + in the implementation. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HTTP_CONFIGURE)( + IN EFI_HTTP_PROTOCOL *This, + IN EFI_HTTP_CONFIG_DATA *HttpConfigData OPTIONAL + ); + +/** + The Request() function queues an HTTP request to this HTTP instance, + similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent + successfully, or if there is an error, Status in token will be updated and Event will + be signaled. + + @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. + @param[in] Token Pointer to storage containing HTTP request token. + + @retval EFI_SUCCESS Outgoing data was processed. + @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_TIMEOUT Data was dropped out of the transmit or receive queue. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + Token is NULL. + Token->Message is NULL. + Token->Message->Body is not NULL, + Token->Message->BodyLength is non-zero, and + Token->Message->Data is NULL, but a previous call to + Request()has not been completed successfully. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources. + @retval EFI_UNSUPPORTED The HTTP method is not supported in current implementation. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HTTP_REQUEST)( + IN EFI_HTTP_PROTOCOL *This, + IN EFI_HTTP_TOKEN *Token + ); + +/** + Abort an asynchronous HTTP request or response token. + + The Cancel() function aborts a pending HTTP request or response transaction. If + Token is not NULL and the token is in transmit or receive queues when it is being + cancelled, its Token->Status will be set to EFI_ABORTED and then Token->Event will + be signaled. If the token is not in one of the queues, which usually means that the + asynchronous operation has completed, EFI_NOT_FOUND is returned. If Token is NULL, + all asynchronous tokens issued by Request() or Response() will be aborted. + + @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. + @param[in] Token Point to storage containing HTTP request or response + token. + + @retval EFI_SUCCESS Request and Response queues are successfully flushed. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_STARTED This instance hasn't been configured. + @retval EFI_NOT_FOUND The asynchronous request or response token is not + found. + @retval EFI_UNSUPPORTED The implementation does not support this function. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HTTP_CANCEL)( + IN EFI_HTTP_PROTOCOL *This, + IN EFI_HTTP_TOKEN *Token + ); + +/** + The Response() function queues an HTTP response to this HTTP instance, similar to + Receive() function in the EFI TCP driver. When the HTTP Response is received successfully, + or if there is an error, Status in token will be updated and Event will be signaled. + + The HTTP driver will queue a receive token to the underlying TCP instance. When data + is received in the underlying TCP instance, the data will be parsed and Token will + be populated with the response data. If the data received from the remote host + contains an incomplete or invalid HTTP header, the HTTP driver will continue waiting + (asynchronously) for more data to be sent from the remote host before signaling + Event in Token. + + It is the responsibility of the caller to allocate a buffer for Body and specify the + size in BodyLength. If the remote host provides a response that contains a content + body, up to BodyLength bytes will be copied from the receive buffer into Body and + BodyLength will be updated with the amount of bytes received and copied to Body. This + allows the client to download a large file in chunks instead of into one contiguous + block of memory. Similar to HTTP request, if Body is not NULL and BodyLength is + non-zero and all other fields are NULL or 0, the HTTP driver will queue a receive + token to underlying TCP instance. If data arrives in the receive buffer, up to + BodyLength bytes of data will be copied to Body. The HTTP driver will then update + BodyLength with the amount of bytes received and copied to Body. + + If the HTTP driver does not have an open underlying TCP connection with the host + specified in the response URL, Request() will return EFI_ACCESS_DENIED. This is + consistent with RFC 2616 recommendation that HTTP clients should attempt to maintain + an open TCP connection between client and host. + + @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. + @param[in] Token Pointer to storage containing HTTP response token. + + @retval EFI_SUCCESS Allocation succeeded. + @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been + initialized. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + Token is NULL. + Token->Message->Headers is NULL. + Token->Message is NULL. + Token->Message->Body is not NULL, + Token->Message->BodyLength is non-zero, and + Token->Message->Data is NULL, but a previous call to + Response() has not been completed successfully. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources. + @retval EFI_ACCESS_DENIED An open TCP connection is not present with the host + specified by response URL. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HTTP_RESPONSE)( + IN EFI_HTTP_PROTOCOL *This, + IN EFI_HTTP_TOKEN *Token + ); + +/** + The Poll() function can be used by network drivers and applications to increase the + rate that data packets are moved between the communication devices and the transmit + and receive queues. + + In some systems, the periodic timer event in the managed network driver may not poll + the underlying communications device fast enough to transmit and/or receive all data + packets without missing incoming packets or dropping outgoing packets. Drivers and + applications that are experiencing packet loss should try calling the Poll() function + more often. + + @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. + + @retval EFI_SUCCESS Incoming or outgoing data was processed.. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_READY No incoming or outgoing data is processed. + @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HTTP_POLL)( + IN EFI_HTTP_PROTOCOL *This + ); + +/// +/// The EFI HTTP protocol is designed to be used by EFI drivers and applications to +/// create and transmit HTTP Requests, as well as handle HTTP responses that are +/// returned by a remote host. This EFI protocol uses and relies on an underlying EFI +/// TCP protocol. +/// +struct _EFI_HTTP_PROTOCOL { + EFI_HTTP_GET_MODE_DATA GetModeData; + EFI_HTTP_CONFIGURE Configure; + EFI_HTTP_REQUEST Request; + EFI_HTTP_CANCEL Cancel; + EFI_HTTP_RESPONSE Response; + EFI_HTTP_POLL Poll; +}; + +extern EFI_GUID gEfiHttpServiceBindingProtocolGuid; +extern EFI_GUID gEfiHttpProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/IdeControllerInit.h b/sys/contrib/edk2/Include/Protocol/IdeControllerInit.h new file mode 100644 index 000000000000..a8bfa62a6e2c --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/IdeControllerInit.h @@ -0,0 +1,559 @@ +/** @file + This file declares EFI IDE Controller Init Protocol + + The EFI_IDE_CONTROLLER_INIT_PROTOCOL provides the chipset-specific information + to the driver entity. This protocol is mandatory for IDE controllers if the + IDE devices behind the controller are to be enumerated by a driver entity. + + There can only be one instance of EFI_IDE_CONTROLLER_INIT_PROTOCOL for each IDE + controller in a system. It is installed on the handle that corresponds to the + IDE controller. A driver entity that wishes to manage an IDE bus and possibly + IDE devices in a system will have to retrieve the EFI_IDE_CONTROLLER_INIT_PROTOCOL + instance that is associated with the controller to be managed. + + A device handle for an IDE controller must contain an EFI_DEVICE_PATH_PROTOCOL. + +Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is defined in UEFI Platform Initialization Specification 1.2 + Volume 5: Standards. + +**/ + +#ifndef _EFI_IDE_CONTROLLER_INIT_PROTOCOL_H_ +#define _EFI_IDE_CONTROLLER_INIT_PROTOCOL_H_ + +#include <IndustryStandard/Atapi.h> + +/// +/// Global ID for the EFI_IDE_CONTROLLER_INIT_PROTOCOL. +/// +#define EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID \ + { \ + 0xa1e37052, 0x80d9, 0x4e65, {0xa3, 0x17, 0x3e, 0x9a, 0x55, 0xc4, 0x3e, 0xc9 } \ + } + +/// +/// Forward declaration for EFI_IDE_CONTROLLER_INIT_PROTOCOL. +/// +typedef struct _EFI_IDE_CONTROLLER_INIT_PROTOCOL EFI_IDE_CONTROLLER_INIT_PROTOCOL; + +/// +/// The phase of the IDE Controller enumeration. +/// +typedef enum { + /// + /// The driver entity is about to begin enumerating the devices + /// behind the specified channel. This notification can be used to + /// perform any chipset-specific programming. + /// + EfiIdeBeforeChannelEnumeration, + /// + /// The driver entity has completed enumerating the devices + /// behind the specified channel. This notification can be used to + /// perform any chipset-specific programming. + /// + EfiIdeAfterChannelEnumeration, + /// + /// The driver entity is about to reset the devices behind the + /// specified channel. This notification can be used to perform any + /// chipset-specific programming. + /// + EfiIdeBeforeChannelReset, + /// + /// The driver entity has completed resetting the devices behind + /// the specified channel. This notification can be used to perform + /// any chipset-specific programming. + /// + EfiIdeAfterChannelReset, + /// + /// The driver entity is about to detect the presence of devices + /// behind the specified channel. This notification can be used to + /// set up the bus signals to default levels or for implementing + /// predelays. + /// + EfiIdeBusBeforeDevicePresenceDetection, + /// + /// The driver entity is done with detecting the presence of + /// devices behind the specified channel. This notification can be + /// used to perform any chipset-specific programming. + /// + EfiIdeBusAfterDevicePresenceDetection, + /// + /// The IDE bus is requesting the IDE controller driver to + /// reprogram the IDE controller hardware and thereby reset all + /// the mode and timing settings to default settings. + /// + EfiIdeResetMode, + EfiIdeBusPhaseMaximum +} EFI_IDE_CONTROLLER_ENUM_PHASE; + +/// +/// This extended mode describes the SATA physical protocol. +/// SATA physical layers can operate at different speeds. +/// These speeds are defined below. Various PATA protocols +/// and associated modes are not applicable to SATA devices. +/// +typedef enum { + EfiAtaSataTransferProtocol +} EFI_ATA_EXT_TRANSFER_PROTOCOL; + +/// +/// Automatically detects the optimum SATA speed. +/// +#define EFI_SATA_AUTO_SPEED 0 + +/// +/// Indicates a first-generation (Gen1) SATA speed. +/// +#define EFI_SATA_GEN1_SPEED 1 + +/// +/// Indicates a second-generation (Gen2) SATA speed. +/// +#define EFI_SATA_GEN2_SPEED 2 + +/// +/// EFI_ATA_MODE structure. +/// +typedef struct { + BOOLEAN Valid; ///< TRUE if Mode is valid. + UINT32 Mode; ///< The actual ATA mode. This field is not a bit map. +} EFI_ATA_MODE; + +/// +/// EFI_ATA_EXTENDED_MODE structure +/// +typedef struct { + /// + /// An enumeration defining various transfer protocols other than the protocols + /// that exist at the time this specification was developed (i.e., PIO, single + /// word DMA, multiword DMA, and UDMA). Each transfer protocol is associated + /// with a mode. The various transfer protocols are defined by the ATA/ATAPI + /// specification. This enumeration makes the interface extensible because we + /// can support new transport protocols beyond UDMA. Type EFI_ATA_EXT_TRANSFER_PROTOCOL + /// is defined below. + /// + EFI_ATA_EXT_TRANSFER_PROTOCOL TransferProtocol; + /// + /// The mode for operating the transfer protocol that is identified by TransferProtocol. + /// + UINT32 Mode; +} EFI_ATA_EXTENDED_MODE; + +/// +/// EFI_ATA_COLLECTIVE_MODE structure. +/// +typedef struct { + /// + /// This field specifies the PIO mode. PIO modes are defined in the ATA/ATAPI + /// specification. The ATA/ATAPI specification defines the enumeration. In + /// other words, a value of 1 in this field means PIO mode 1. The actual meaning + /// of PIO mode 1 is governed by the ATA/ATAPI specification. Type EFI_ATA_MODE + /// is defined below. + /// + EFI_ATA_MODE PioMode; + /// + /// This field specifies the single word DMA mode. Single word DMA modes are defined + /// in the ATA/ATAPI specification, versions 1 and 2. Single word DMA support was + /// obsoleted in the ATA/ATAPI specification, version 3. Therefore, most devices and + /// controllers will not support this transfer mode. The ATA/ATAPI specification defines + /// the enumeration. In other words, a value of 1 in this field means single word DMA + /// mode 1. The actual meaning of single word DMA mode 1 is governed by the ATA/ + /// ATAPI specification. + /// + EFI_ATA_MODE SingleWordDmaMode; + /// + /// This field specifies the multiword DMA mode. Various multiword DMA modes are + /// defined in the ATA/ATAPI specification. A value of 1 in this field means multiword + /// DMA mode 1. The actual meaning of multiword DMA mode 1 is governed by the + /// ATA/ATAPI specification. + /// + EFI_ATA_MODE MultiWordDmaMode; + /// + /// This field specifies the ultra DMA (UDMA) mode. UDMA modes are defined in the + /// ATA/ATAPI specification. A value of 1 in this field means UDMA mode 1. The + /// actual meaning of UDMA mode 1 is governed by the ATA/ATAPI specification. + /// + EFI_ATA_MODE UdmaMode; + /// + /// The number of extended-mode bitmap entries. Extended modes describe transfer + /// protocols beyond PIO, single word DMA, multiword DMA, and UDMA. This field + /// can be zero and provides extensibility. + /// + UINT32 ExtModeCount; + /// + /// ExtModeCount number of entries. Each entry represents a transfer protocol other + /// than the ones defined above (i.e., PIO, single word DMA, multiword DMA, and + /// UDMA). This field is defined for extensibility. At this time, only one extended + /// transfer protocol is defined to cover SATA transfers. Type + /// EFI_ATA_EXTENDED_MODE is defined below. + /// + EFI_ATA_EXTENDED_MODE ExtMode[1]; +} EFI_ATA_COLLECTIVE_MODE; + +/// +/// EFI_ATA_IDENTIFY_DATA & EFI_ATAPI_IDENTIFY_DATA structure +/// +/// The definition of these two structures is not part of the protocol +/// definition because the ATA/ATAPI Specification controls the definition +/// of all the fields. The ATA/ATAPI Specification can obsolete old fields +/// or redefine existing fields. +typedef ATA_IDENTIFY_DATA EFI_ATA_IDENTIFY_DATA; +typedef ATAPI_IDENTIFY_DATA EFI_ATAPI_IDENTIFY_DATA; + +/// +/// This flag indicates whether the IDENTIFY data is a response from an ATA device +/// (EFI_ATA_IDENTIFY_DATA) or response from an ATAPI device +/// (EFI_ATAPI_IDENTIFY_DATA). According to the ATA/ATAPI specification, +/// EFI_IDENTIFY_DATA is for an ATA device if bit 15 of the Config field is zero. +/// The Config field is common to both EFI_ATA_IDENTIFY_DATA and +/// EFI_ATAPI_IDENTIFY_DATA. +/// +#define EFI_ATAPI_DEVICE_IDENTIFY_DATA 0x8000 + +/// +/// EFI_IDENTIFY_DATA structure. +/// +typedef union { + /// + /// The data that is returned by an ATA device upon successful completion + /// of the ATA IDENTIFY_DEVICE command. + /// + EFI_ATA_IDENTIFY_DATA AtaData; + /// + /// The data that is returned by an ATAPI device upon successful completion + /// of the ATA IDENTIFY_PACKET_DEVICE command. + /// + EFI_ATAPI_IDENTIFY_DATA AtapiData; +} EFI_IDENTIFY_DATA; + +/** + Returns the information about the specified IDE channel. + + This function can be used to obtain information about a particular IDE channel. + The driver entity uses this information during the enumeration process. + + If Enabled is set to FALSE, the driver entity will not scan the channel. Note + that it will not prevent an operating system driver from scanning the channel. + + For most of today's controllers, MaxDevices will either be 1 or 2. For SATA + controllers, this value will always be 1. SATA configurations can contain SATA + port multipliers. SATA port multipliers behave like SATA bridges and can support + up to 16 devices on the other side. If a SATA port out of the IDE controller + is connected to a port multiplier, MaxDevices will be set to the number of SATA + devices that the port multiplier supports. Because today's port multipliers + support up to fifteen SATA devices, this number can be as large as fifteen. The IDE + bus driver is required to scan for the presence of port multipliers behind an SATA + controller and enumerate up to MaxDevices number of devices behind the port + multiplier. + + In this context, the devices behind a port multiplier constitute a channel. + + @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel Zero-based channel number. + @param[out] Enabled TRUE if this channel is enabled. Disabled channels + are not scanned to see if any devices are present. + @param[out] MaxDevices The maximum number of IDE devices that the bus driver + can expect on this channel. For the ATA/ATAPI + specification, version 6, this number will either be + one or two. For Serial ATA (SATA) configurations with a + port multiplier, this number can be as large as fifteen. + + @retval EFI_SUCCESS Information was returned without any errors. + @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IDE_CONTROLLER_GET_CHANNEL_INFO)( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + OUT BOOLEAN *Enabled, + OUT UINT8 *MaxDevices + ); + +/** + The notifications from the driver entity that it is about to enter a certain + phase of the IDE channel enumeration process. + + This function can be used to notify the IDE controller driver to perform + specific actions, including any chipset-specific initialization, so that the + chipset is ready to enter the next phase. Seven notification points are defined + at this time. + + More synchronization points may be added as required in the future. + + @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Phase The phase during enumeration. + @param[in] Channel Zero-based channel number. + + @retval EFI_SUCCESS The notification was accepted without any errors. + @retval EFI_UNSUPPORTED Phase is not supported. + @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). + @retval EFI_NOT_READY This phase cannot be entered at this time; for + example, an attempt was made to enter a Phase + without having entered one or more previous + Phase. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IDE_CONTROLLER_NOTIFY_PHASE)( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase, + IN UINT8 Channel + ); + +/** + Submits the device information to the IDE controller driver. + + This function is used by the driver entity to pass detailed information about + a particular device to the IDE controller driver. The driver entity obtains + this information by issuing an ATA or ATAPI IDENTIFY_DEVICE command. IdentifyData + is the pointer to the response data buffer. The IdentifyData buffer is owned + by the driver entity, and the IDE controller driver must make a local copy + of the entire buffer or parts of the buffer as needed. The original IdentifyData + buffer pointer may not be valid when + + - EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() or + - EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() is called at a later point. + + The IDE controller driver may consult various fields of EFI_IDENTIFY_DATA to + compute the optimum mode for the device. These fields are not limited to the + timing information. For example, an implementation of the IDE controller driver + may examine the vendor and type/mode field to match known bad drives. + + The driver entity may submit drive information in any order, as long as it + submits information for all the devices belonging to the enumeration group + before EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() is called for any device + in that enumeration group. If a device is absent, EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() + should be called with IdentifyData set to NULL. The IDE controller driver may + not have any other mechanism to know whether a device is present or not. Therefore, + setting IdentifyData to NULL does not constitute an error condition. + EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() can be called only once for a + given (Channel, Device) pair. + + @param[in] This A pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel Zero-based channel number. + @param[in] Device Zero-based device number on the Channel. + @param[in] IdentifyData The device's response to the ATA IDENTIFY_DEVICE command. + + @retval EFI_SUCCESS The information was accepted without any errors. + @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). + @retval EFI_INVALID_PARAMETER Device is invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IDE_CONTROLLER_SUBMIT_DATA)( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_IDENTIFY_DATA *IdentifyData + ); + +/** + Disqualifies specific modes for an IDE device. + + This function allows the driver entity or other drivers (such as platform + drivers) to reject certain timing modes and request the IDE controller driver + to recalculate modes. This function allows the driver entity and the IDE + controller driver to negotiate the timings on a per-device basis. This function + is useful in the case of drives that lie about their capabilities. An example + is when the IDE device fails to accept the timing modes that are calculated + by the IDE controller driver based on the response to the Identify Drive command. + + If the driver entity does not want to limit the ATA timing modes and leave that + decision to the IDE controller driver, it can either not call this function for + the given device or call this function and set the Valid flag to FALSE for all + modes that are listed in EFI_ATA_COLLECTIVE_MODE. + + The driver entity may disqualify modes for a device in any order and any number + of times. + + This function can be called multiple times to invalidate multiple modes of the + same type (e.g., Programmed Input/Output [PIO] modes 3 and 4). See the ATA/ATAPI + specification for more information on PIO modes. + + For Serial ATA (SATA) controllers, this member function can be used to disqualify + a higher transfer rate mode on a given channel. For example, a platform driver + may inform the IDE controller driver to not use second-generation (Gen2) speeds + for a certain SATA drive. + + @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel The zero-based channel number. + @param[in] Device The zero-based device number on the Channel. + @param[in] BadModes The modes that the device does not support and that + should be disqualified. + + @retval EFI_SUCCESS The modes were accepted without any errors. + @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). + @retval EFI_INVALID_PARAMETER Device is invalid. + @retval EFI_INVALID_PARAMETER IdentifyData is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IDE_CONTROLLER_DISQUALIFY_MODE)( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_ATA_COLLECTIVE_MODE *BadModes + ); + +/** + Returns the information about the optimum modes for the specified IDE device. + + This function is used by the driver entity to obtain the optimum ATA modes for + a specific device. The IDE controller driver takes into account the following + while calculating the mode: + - The IdentifyData inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() + - The BadModes inputs to EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() + + The driver entity is required to call EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() + for all the devices that belong to an enumeration group before calling + EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() for any device in the same group. + + The IDE controller driver will use controller- and possibly platform-specific + algorithms to arrive at SupportedModes. The IDE controller may base its + decision on user preferences and other considerations as well. This function + may be called multiple times because the driver entity may renegotiate the mode + with the IDE controller driver using EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode(). + + The driver entity may collect timing information for various devices in any + order. The driver entity is responsible for making sure that all the dependencies + are satisfied. For example, the SupportedModes information for device A that + was previously returned may become stale after a call to + EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyMode() for device B. + + The buffer SupportedModes is allocated by the callee because the caller does + not necessarily know the size of the buffer. The type EFI_ATA_COLLECTIVE_MODE + is defined in a way that allows for future extensibility and can be of variable + length. This memory pool should be deallocated by the caller when it is no + longer necessary. + + The IDE controller driver for a Serial ATA (SATA) controller can use this + member function to force a lower speed (first-generation [Gen1] speeds on a + second-generation [Gen2]-capable hardware). The IDE controller driver can + also allow the driver entity to stay with the speed that has been negotiated + by the physical layer. + + @param[in] This The pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel A zero-based channel number. + @param[in] Device A zero-based device number on the Channel. + @param[out] SupportedModes The optimum modes for the device. + + @retval EFI_SUCCESS SupportedModes was returned. + @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). + @retval EFI_INVALID_PARAMETER Device is invalid. + @retval EFI_INVALID_PARAMETER SupportedModes is NULL. + @retval EFI_NOT_READY Modes cannot be calculated due to a lack of + data. This error may happen if + EFI_IDE_CONTROLLER_INIT_PROTOCOL.SubmitData() + and EFI_IDE_CONTROLLER_INIT_PROTOCOL.DisqualifyData() + were not called for at least one drive in the + same enumeration group. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IDE_CONTROLLER_CALCULATE_MODE)( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes + ); + +/** + Commands the IDE controller driver to program the IDE controller hardware + so that the specified device can operate at the specified mode. + + This function is used by the driver entity to instruct the IDE controller + driver to program the IDE controller hardware to the specified modes. This + function can be called only once for a particular device. For a Serial ATA + (SATA) Advanced Host Controller Interface (AHCI) controller, no controller- + specific programming may be required. + + @param[in] This Pointer to the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance. + @param[in] Channel Zero-based channel number. + @param[in] Device Zero-based device number on the Channel. + @param[in] Modes The modes to set. + + @retval EFI_SUCCESS The command was accepted without any errors. + @retval EFI_INVALID_PARAMETER Channel is invalid (Channel >= ChannelCount). + @retval EFI_INVALID_PARAMETER Device is invalid. + @retval EFI_NOT_READY Modes cannot be set at this time due to lack of data. + @retval EFI_DEVICE_ERROR Modes cannot be set due to hardware failure. + The driver entity should not use this device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IDE_CONTROLLER_SET_TIMING)( + IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This, + IN UINT8 Channel, + IN UINT8 Device, + IN EFI_ATA_COLLECTIVE_MODE *Modes + ); + +/// +/// Provides the basic interfaces to abstract an IDE controller. +/// +struct _EFI_IDE_CONTROLLER_INIT_PROTOCOL { + /// + /// Returns the information about a specific channel. + /// + EFI_IDE_CONTROLLER_GET_CHANNEL_INFO GetChannelInfo; + + /// + /// The notification that the driver entity is about to enter the + /// specified phase during the enumeration process. + /// + EFI_IDE_CONTROLLER_NOTIFY_PHASE NotifyPhase; + + /// + /// Submits the Drive Identify data that was returned by the device. + /// + EFI_IDE_CONTROLLER_SUBMIT_DATA SubmitData; + + /// + /// Submits information about modes that should be disqualified. The specified + /// IDE device does not support these modes and these modes should not be + /// returned by EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode() + /// + EFI_IDE_CONTROLLER_DISQUALIFY_MODE DisqualifyMode; + + /// + /// Calculates and returns the optimum mode for a particular IDE device. + /// + EFI_IDE_CONTROLLER_CALCULATE_MODE CalculateMode; + + /// + /// Programs the IDE controller hardware to the default timing or per the modes + /// that were returned by the last call to EFI_IDE_CONTROLLER_INIT_PROTOCOL.CalculateMode(). + /// + EFI_IDE_CONTROLLER_SET_TIMING SetTiming; + + /// + /// Set to TRUE if the enumeration group includes all the channels that are + /// produced by this controller. Set to FALSE if an enumeration group consists of + /// only one channel. + /// + BOOLEAN EnumAll; + + /// + /// The number of channels that are produced by this controller. Parallel ATA + /// (PATA) controllers can support up to two channels. Advanced Host Controller + /// Interface (AHCI) Serial ATA (SATA) controllers can support up to 32 channels, + /// each of which can have up to one device. In the presence of a multiplier, + /// each channel can have fifteen devices. + /// + UINT8 ChannelCount; +}; + +extern EFI_GUID gEfiIdeControllerInitProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Ip4.h b/sys/contrib/edk2/Include/Protocol/Ip4.h new file mode 100644 index 000000000000..9f08bee84c03 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Ip4.h @@ -0,0 +1,602 @@ +/** @file + This file defines the EFI IPv4 (Internet Protocol version 4) + Protocol interface. It is split into the following three main + sections: + - EFI IPv4 Service Binding Protocol + - EFI IPv4 Variable (deprecated in UEFI 2.4B) + - EFI IPv4 Protocol. + The EFI IPv4 Protocol provides basic network IPv4 packet I/O services, + which includes support foR a subset of the Internet Control Message + Protocol (ICMP) and may include support for the Internet Group Management + Protocol (IGMP). + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.0. + +**/ + +#ifndef __EFI_IP4_PROTOCOL_H__ +#define __EFI_IP4_PROTOCOL_H__ + +#include <Protocol/ManagedNetwork.h> + +#define EFI_IP4_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0xc51711e7, 0xb4bf, 0x404a, {0xbf, 0xb8, 0x0a, 0x04, 0x8e, 0xf1, 0xff, 0xe4 } \ + } + +#define EFI_IP4_PROTOCOL_GUID \ + { \ + 0x41d94cd2, 0x35b6, 0x455a, {0x82, 0x58, 0xd4, 0xe5, 0x13, 0x34, 0xaa, 0xdd } \ + } + +typedef struct _EFI_IP4_PROTOCOL EFI_IP4_PROTOCOL; + +/// +/// EFI_IP4_ADDRESS_PAIR is deprecated in the UEFI 2.4B and should not be used any more. +/// The definition in here is only present to provide backwards compatability. +/// +typedef struct { + EFI_HANDLE InstanceHandle; + EFI_IPv4_ADDRESS Ip4Address; + EFI_IPv4_ADDRESS SubnetMask; +} EFI_IP4_ADDRESS_PAIR; + +/// +/// EFI_IP4_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more. +/// The definition in here is only present to provide backwards compatability. +/// +typedef struct { + EFI_HANDLE DriverHandle; + UINT32 AddressCount; + EFI_IP4_ADDRESS_PAIR AddressPairs[1]; +} EFI_IP4_VARIABLE_DATA; + +typedef struct { + /// + /// The default IPv4 protocol packets to send and receive. Ignored + /// when AcceptPromiscuous is TRUE. + /// + UINT8 DefaultProtocol; + /// + /// Set to TRUE to receive all IPv4 packets that get through the receive filters. + /// Set to FALSE to receive only the DefaultProtocol IPv4 + /// packets that get through the receive filters. + /// + BOOLEAN AcceptAnyProtocol; + /// + /// Set to TRUE to receive ICMP error report packets. Ignored when + /// AcceptPromiscuous or AcceptAnyProtocol is TRUE. + /// + BOOLEAN AcceptIcmpErrors; + /// + /// Set to TRUE to receive broadcast IPv4 packets. Ignored when + /// AcceptPromiscuous is TRUE. + /// Set to FALSE to stop receiving broadcast IPv4 packets. + /// + BOOLEAN AcceptBroadcast; + /// + /// Set to TRUE to receive all IPv4 packets that are sent to any + /// hardware address or any protocol address. + /// Set to FALSE to stop receiving all promiscuous IPv4 packets + /// + BOOLEAN AcceptPromiscuous; + /// + /// Set to TRUE to use the default IPv4 address and default routing table. + /// + BOOLEAN UseDefaultAddress; + /// + /// The station IPv4 address that will be assigned to this EFI IPv4Protocol instance. + /// + EFI_IPv4_ADDRESS StationAddress; + /// + /// The subnet address mask that is associated with the station address. + /// + EFI_IPv4_ADDRESS SubnetMask; + /// + /// TypeOfService field in transmitted IPv4 packets. + /// + UINT8 TypeOfService; + /// + /// TimeToLive field in transmitted IPv4 packets. + /// + UINT8 TimeToLive; + /// + /// State of the DoNotFragment bit in transmitted IPv4 packets. + /// + BOOLEAN DoNotFragment; + /// + /// Set to TRUE to send and receive unformatted packets. The other + /// IPv4 receive filters are still applied. Fragmentation is disabled for RawData mode. + /// + BOOLEAN RawData; + /// + /// The timer timeout value (number of microseconds) for the + /// receive timeout event to be associated with each assembled + /// packet. Zero means do not drop assembled packets. + /// + UINT32 ReceiveTimeout; + /// + /// The timer timeout value (number of microseconds) for the + /// transmit timeout event to be associated with each outgoing + /// packet. Zero means do not drop outgoing packets. + /// + UINT32 TransmitTimeout; +} EFI_IP4_CONFIG_DATA; + +typedef struct { + EFI_IPv4_ADDRESS SubnetAddress; + EFI_IPv4_ADDRESS SubnetMask; + EFI_IPv4_ADDRESS GatewayAddress; +} EFI_IP4_ROUTE_TABLE; + +typedef struct { + UINT8 Type; + UINT8 Code; +} EFI_IP4_ICMP_TYPE; + +typedef struct { + /// + /// Set to TRUE after this EFI IPv4 Protocol instance has been successfully configured. + /// + BOOLEAN IsStarted; + /// + /// The maximum packet size, in bytes, of the packet which the upper layer driver could feed. + /// + UINT32 MaxPacketSize; + /// + /// Current configuration settings. + /// + EFI_IP4_CONFIG_DATA ConfigData; + /// + /// Set to TRUE when the EFI IPv4 Protocol instance has a station address and subnet mask. + /// + BOOLEAN IsConfigured; + /// + /// Number of joined multicast groups. + /// + UINT32 GroupCount; + /// + /// List of joined multicast group addresses. + /// + EFI_IPv4_ADDRESS *GroupTable; + /// + /// Number of entries in the routing table. + /// + UINT32 RouteCount; + /// + /// Routing table entries. + /// + EFI_IP4_ROUTE_TABLE *RouteTable; + /// + /// Number of entries in the supported ICMP types list. + /// + UINT32 IcmpTypeCount; + /// + /// Array of ICMP types and codes that are supported by this EFI IPv4 Protocol driver + /// + EFI_IP4_ICMP_TYPE *IcmpTypeList; +} EFI_IP4_MODE_DATA; + +#pragma pack(1) + +typedef struct { + UINT8 HeaderLength : 4; + UINT8 Version : 4; + UINT8 TypeOfService; + UINT16 TotalLength; + UINT16 Identification; + UINT16 Fragmentation; + UINT8 TimeToLive; + UINT8 Protocol; + UINT16 Checksum; + EFI_IPv4_ADDRESS SourceAddress; + EFI_IPv4_ADDRESS DestinationAddress; +} EFI_IP4_HEADER; +#pragma pack() + +typedef struct { + UINT32 FragmentLength; + VOID *FragmentBuffer; +} EFI_IP4_FRAGMENT_DATA; + +typedef struct { + EFI_TIME TimeStamp; + EFI_EVENT RecycleSignal; + UINT32 HeaderLength; + EFI_IP4_HEADER *Header; + UINT32 OptionsLength; + VOID *Options; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_IP4_FRAGMENT_DATA FragmentTable[1]; +} EFI_IP4_RECEIVE_DATA; + +typedef struct { + EFI_IPv4_ADDRESS SourceAddress; + EFI_IPv4_ADDRESS GatewayAddress; + UINT8 Protocol; + UINT8 TypeOfService; + UINT8 TimeToLive; + BOOLEAN DoNotFragment; +} EFI_IP4_OVERRIDE_DATA; + +typedef struct { + EFI_IPv4_ADDRESS DestinationAddress; + EFI_IP4_OVERRIDE_DATA *OverrideData; // OPTIONAL + UINT32 OptionsLength; // OPTIONAL + VOID *OptionsBuffer; // OPTIONAL + UINT32 TotalDataLength; + UINT32 FragmentCount; + EFI_IP4_FRAGMENT_DATA FragmentTable[1]; +} EFI_IP4_TRANSMIT_DATA; + +typedef struct { + /// + /// This Event will be signaled after the Status field is updated + /// by the EFI IPv4 Protocol driver. The type of Event must be + /// EFI_NOTIFY_SIGNAL. The Task Priority Level (TPL) of + /// Event must be lower than or equal to TPL_CALLBACK. + /// + EFI_EVENT Event; + /// + /// The status that is returned to the caller at the end of the operation + /// to indicate whether this operation completed successfully. + /// + EFI_STATUS Status; + union { + /// + /// When this token is used for receiving, RxData is a pointer to the EFI_IP4_RECEIVE_DATA. + /// + EFI_IP4_RECEIVE_DATA *RxData; + /// + /// When this token is used for transmitting, TxData is a pointer to the EFI_IP4_TRANSMIT_DATA. + /// + EFI_IP4_TRANSMIT_DATA *TxData; + } Packet; +} EFI_IP4_COMPLETION_TOKEN; + +/** + Gets the current operational settings for this instance of the EFI IPv4 Protocol driver. + + The GetModeData() function returns the current operational mode data for this + driver instance. The data fields in EFI_IP4_MODE_DATA are read only. This + function is used optionally to retrieve the operational mode data of underlying + networks or drivers. + + @param This The pointer to the EFI_IP4_PROTOCOL instance. + @param Ip4ModeData The pointer to the EFI IPv4 Protocol mode data structure. + @param MnpConfigData The pointer to the managed network configuration data structure. + @param SnpModeData The pointer to the simple network mode data structure. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_GET_MODE_DATA)( + IN CONST EFI_IP4_PROTOCOL *This, + OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL, + OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, + OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL + ); + +/** + Assigns an IPv4 address and subnet mask to this EFI IPv4 Protocol driver instance. + + The Configure() function is used to set, change, or reset the operational + parameters and filter settings for this EFI IPv4 Protocol instance. Until these + parameters have been set, no network traffic can be sent or received by this + instance. Once the parameters have been reset (by calling this function with + IpConfigData set to NULL), no more traffic can be sent or received until these + parameters have been set again. Each EFI IPv4 Protocol instance can be started + and stopped independently of each other by enabling or disabling their receive + filter settings with the Configure() function. + + When IpConfigData.UseDefaultAddress is set to FALSE, the new station address will + be appended as an alias address into the addresses list in the EFI IPv4 Protocol + driver. While set to TRUE, Configure() will trigger the EFI_IP4_CONFIG_PROTOCOL + to retrieve the default IPv4 address if it is not available yet. Clients could + frequently call GetModeData() to check the status to ensure that the default IPv4 + address is ready. + + If operational parameters are reset or changed, any pending transmit and receive + requests will be cancelled. Their completion token status will be set to EFI_ABORTED + and their events will be signaled. + + @param This The pointer to the EFI_IP4_PROTOCOL instance. + @param IpConfigData The pointer to the EFI IPv4 Protocol configuration data structure. + + @retval EFI_SUCCESS The driver instance was successfully opened. + @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, + RARP, etc.) is not finished yet. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + IpConfigData.StationAddress is not a unicast IPv4 address. + IpConfigData.SubnetMask is not a valid IPv4 subnet + @retval EFI_UNSUPPORTED One or more of the following conditions is TRUE: + A configuration protocol (DHCP, BOOTP, RARP, etc.) could + not be located when clients choose to use the default IPv4 + address. This EFI IPv4 Protocol implementation does not + support this requested filter or timeout setting. + @retval EFI_OUT_OF_RESOURCES The EFI IPv4 Protocol driver instance data could not be allocated. + @retval EFI_ALREADY_STARTED The interface is already open and must be stopped before the + IPv4 address or subnet mask can be changed. The interface must + also be stopped when switching to/from raw packet mode. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI IPv4 + Protocol driver instance is not opened. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_CONFIGURE)( + IN EFI_IP4_PROTOCOL *This, + IN EFI_IP4_CONFIG_DATA *IpConfigData OPTIONAL + ); + +/** + Joins and leaves multicast groups. + + The Groups() function is used to join and leave multicast group sessions. Joining + a group will enable reception of matching multicast packets. Leaving a group will + disable the multicast packet reception. + + If JoinFlag is FALSE and GroupAddress is NULL, all joined groups will be left. + + @param This The pointer to the EFI_IP4_PROTOCOL instance. + @param JoinFlag Set to TRUE to join the multicast group session and FALSE to leave. + @param GroupAddress The pointer to the IPv4 multicast address. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER One or more of the following is TRUE: + - This is NULL. + - JoinFlag is TRUE and GroupAddress is NULL. + - GroupAddress is not NULL and *GroupAddress is + not a multicast IPv4 address. + @retval EFI_NOT_STARTED This instance has not been started. + @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, + RARP, etc.) is not finished yet. + @retval EFI_OUT_OF_RESOURCES System resources could not be allocated. + @retval EFI_UNSUPPORTED This EFI IPv4 Protocol implementation does not support multicast groups. + @retval EFI_ALREADY_STARTED The group address is already in the group table (when + JoinFlag is TRUE). + @retval EFI_NOT_FOUND The group address is not in the group table (when JoinFlag is FALSE). + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_GROUPS)( + IN EFI_IP4_PROTOCOL *This, + IN BOOLEAN JoinFlag, + IN EFI_IPv4_ADDRESS *GroupAddress OPTIONAL + ); + +/** + Adds and deletes routing table entries. + + The Routes() function adds a route to or deletes a route from the routing table. + + Routes are determined by comparing the SubnetAddress with the destination IPv4 + address arithmetically AND-ed with the SubnetMask. The gateway address must be + on the same subnet as the configured station address. + + The default route is added with SubnetAddress and SubnetMask both set to 0.0.0.0. + The default route matches all destination IPv4 addresses that do not match any + other routes. + + A GatewayAddress that is zero is a nonroute. Packets are sent to the destination + IP address if it can be found in the ARP cache or on the local subnet. One automatic + nonroute entry will be inserted into the routing table for outgoing packets that + are addressed to a local subnet (gateway address of 0.0.0.0). + + Each EFI IPv4 Protocol instance has its own independent routing table. Those EFI + IPv4 Protocol instances that use the default IPv4 address will also have copies + of the routing table that was provided by the EFI_IP4_CONFIG_PROTOCOL, and these + copies will be updated whenever the EIF IPv4 Protocol driver reconfigures its + instances. As a result, client modification to the routing table will be lost. + + @param This The pointer to the EFI_IP4_PROTOCOL instance. + @param DeleteRoute Set to TRUE to delete this route from the routing table. Set to + FALSE to add this route to the routing table. SubnetAddress + and SubnetMask are used as the key to each route entry. + @param SubnetAddress The address of the subnet that needs to be routed. + @param SubnetMask The subnet mask of SubnetAddress. + @param GatewayAddress The unicast gateway IPv4 address for this route. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_NOT_STARTED The driver instance has not been started. + @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, + RARP, etc.) is not finished yet. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - SubnetAddress is NULL. + - SubnetMask is NULL. + - GatewayAddress is NULL. + - *SubnetAddress is not a valid subnet address. + - *SubnetMask is not a valid subnet mask. + - *GatewayAddress is not a valid unicast IPv4 address. + @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table. + @retval EFI_NOT_FOUND This route is not in the routing table (when DeleteRoute is TRUE). + @retval EFI_ACCESS_DENIED The route is already defined in the routing table (when + DeleteRoute is FALSE). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_ROUTES)( + IN EFI_IP4_PROTOCOL *This, + IN BOOLEAN DeleteRoute, + IN EFI_IPv4_ADDRESS *SubnetAddress, + IN EFI_IPv4_ADDRESS *SubnetMask, + IN EFI_IPv4_ADDRESS *GatewayAddress + ); + +/** + Places outgoing data packets into the transmit queue. + + The Transmit() function places a sending request in the transmit queue of this + EFI IPv4 Protocol instance. Whenever the packet in the token is sent out or some + errors occur, the event in the token will be signaled and the status is updated. + + @param This The pointer to the EFI_IP4_PROTOCOL instance. + @param Token The pointer to the transmit token. + + @retval EFI_SUCCESS The data has been queued for transmission. + @retval EFI_NOT_STARTED This instance has not been started. + @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, + RARP, etc.) is not finished yet. + @retval EFI_INVALID_PARAMETER One or more pameters are invalid. + @retval EFI_ACCESS_DENIED The transmit completion token with the same Token.Event + was already in the transmit queue. + @retval EFI_NOT_READY The completion token could not be queued because the transmit + queue is full. + @retval EFI_NOT_FOUND Not route is found to destination address. + @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data. + @retval EFI_BUFFER_TOO_SMALL Token.Packet.TxData.TotalDataLength is too + short to transmit. + @retval EFI_BAD_BUFFER_SIZE The length of the IPv4 header + option length + total data length is + greater than MTU (or greater than the maximum packet size if + Token.Packet.TxData.OverrideData. + DoNotFragment is TRUE.) + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_TRANSMIT)( + IN EFI_IP4_PROTOCOL *This, + IN EFI_IP4_COMPLETION_TOKEN *Token + ); + +/** + Places a receiving request into the receiving queue. + + The Receive() function places a completion token into the receive packet queue. + This function is always asynchronous. + + The Token.Event field in the completion token must be filled in by the caller + and cannot be NULL. When the receive operation completes, the EFI IPv4 Protocol + driver updates the Token.Status and Token.Packet.RxData fields and the Token.Event + is signaled. + + @param This The pointer to the EFI_IP4_PROTOCOL instance. + @param Token The pointer to a token that is associated with the receive data descriptor. + + @retval EFI_SUCCESS The receive completion token was cached. + @retval EFI_NOT_STARTED This EFI IPv4 Protocol instance has not been started. + @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, RARP, etc.) + is not finished yet. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - Token is NULL. + - Token.Event is NULL. + @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of system + resources (usually memory). + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + The EFI IPv4 Protocol instance has been reset to startup defaults. + @retval EFI_ACCESS_DENIED The receive completion token with the same Token.Event was already + in the receive queue. + @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. + @retval EFI_ICMP_ERROR An ICMP error packet was received. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_RECEIVE)( + IN EFI_IP4_PROTOCOL *This, + IN EFI_IP4_COMPLETION_TOKEN *Token + ); + +/** + Abort an asynchronous transmit or receive request. + + The Cancel() function is used to abort a pending transmit or receive request. + If the token is in the transmit or receive request queues, after calling this + function, Token->Status will be set to EFI_ABORTED and then Token->Event will + be signaled. If the token is not in one of the queues, which usually means the + asynchronous operation has completed, this function will not signal the token + and EFI_NOT_FOUND is returned. + + @param This The pointer to the EFI_IP4_PROTOCOL instance. + @param Token The pointer to a token that has been issued by + EFI_IP4_PROTOCOL.Transmit() or + EFI_IP4_PROTOCOL.Receive(). If NULL, all pending + tokens are aborted. Type EFI_IP4_COMPLETION_TOKEN is + defined in EFI_IP4_PROTOCOL.Transmit(). + + @retval EFI_SUCCESS The asynchronous I/O request was aborted and + Token->Event was signaled. When Token is NULL, all + pending requests were aborted and their events were signaled. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_STARTED This instance has not been started. + @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, + RARP, etc.) is not finished yet. + @retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O request was + not found in the transmit or receive queue. It has either completed + or was not issued by Transmit() and Receive(). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_CANCEL)( + IN EFI_IP4_PROTOCOL *This, + IN EFI_IP4_COMPLETION_TOKEN *Token OPTIONAL + ); + +/** + Polls for incoming data packets and processes outgoing data packets. + + The Poll() function polls for incoming data packets and processes outgoing data + packets. Network drivers and applications can call the EFI_IP4_PROTOCOL.Poll() + function to increase the rate that data packets are moved between the communications + device and the transmit and receive queues. + + In some systems the periodic timer event may not poll the underlying communications + device fast enough to transmit and/or receive all data packets without missing + incoming packets or dropping outgoing packets. Drivers and applications that are + experiencing packet loss should try calling the EFI_IP4_PROTOCOL.Poll() function + more often. + + @param This The pointer to the EFI_IP4_PROTOCOL instance. + + @retval EFI_SUCCESS Incoming or outgoing data was processed. + @retval EFI_NOT_STARTED This EFI IPv4 Protocol instance has not been started. + @retval EFI_NO_MAPPING When using the default address, configuration (DHCP, BOOTP, + RARP, etc.) is not finished yet. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_NOT_READY No incoming or outgoing data is processed. + @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. + Consider increasing the polling rate. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_POLL)( + IN EFI_IP4_PROTOCOL *This + ); + +/// +/// The EFI IPv4 Protocol implements a simple packet-oriented interface that can be +/// used by drivers, daemons, and applications to transmit and receive network packets. +/// +struct _EFI_IP4_PROTOCOL { + EFI_IP4_GET_MODE_DATA GetModeData; + EFI_IP4_CONFIGURE Configure; + EFI_IP4_GROUPS Groups; + EFI_IP4_ROUTES Routes; + EFI_IP4_TRANSMIT Transmit; + EFI_IP4_RECEIVE Receive; + EFI_IP4_CANCEL Cancel; + EFI_IP4_POLL Poll; +}; + +extern EFI_GUID gEfiIp4ServiceBindingProtocolGuid; +extern EFI_GUID gEfiIp4ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Ip4Config.h b/sys/contrib/edk2/Include/Protocol/Ip4Config.h new file mode 100644 index 000000000000..5a2aba05b4f8 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Ip4Config.h @@ -0,0 +1,176 @@ +/** @file + This file provides a definition of the EFI IPv4 Configuration + Protocol. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.0. + +**/ + +#ifndef __EFI_IP4CONFIG_PROTOCOL_H__ +#define __EFI_IP4CONFIG_PROTOCOL_H__ + +#include <Protocol/Ip4.h> + +#define EFI_IP4_CONFIG_PROTOCOL_GUID \ + { \ + 0x3b95aa31, 0x3793, 0x434b, {0x86, 0x67, 0xc8, 0x07, 0x08, 0x92, 0xe0, 0x5e } \ + } + +typedef struct _EFI_IP4_CONFIG_PROTOCOL EFI_IP4_CONFIG_PROTOCOL; + +#define IP4_CONFIG_VARIABLE_ATTRIBUTES \ + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) + +/// +/// EFI_IP4_IPCONFIG_DATA contains the minimum IPv4 configuration data +/// that is needed to start basic network communication. The StationAddress +/// and SubnetMask must be a valid unicast IP address and subnet mask. +/// If RouteTableSize is not zero, then RouteTable contains a properly +/// formatted routing table for the StationAddress/SubnetMask, with the +/// last entry in the table being the default route. +/// +typedef struct { + /// + /// Default station IP address, stored in network byte order. + /// + EFI_IPv4_ADDRESS StationAddress; + /// + /// Default subnet mask, stored in network byte order. + /// + EFI_IPv4_ADDRESS SubnetMask; + /// + /// Number of entries in the following RouteTable. May be zero. + /// + UINT32 RouteTableSize; + /// + /// Default routing table data (stored in network byte order). + /// Ignored if RouteTableSize is zero. + /// + EFI_IP4_ROUTE_TABLE *RouteTable; +} EFI_IP4_IPCONFIG_DATA; + +/** + Starts running the configuration policy for the EFI IPv4 Protocol driver. + + The Start() function is called to determine and to begin the platform + configuration policy by the EFI IPv4 Protocol driver. This determination may + be as simple as returning EFI_UNSUPPORTED if there is no EFI IPv4 Protocol + driver configuration policy. It may be as involved as loading some defaults + from nonvolatile storage, downloading dynamic data from a DHCP server, and + checking permissions with a site policy server. + Starting the configuration policy is just the beginning. It may finish almost + instantly or it may take several minutes before it fails to retrieve configuration + information from one or more servers. Once the policy is started, drivers + should use the DoneEvent parameter to determine when the configuration policy + has completed. EFI_IP4_CONFIG_PROTOCOL.GetData() must then be called to + determine if the configuration succeeded or failed. + Until the configuration completes successfully, EFI IPv4 Protocol driver instances + that are attempting to use default configurations must return EFI_NO_MAPPING. + Once the configuration is complete, the EFI IPv4 Configuration Protocol driver + signals DoneEvent. The configuration may need to be updated in the future. + Note that in this case the EFI IPv4 Configuration Protocol driver must signal + ReconfigEvent, and all EFI IPv4 Protocol driver instances that are using default + configurations must return EFI_NO_MAPPING until the configuration policy has + been rerun. + + @param This The pointer to the EFI_IP4_CONFIG_PROTOCOL instance. + @param DoneEvent Event that will be signaled when the EFI IPv4 + Protocol driver configuration policy completes + execution. This event must be of type EVT_NOTIFY_SIGNAL. + @param ReconfigEvent Event that will be signaled when the EFI IPv4 + Protocol driver configuration needs to be updated. + This event must be of type EVT_NOTIFY_SIGNAL. + + @retval EFI_SUCCESS The configuration policy for the EFI IPv4 Protocol + driver is now running. + @retval EFI_INVALID_PARAMETER One or more of the following parameters is NULL: + This + DoneEvent + ReconfigEvent + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_ALREADY_STARTED The configuration policy for the EFI IPv4 Protocol + driver was already started. + @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred. + @retval EFI_UNSUPPORTED This interface does not support the EFI IPv4 Protocol + driver configuration. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_CONFIG_START)( + IN EFI_IP4_CONFIG_PROTOCOL *This, + IN EFI_EVENT DoneEvent, + IN EFI_EVENT ReconfigEvent + ); + +/** + Stops running the configuration policy for the EFI IPv4 Protocol driver. + + The Stop() function stops the configuration policy for the EFI IPv4 Protocol driver. + All configuration data will be lost after calling Stop(). + + @param This The pointer to the EFI_IP4_CONFIG_PROTOCOL instance. + + @retval EFI_SUCCESS The configuration policy for the EFI IPv4 Protocol + driver has been stopped. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_STARTED The configuration policy for the EFI IPv4 Protocol + driver was not started. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_CONFIG_STOP)( + IN EFI_IP4_CONFIG_PROTOCOL *This + ); + +/** + Returns the default configuration data (if any) for the EFI IPv4 Protocol driver. + + The GetData() function returns the current configuration data for the EFI IPv4 + Protocol driver after the configuration policy has completed. + + @param This The pointer to the EFI_IP4_CONFIG_PROTOCOL instance. + @param IpConfigDataSize On input, the size of the IpConfigData buffer. + On output, the count of bytes that were written + into the IpConfigData buffer. + @param IpConfigData The pointer to the EFI IPv4 Configuration Protocol + driver configuration data structure. + Type EFI_IP4_IPCONFIG_DATA is defined in + "Related Definitions" below. + + @retval EFI_SUCCESS The EFI IPv4 Protocol driver configuration has been returned. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_STARTED The configuration policy for the EFI IPv4 Protocol + driver is not running. + @retval EFI_NOT_READY EFI IPv4 Protocol driver configuration is still running. + @retval EFI_ABORTED EFI IPv4 Protocol driver configuration could not complete. + @retval EFI_BUFFER_TOO_SMALL *IpConfigDataSize is smaller than the configuration + data buffer or IpConfigData is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_CONFIG_GET_DATA)( + IN EFI_IP4_CONFIG_PROTOCOL *This, + IN OUT UINTN *IpConfigDataSize, + OUT EFI_IP4_IPCONFIG_DATA *IpConfigData OPTIONAL + ); + +/// +/// The EFI_IP4_CONFIG_PROTOCOL driver performs platform-dependent and policy-dependent +/// configurations for the EFI IPv4 Protocol driver. +/// +struct _EFI_IP4_CONFIG_PROTOCOL { + EFI_IP4_CONFIG_START Start; + EFI_IP4_CONFIG_STOP Stop; + EFI_IP4_CONFIG_GET_DATA GetData; +}; + +extern EFI_GUID gEfiIp4ConfigProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Ip4Config2.h b/sys/contrib/edk2/Include/Protocol/Ip4Config2.h new file mode 100644 index 000000000000..407dae229064 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Ip4Config2.h @@ -0,0 +1,316 @@ +/** @file + This file provides a definition of the EFI IPv4 Configuration II + Protocol. + +Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +@par Revision Reference: +This Protocol is introduced in UEFI Specification 2.5 + +**/ + +#ifndef __EFI_IP4CONFIG2_PROTOCOL_H__ +#define __EFI_IP4CONFIG2_PROTOCOL_H__ + +#include <Protocol/Ip4.h> + +#define EFI_IP4_CONFIG2_PROTOCOL_GUID \ + { \ + 0x5b446ed1, 0xe30b, 0x4faa, {0x87, 0x1a, 0x36, 0x54, 0xec, 0xa3, 0x60, 0x80 } \ + } + +typedef struct _EFI_IP4_CONFIG2_PROTOCOL EFI_IP4_CONFIG2_PROTOCOL; + +/// +/// EFI_IP4_CONFIG2_DATA_TYPE +/// +typedef enum { + /// + /// The interface information of the communication device this EFI + /// IPv4 Configuration II Protocol instance manages. This type of + /// data is read only. The corresponding Data is of type + /// EFI_IP4_CONFIG2_INTERFACE_INFO. + /// + Ip4Config2DataTypeInterfaceInfo, + /// + /// The general configuration policy for the EFI IPv4 network stack + /// running on the communication device this EFI IPv4 + /// Configuration II Protocol instance manages. The policy will + /// affect other configuration settings. The corresponding Data is of + /// type EFI_IP4_CONFIG2_POLICY. + /// + Ip4Config2DataTypePolicy, + /// + /// The station addresses set manually for the EFI IPv4 network + /// stack. It is only configurable when the policy is + /// Ip4Config2PolicyStatic. The corresponding Data is of + /// type EFI_IP4_CONFIG2_MANUAL_ADDRESS. When DataSize + /// is 0 and Data is NULL, the existing configuration is cleared + /// from the EFI IPv4 Configuration II Protocol instance. + /// + Ip4Config2DataTypeManualAddress, + /// + /// The gateway addresses set manually for the EFI IPv4 network + /// stack running on the communication device this EFI IPv4 + /// Configuration II Protocol manages. It is not configurable when + /// the policy is Ip4Config2PolicyDhcp. The gateway + /// addresses must be unicast IPv4 addresses. The corresponding + /// Data is a pointer to an array of EFI_IPv4_ADDRESS instances. + /// When DataSize is 0 and Data is NULL, the existing configuration + /// is cleared from the EFI IPv4 Configuration II Protocol instance. + /// + Ip4Config2DataTypeGateway, + /// + /// The DNS server list for the EFI IPv4 network stack running on + /// the communication device this EFI IPv4 Configuration II + /// Protocol manages. It is not configurable when the policy is + /// Ip4Config2PolicyDhcp. The DNS server addresses must be + /// unicast IPv4 addresses. The corresponding Data is a pointer to + /// an array of EFI_IPv4_ADDRESS instances. When DataSize + /// is 0 and Data is NULL, the existing configuration is cleared + /// from the EFI IPv4 Configuration II Protocol instance. + /// + Ip4Config2DataTypeDnsServer, + Ip4Config2DataTypeMaximum +} EFI_IP4_CONFIG2_DATA_TYPE; + +/// +/// EFI_IP4_CONFIG2_INTERFACE_INFO related definitions +/// +#define EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE 32 + +/// +/// EFI_IP4_CONFIG2_INTERFACE_INFO +/// +typedef struct { + /// + /// The name of the interface. It is a NULL-terminated Unicode string. + /// + CHAR16 Name[EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE]; + /// + /// The interface type of the network interface. See RFC 1700, + /// section "Number Hardware Type". + /// + UINT8 IfType; + /// + /// The size, in bytes, of the network interface's hardware address. + /// + UINT32 HwAddressSize; + /// + /// The hardware address for the network interface. + /// + EFI_MAC_ADDRESS HwAddress; + /// + /// The station IPv4 address of this EFI IPv4 network stack. + /// + EFI_IPv4_ADDRESS StationAddress; + /// + /// The subnet address mask that is associated with the station address. + /// + EFI_IPv4_ADDRESS SubnetMask; + /// + /// Size of the following RouteTable, in bytes. May be zero. + /// + UINT32 RouteTableSize; + /// + /// The route table of the IPv4 network stack runs on this interface. + /// Set to NULL if RouteTableSize is zero. Type EFI_IP4_ROUTE_TABLE is defined in + /// EFI_IP4_PROTOCOL.GetModeData(). + /// + EFI_IP4_ROUTE_TABLE *RouteTable OPTIONAL; +} EFI_IP4_CONFIG2_INTERFACE_INFO; + +/// +/// EFI_IP4_CONFIG2_POLICY +/// +typedef enum { + /// + /// Under this policy, the Ip4Config2DataTypeManualAddress, + /// Ip4Config2DataTypeGateway and Ip4Config2DataTypeDnsServer configuration + /// data are required to be set manually. The EFI IPv4 Protocol will get all + /// required configuration such as IPv4 address, subnet mask and + /// gateway settings from the EFI IPv4 Configuration II protocol. + /// + Ip4Config2PolicyStatic, + /// + /// Under this policy, the Ip4Config2DataTypeManualAddress, + /// Ip4Config2DataTypeGateway and Ip4Config2DataTypeDnsServer configuration data are + /// not allowed to set via SetData(). All of these configurations are retrieved from DHCP + /// server or other auto-configuration mechanism. + /// + Ip4Config2PolicyDhcp, + Ip4Config2PolicyMax +} EFI_IP4_CONFIG2_POLICY; + +/// +/// EFI_IP4_CONFIG2_MANUAL_ADDRESS +/// +typedef struct { + /// + /// The IPv4 unicast address. + /// + EFI_IPv4_ADDRESS Address; + /// + /// The subnet mask. + /// + EFI_IPv4_ADDRESS SubnetMask; +} EFI_IP4_CONFIG2_MANUAL_ADDRESS; + +/** + Set the configuration for the EFI IPv4 network stack running on the communication device this EFI + IPv4 Configuration II Protocol instance manages. + + This function is used to set the configuration data of type DataType for the EFI IPv4 network stack + running on the communication device this EFI IPv4 Configuration II Protocol instance manages. + The successfully configured data is valid after system reset or power-off. + The DataSize is used to calculate the count of structure instances in the Data for some + DataType that multiple structure instances are allowed. + This function is always non-blocking. When setting some typeof configuration data, an + asynchronous process is invoked to check the correctness of the data, such as doing address conflict + detection on the manually set local IPv4 address. EFI_NOT_READY is returned immediately to + indicate that such an asynchronous process is invoked and the process is not finished yet. The caller + willing to get the result of the asynchronous process is required to call RegisterDataNotify() + to register an event on the specified configuration data. Once the event is signaled, the caller can call + GetData()to get back the configuration data in order to know the result. For other types of + configuration data that do not require an asynchronous configuration process, the result of the + operation is immediately returned. + + @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance. + @param[in] DataType The type of data to set. + @param[in] DataSize Size of the buffer pointed to by Data in bytes. + @param[in] Data The data buffer to set. The type ofthe data buffer is associated + with the DataType. + + @retval EFI_SUCCESS The specified configuration data for the EFI IPv4 network stack is set + successfully. + @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: + This is NULL. + One or more fields in Data and DataSize do not match the + requirement of the data type indicated by DataType. + @retval EFI_WRITE_PROTECTED The specified configuration data is read-only or the specified configuration + data can not be set under the current policy. + @retval EFI_ACCESS_DENIED Another set operation on the specified configuration data is already in process. + @retval EFI_NOT_READY An asynchronous process is invoked to set the specified configuration data and + the process is not finished yet. + @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type indicated by DataType. + @retval EFI_UNSUPPORTED This DataType is not supported. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_CONFIG2_SET_DATA)( + IN EFI_IP4_CONFIG2_PROTOCOL *This, + IN EFI_IP4_CONFIG2_DATA_TYPE DataType, + IN UINTN DataSize, + IN VOID *Data + ); + +/** + Get the configuration data for the EFI IPv4 network stack running on the communication device this + EFI IPv4 Configuration II Protocol instance manages. + + This function returns the configuration data of type DataType for the EFI IPv4 network stack + running on the communication device this EFI IPv4 Configuration II Protocol instance manages. + The caller is responsible for allocating the buffer usedto return the specified configuration data and + the required size will be returned to the caller if the size of the buffer is too small. + EFI_NOT_READY is returned if the specified configuration data is not ready due to an already in + progress asynchronous configuration process. The caller can call RegisterDataNotify() to + register an event on the specified configuration data. Once the asynchronous configuration process is + finished, the event will be signaled and a subsequent GetData() call will return the specified + configuration data. + + @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance. + @param[in] DataType The type of data to get. + @param[out] DataSize On input, in bytes, the size of Data. On output, in bytes, the size + of buffer required to store the specified configuration data. + @param[in] Data The data buffer in which the configuration data is returned. The + type of the data buffer is associated with the DataType. Ignored + if DataSize is 0. + + @retval EFI_SUCCESS The specified configuration data is got successfully. + @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE: + This is NULL. + DataSize is NULL. + Data is NULL if *DataSizeis not zero. + @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified configuration data + and the required size is returned in DataSize. + @retval EFI_NOT_READY The specified configuration data is not ready due to an already in + progress asynchronous configuration process. + @retval EFI_NOT_FOUND The specified configuration data is not found. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_CONFIG2_GET_DATA)( + IN EFI_IP4_CONFIG2_PROTOCOL *This, + IN EFI_IP4_CONFIG2_DATA_TYPE DataType, + IN OUT UINTN *DataSize, + IN VOID *Data OPTIONAL + ); + +/** + Register an event that is to be signaled whenever a configuration process on the specified + configuration data is done. + + This function registers an event that is to be signaled whenever a configuration process on the + specified configuration data is done. An event can be registered for different DataType + simultaneously and the caller is responsible for determining which type of configuration data causes + the signaling of the event in such case. + + @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance. + @param[in] DataType The type of data to unregister the event for. + @param[in] Event The event to register. + + @retval EFI_SUCCESS The notification event for the specified configuration data is + registered. + @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL. + @retval EFI_UNSUPPORTED The configuration data type specified by DataType is not supported. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_ACCESS_DENIED The Event is already registered for the DataType. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_CONFIG2_REGISTER_NOTIFY)( + IN EFI_IP4_CONFIG2_PROTOCOL *This, + IN EFI_IP4_CONFIG2_DATA_TYPE DataType, + IN EFI_EVENT Event + ); + +/** + Remove a previously registered event for the specified configuration data. + + This function removes a previously registeredevent for the specified configuration data. + + @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance. + @param[in] DataType The type of data to remove the previously registered event for. + @param[in] Event The event to unregister. + + @retval EFI_SUCCESS The event registered for the specified configuration data is removed. + @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL. + @retval EFI_NOT_FOUND The Eventhas not been registered for the specified DataType. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_CONFIG2_UNREGISTER_NOTIFY)( + IN EFI_IP4_CONFIG2_PROTOCOL *This, + IN EFI_IP4_CONFIG2_DATA_TYPE DataType, + IN EFI_EVENT Event + ); + +/// +/// The EFI_IP4_CONFIG2_PROTOCOL is designed to be the central repository for the common +/// configurations and the administrator configurable settings for the EFI IPv4 network stack. +/// An EFI IPv4 Configuration II Protocol instance will be installed on each communication device that +/// the EFI IPv4 network stack runs on. +/// +struct _EFI_IP4_CONFIG2_PROTOCOL { + EFI_IP4_CONFIG2_SET_DATA SetData; + EFI_IP4_CONFIG2_GET_DATA GetData; + EFI_IP4_CONFIG2_REGISTER_NOTIFY RegisterDataNotify; + EFI_IP4_CONFIG2_UNREGISTER_NOTIFY UnregisterDataNotify; +}; + +extern EFI_GUID gEfiIp4Config2ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Ip6.h b/sys/contrib/edk2/Include/Protocol/Ip6.h new file mode 100644 index 000000000000..c5e424c4832f --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Ip6.h @@ -0,0 +1,946 @@ +/** @file + This file defines the EFI IPv6 (Internet Protocol version 6) + Protocol interface. It is split into the following three main + sections: + - EFI IPv6 Service Binding Protocol + - EFI IPv6 Variable (deprecated in UEFI 2.4B) + - EFI IPv6 Protocol + The EFI IPv6 Protocol provides basic network IPv6 packet I/O services, + which includes support for Neighbor Discovery Protocol (ND), Multicast + Listener Discovery Protocol (MLD), and a subset of the Internet Control + Message Protocol (ICMPv6). + + Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.2 + +**/ + +#ifndef __EFI_IP6_PROTOCOL_H__ +#define __EFI_IP6_PROTOCOL_H__ + +#include <Protocol/ManagedNetwork.h> + +#define EFI_IP6_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0xec835dd3, 0xfe0f, 0x617b, {0xa6, 0x21, 0xb3, 0x50, 0xc3, 0xe1, 0x33, 0x88 } \ + } + +#define EFI_IP6_PROTOCOL_GUID \ + { \ + 0x2c8759d5, 0x5c2d, 0x66ef, {0x92, 0x5f, 0xb6, 0x6c, 0x10, 0x19, 0x57, 0xe2 } \ + } + +typedef struct _EFI_IP6_PROTOCOL EFI_IP6_PROTOCOL; + +/// +/// EFI_IP6_ADDRESS_PAIR is deprecated in the UEFI 2.4B and should not be used any more. +/// The definition in here is only present to provide backwards compatability. +/// +typedef struct { + /// + /// The EFI IPv6 Protocol instance handle that is using this address/prefix pair. + /// + EFI_HANDLE InstanceHandle; + /// + /// IPv6 address in network byte order. + /// + EFI_IPv6_ADDRESS Ip6Address; + /// + /// The length of the prefix associated with the Ip6Address. + /// + UINT8 PrefixLength; +} EFI_IP6_ADDRESS_PAIR; + +/// +/// EFI_IP6_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more. +/// The definition in here is only present to provide backwards compatability. +/// +typedef struct { + /// + /// The handle of the driver that creates this entry. + /// + EFI_HANDLE DriverHandle; + /// + /// The number of IPv6 address pairs that follow this data structure. + /// + UINT32 AddressCount; + /// + /// List of IPv6 address pairs that are currently in use. + /// + EFI_IP6_ADDRESS_PAIR AddressPairs[1]; +} EFI_IP6_VARIABLE_DATA; + +/// +/// ICMPv6 type definitions for error messages +/// +///@{ +#define ICMP_V6_DEST_UNREACHABLE 0x1 +#define ICMP_V6_PACKET_TOO_BIG 0x2 +#define ICMP_V6_TIME_EXCEEDED 0x3 +#define ICMP_V6_PARAMETER_PROBLEM 0x4 +///@} + +/// +/// ICMPv6 type definition for informational messages +/// +///@{ +#define ICMP_V6_ECHO_REQUEST 0x80 +#define ICMP_V6_ECHO_REPLY 0x81 +#define ICMP_V6_LISTENER_QUERY 0x82 +#define ICMP_V6_LISTENER_REPORT 0x83 +#define ICMP_V6_LISTENER_DONE 0x84 +#define ICMP_V6_ROUTER_SOLICIT 0x85 +#define ICMP_V6_ROUTER_ADVERTISE 0x86 +#define ICMP_V6_NEIGHBOR_SOLICIT 0x87 +#define ICMP_V6_NEIGHBOR_ADVERTISE 0x88 +#define ICMP_V6_REDIRECT 0x89 +#define ICMP_V6_LISTENER_REPORT_2 0x8F +///@} + +/// +/// ICMPv6 code definitions for ICMP_V6_DEST_UNREACHABLE +/// +///@{ +#define ICMP_V6_NO_ROUTE_TO_DEST 0x0 +#define ICMP_V6_COMM_PROHIBITED 0x1 +#define ICMP_V6_BEYOND_SCOPE 0x2 +#define ICMP_V6_ADDR_UNREACHABLE 0x3 +#define ICMP_V6_PORT_UNREACHABLE 0x4 +#define ICMP_V6_SOURCE_ADDR_FAILED 0x5 +#define ICMP_V6_ROUTE_REJECTED 0x6 +///@} + +/// +/// ICMPv6 code definitions for ICMP_V6_TIME_EXCEEDED +/// +///@{ +#define ICMP_V6_TIMEOUT_HOP_LIMIT 0x0 +#define ICMP_V6_TIMEOUT_REASSEMBLE 0x1 +///@} + +/// +/// ICMPv6 code definitions for ICMP_V6_PARAMETER_PROBLEM +/// +///@{ +#define ICMP_V6_ERRONEOUS_HEADER 0x0 +#define ICMP_V6_UNRECOGNIZE_NEXT_HDR 0x1 +#define ICMP_V6_UNRECOGNIZE_OPTION 0x2 +///@} + +/// +/// EFI_IP6_CONFIG_DATA +/// is used to report and change IPv6 session parameters. +/// +typedef struct { + /// + /// For the IPv6 packet to send and receive, this is the default value + /// of the 'Next Header' field in the last IPv6 extension header or in + /// the IPv6 header if there are no extension headers. Ignored when + /// AcceptPromiscuous is TRUE. + /// + UINT8 DefaultProtocol; + /// + /// Set to TRUE to receive all IPv6 packets that get through the + /// receive filters. + /// Set to FALSE to receive only the DefaultProtocol IPv6 + /// packets that get through the receive filters. Ignored when + /// AcceptPromiscuous is TRUE. + /// + BOOLEAN AcceptAnyProtocol; + /// + /// Set to TRUE to receive ICMP error report packets. Ignored when + /// AcceptPromiscuous or AcceptAnyProtocol is TRUE. + /// + BOOLEAN AcceptIcmpErrors; + /// + /// Set to TRUE to receive all IPv6 packets that are sent to any + /// hardware address or any protocol address. Set to FALSE to stop + /// receiving all promiscuous IPv6 packets. + /// + BOOLEAN AcceptPromiscuous; + /// + /// The destination address of the packets that will be transmitted. + /// Ignored if it is unspecified. + /// + EFI_IPv6_ADDRESS DestinationAddress; + /// + /// The station IPv6 address that will be assigned to this EFI IPv6 + /// Protocol instance. This field can be set and changed only when + /// the EFI IPv6 driver is transitioning from the stopped to the started + /// states. If the StationAddress is specified, the EFI IPv6 Protocol + /// driver will deliver only incoming IPv6 packets whose destination + /// matches this IPv6 address exactly. The StationAddress is required + /// to be one of currently configured IPv6 addresses. An address + /// containing all zeroes is also accepted as a special case. Under this + /// situation, the IPv6 driver is responsible for binding a source + /// address to this EFI IPv6 protocol instance according to the source + /// address selection algorithm. Only incoming packets destined to + /// the selected address will be delivered to the user. And the + /// selected station address can be retrieved through later + /// GetModeData() call. If no address is available for selecting, + /// EFI_NO_MAPPING will be returned, and the station address will + /// only be successfully bound to this EFI IPv6 protocol instance + /// after IP6ModeData.IsConfigured changed to TRUE. + /// + EFI_IPv6_ADDRESS StationAddress; + /// + /// TrafficClass field in transmitted IPv6 packets. Default value + /// is zero. + /// + UINT8 TrafficClass; + /// + /// HopLimit field in transmitted IPv6 packets. + /// + UINT8 HopLimit; + /// + /// FlowLabel field in transmitted IPv6 packets. Default value is + /// zero. + /// + UINT32 FlowLabel; + /// + /// The timer timeout value (number of microseconds) for the + /// receive timeout event to be associated with each assembled + /// packet. Zero means do not drop assembled packets. + /// + UINT32 ReceiveTimeout; + /// + /// The timer timeout value (number of microseconds) for the + /// transmit timeout event to be associated with each outgoing + /// packet. Zero means do not drop outgoing packets. + /// + UINT32 TransmitTimeout; +} EFI_IP6_CONFIG_DATA; + +/// +/// EFI_IP6_ADDRESS_INFO +/// +typedef struct { + EFI_IPv6_ADDRESS Address; ///< The IPv6 address. + UINT8 PrefixLength; ///< The length of the prefix associated with the Address. +} EFI_IP6_ADDRESS_INFO; + +/// +/// EFI_IP6_ROUTE_TABLE +/// is the entry structure that is used in routing tables +/// +typedef struct { + /// + /// The IPv6 address of the gateway to be used as the next hop for + /// packets to this prefix. If the IPv6 address is all zeros, then the + /// prefix is on-link. + /// + EFI_IPv6_ADDRESS Gateway; + /// + /// The destination prefix to be routed. + /// + EFI_IPv6_ADDRESS Destination; + /// + /// The length of the prefix associated with the Destination. + /// + UINT8 PrefixLength; +} EFI_IP6_ROUTE_TABLE; + +/// +/// EFI_IP6_NEIGHBOR_STATE +/// +typedef enum { + /// + /// Address resolution is being performed on this entry. Specially, + /// Neighbor Solicitation has been sent to the solicited-node + /// multicast address of the target, but corresponding Neighbor + /// Advertisement has not been received. + /// + EfiNeighborInComplete, + /// + /// Positive confirmation was received that the forward path to the + /// neighbor was functioning properly. + /// + EfiNeighborReachable, + /// + /// Reachable Time has elapsed since the last positive confirmation + /// was received. In this state, the forward path to the neighbor was + /// functioning properly. + /// + EfiNeighborStale, + /// + /// This state is an optimization that gives upper-layer protocols + /// additional time to provide reachability confirmation. + /// + EfiNeighborDelay, + /// + /// A reachability confirmation is actively sought by retransmitting + /// Neighbor Solicitations every RetransTimer milliseconds until a + /// reachability confirmation is received. + /// + EfiNeighborProbe +} EFI_IP6_NEIGHBOR_STATE; + +/// +/// EFI_IP6_NEIGHBOR_CACHE +/// is the entry structure that is used in neighbor cache. It records a set +/// of entries about individual neighbors to which traffic has been sent recently. +/// +typedef struct { + EFI_IPv6_ADDRESS Neighbor; ///< The on-link unicast/anycast IP address of the neighbor. + EFI_MAC_ADDRESS LinkAddress; ///< Link-layer address of the neighbor. + EFI_IP6_NEIGHBOR_STATE State; ///< State of this neighbor cache entry. +} EFI_IP6_NEIGHBOR_CACHE; + +/// +/// EFI_IP6_ICMP_TYPE +/// is used to describe those ICMP messages that are supported by this EFI +/// IPv6 Protocol driver. +/// +typedef struct { + UINT8 Type; ///< The type of ICMP message. + UINT8 Code; ///< The code of the ICMP message. +} EFI_IP6_ICMP_TYPE; + +/// +/// EFI_IP6_MODE_DATA +/// +typedef struct { + /// + /// Set to TRUE after this EFI IPv6 Protocol instance is started. + /// All other fields in this structure are undefined until this field is TRUE. + /// Set to FALSE when the EFI IPv6 Protocol instance is stopped. + /// + BOOLEAN IsStarted; + /// + /// The maximum packet size, in bytes, of the packet which the upper layer driver could feed. + /// + UINT32 MaxPacketSize; + /// + /// Current configuration settings. Undefined until IsStarted is TRUE. + /// + EFI_IP6_CONFIG_DATA ConfigData; + /// + /// Set to TRUE when the EFI IPv6 Protocol instance is configured. + /// The instance is configured when it has a station address and + /// corresponding prefix length. + /// Set to FALSE when the EFI IPv6 Protocol instance is not configured. + /// + BOOLEAN IsConfigured; + /// + /// Number of configured IPv6 addresses on this interface. + /// + UINT32 AddressCount; + /// + /// List of currently configured IPv6 addresses and corresponding + /// prefix lengths assigned to this interface. It is caller's + /// responsibility to free this buffer. + /// + EFI_IP6_ADDRESS_INFO *AddressList; + /// + /// Number of joined multicast groups. Undefined until + /// IsConfigured is TRUE. + /// + UINT32 GroupCount; + /// + /// List of joined multicast group addresses. It is caller's + /// responsibility to free this buffer. Undefined until + /// IsConfigured is TRUE. + /// + EFI_IPv6_ADDRESS *GroupTable; + /// + /// Number of entries in the routing table. Undefined until + /// IsConfigured is TRUE. + /// + UINT32 RouteCount; + /// + /// Routing table entries. It is caller's responsibility to free this buffer. + /// + EFI_IP6_ROUTE_TABLE *RouteTable; + /// + /// Number of entries in the neighbor cache. Undefined until + /// IsConfigured is TRUE. + /// + UINT32 NeighborCount; + /// + /// Neighbor cache entries. It is caller's responsibility to free this + /// buffer. Undefined until IsConfigured is TRUE. + /// + EFI_IP6_NEIGHBOR_CACHE *NeighborCache; + /// + /// Number of entries in the prefix table. Undefined until + /// IsConfigured is TRUE. + /// + UINT32 PrefixCount; + /// + /// On-link Prefix table entries. It is caller's responsibility to free this + /// buffer. Undefined until IsConfigured is TRUE. + /// + EFI_IP6_ADDRESS_INFO *PrefixTable; + /// + /// Number of entries in the supported ICMP types list. + /// + UINT32 IcmpTypeCount; + /// + /// Array of ICMP types and codes that are supported by this EFI + /// IPv6 Protocol driver. It is caller's responsibility to free this + /// buffer. + /// + EFI_IP6_ICMP_TYPE *IcmpTypeList; +} EFI_IP6_MODE_DATA; + +/// +/// EFI_IP6_HEADER +/// The fields in the IPv6 header structure are defined in the Internet +/// Protocol version6 specification. +/// +#pragma pack(1) +typedef struct _EFI_IP6_HEADER { + UINT8 TrafficClassH : 4; + UINT8 Version : 4; + UINT8 FlowLabelH : 4; + UINT8 TrafficClassL : 4; + UINT16 FlowLabelL; + UINT16 PayloadLength; + UINT8 NextHeader; + UINT8 HopLimit; + EFI_IPv6_ADDRESS SourceAddress; + EFI_IPv6_ADDRESS DestinationAddress; +} EFI_IP6_HEADER; +#pragma pack() + +/// +/// EFI_IP6_FRAGMENT_DATA +/// describes the location and length of the IPv6 packet +/// fragment to transmit or that has been received. +/// +typedef struct _EFI_IP6_FRAGMENT_DATA { + UINT32 FragmentLength; ///< Length of fragment data. This field may not be set to zero. + VOID *FragmentBuffer; ///< Pointer to fragment data. This field may not be set to NULL. +} EFI_IP6_FRAGMENT_DATA; + +/// +/// EFI_IP6_RECEIVE_DATA +/// +typedef struct _EFI_IP6_RECEIVE_DATA { + /// + /// Time when the EFI IPv6 Protocol driver accepted the packet. + /// Ignored if it is zero. + /// + EFI_TIME TimeStamp; + /// + /// After this event is signaled, the receive data structure is released + /// and must not be referenced. + /// + EFI_EVENT RecycleSignal; + /// + /// Length of the IPv6 packet headers, including both the IPv6 + /// header and any extension headers. + /// + UINT32 HeaderLength; + /// + /// Pointer to the IPv6 packet header. If the IPv6 packet was + /// fragmented, this argument is a pointer to the header in the first + /// fragment. + /// + EFI_IP6_HEADER *Header; + /// + /// Sum of the lengths of IPv6 packet buffers in FragmentTable. May + /// be zero. + /// + UINT32 DataLength; + /// + /// Number of IPv6 payload fragments. May be zero. + /// + UINT32 FragmentCount; + /// + /// Array of payload fragment lengths and buffer pointers. + /// + EFI_IP6_FRAGMENT_DATA FragmentTable[1]; +} EFI_IP6_RECEIVE_DATA; + +/// +/// EFI_IP6_OVERRIDE_DATA +/// The information and flags in the override data structure will override +/// default parameters or settings for one Transmit() function call. +/// +typedef struct _EFI_IP6_OVERRIDE_DATA { + UINT8 Protocol; ///< Protocol type override. + UINT8 HopLimit; ///< Hop-Limit override. + UINT32 FlowLabel; ///< Flow-Label override. +} EFI_IP6_OVERRIDE_DATA; + +/// +/// EFI_IP6_TRANSMIT_DATA +/// +typedef struct _EFI_IP6_TRANSMIT_DATA { + /// + /// The destination IPv6 address. If it is unspecified, + /// ConfigData.DestinationAddress will be used instead. + /// + EFI_IPv6_ADDRESS DestinationAddress; + /// + /// If not NULL, the IPv6 transmission control override data. + /// + EFI_IP6_OVERRIDE_DATA *OverrideData; + /// + /// Total length in byte of the IPv6 extension headers specified in + /// ExtHdrs. + /// + UINT32 ExtHdrsLength; + /// + /// Pointer to the IPv6 extension headers. The IP layer will append + /// the required extension headers if they are not specified by + /// ExtHdrs. Ignored if ExtHdrsLength is zero. + /// + VOID *ExtHdrs; + /// + /// The protocol of first extension header in ExtHdrs. Ignored if + /// ExtHdrsLength is zero. + /// + UINT8 NextHeader; + /// + /// Total length in bytes of the FragmentTable data to transmit. + /// + UINT32 DataLength; + /// + /// Number of entries in the fragment data table. + /// + UINT32 FragmentCount; + /// + /// Start of the fragment data table. + /// + EFI_IP6_FRAGMENT_DATA FragmentTable[1]; +} EFI_IP6_TRANSMIT_DATA; + +/// +/// EFI_IP6_COMPLETION_TOKEN +/// structures are used for both transmit and receive operations. +/// +typedef struct { + /// + /// This Event will be signaled after the Status field is updated by + /// the EFI IPv6 Protocol driver. The type of Event must be EFI_NOTIFY_SIGNAL. + /// + EFI_EVENT Event; + /// + /// Will be set to one of the following values: + /// - EFI_SUCCESS: The receive or transmit completed + /// successfully. + /// - EFI_ABORTED: The receive or transmit was aborted + /// - EFI_TIMEOUT: The transmit timeout expired. + /// - EFI_ICMP_ERROR: An ICMP error packet was received. + /// - EFI_DEVICE_ERROR: An unexpected system or network + /// error occurred. + /// - EFI_SECURITY_VIOLATION: The transmit or receive was + /// failed because of an IPsec policy check. + /// - EFI_NO_MEDIA: There was a media error. + /// + EFI_STATUS Status; + union { + /// + /// When the Token is used for receiving, RxData is a pointer to the EFI_IP6_RECEIVE_DATA. + /// + EFI_IP6_RECEIVE_DATA *RxData; + /// + /// When the Token is used for transmitting, TxData is a pointer to the EFI_IP6_TRANSMIT_DATA. + /// + EFI_IP6_TRANSMIT_DATA *TxData; + } Packet; +} EFI_IP6_COMPLETION_TOKEN; + +/** + Gets the current operational settings for this instance of the EFI IPv6 Protocol driver. + + The GetModeData() function returns the current operational mode data for this driver instance. + The data fields in EFI_IP6_MODE_DATA are read only. This function is used optionally to + retrieve the operational mode data of underlying networks or drivers.. + + @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. + @param[out] Ip6ModeData Pointer to the EFI IPv6 Protocol mode data structure. + @param[out] MnpConfigData Pointer to the managed network configuration data structure. + @param[out] SnpModeData Pointer to the simple network mode data structure. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_GET_MODE_DATA)( + IN EFI_IP6_PROTOCOL *This, + OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL, + OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, + OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL + ); + +/** + Assigns an IPv6 address and subnet mask to this EFI IPv6 Protocol driver instance. + + The Configure() function is used to set, change, or reset the operational parameters and filter + settings for this EFI IPv6 Protocol instance. Until these parameters have been set, no network traffic + can be sent or received by this instance. Once the parameters have been reset (by calling this + function with Ip6ConfigData set to NULL), no more traffic can be sent or received until these + parameters have been set again. Each EFI IPv6 Protocol instance can be started and stopped + independently of each other by enabling or disabling their receive filter settings with the + Configure() function. + + If Ip6ConfigData.StationAddress is a valid non-zero IPv6 unicast address, it is required + to be one of the currently configured IPv6 addresses list in the EFI IPv6 drivers, or else + EFI_INVALID_PARAMETER will be returned. If Ip6ConfigData.StationAddress is + unspecified, the IPv6 driver will bind a source address according to the source address selection + algorithm. Clients could frequently call GetModeData() to check get currently configured IPv6 + address list in the EFI IPv6 driver. If both Ip6ConfigData.StationAddress and + Ip6ConfigData.Destination are unspecified, when transmitting the packet afterwards, the + source address filled in each outgoing IPv6 packet is decided based on the destination of this packet. . + + If operational parameters are reset or changed, any pending transmit and receive requests will be + cancelled. Their completion token status will be set to EFI_ABORTED and their events will be + signaled. + + @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. + @param[in] Ip6ConfigData Pointer to the EFI IPv6 Protocol configuration data structure. + + @retval EFI_SUCCESS The driver instance was successfully opened. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - Ip6ConfigData.StationAddress is neither zero nor + a unicast IPv6 address. + - Ip6ConfigData.StationAddress is neither zero nor + one of the configured IP addresses in the EFI IPv6 driver. + - Ip6ConfigData.DefaultProtocol is illegal. + @retval EFI_OUT_OF_RESOURCES The EFI IPv6 Protocol driver instance data could not be allocated. + @retval EFI_NO_MAPPING The IPv6 driver was responsible for choosing a source address for + this instance, but no source address was available for use. + @retval EFI_ALREADY_STARTED The interface is already open and must be stopped before the IPv6 + address or prefix length can be changed. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI IPv6 + Protocol driver instance is not opened. + @retval EFI_UNSUPPORTED Default protocol specified through + Ip6ConfigData.DefaulProtocol isn't supported. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_CONFIGURE)( + IN EFI_IP6_PROTOCOL *This, + IN EFI_IP6_CONFIG_DATA *Ip6ConfigData OPTIONAL + ); + +/** + Joins and leaves multicast groups. + + The Groups() function is used to join and leave multicast group sessions. Joining a group will + enable reception of matching multicast packets. Leaving a group will disable reception of matching + multicast packets. Source-Specific Multicast isn't required to be supported. + + If JoinFlag is FALSE and GroupAddress is NULL, all joined groups will be left. + + @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. + @param[in] JoinFlag Set to TRUE to join the multicast group session and FALSE to leave. + @param[in] GroupAddress Pointer to the IPv6 multicast address. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER One or more of the following is TRUE: + - This is NULL. + - JoinFlag is TRUE and GroupAddress is NULL. + - GroupAddress is not NULL and *GroupAddress is + not a multicast IPv6 address. + - GroupAddress is not NULL and *GroupAddress is in the + range of SSM destination address. + @retval EFI_NOT_STARTED This instance has not been started. + @retval EFI_OUT_OF_RESOURCES System resources could not be allocated. + @retval EFI_UNSUPPORTED This EFI IPv6 Protocol implementation does not support multicast groups. + @retval EFI_ALREADY_STARTED The group address is already in the group table (when + JoinFlag is TRUE). + @retval EFI_NOT_FOUND The group address is not in the group table (when JoinFlag is FALSE). + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_GROUPS)( + IN EFI_IP6_PROTOCOL *This, + IN BOOLEAN JoinFlag, + IN EFI_IPv6_ADDRESS *GroupAddress OPTIONAL + ); + +/** + Adds and deletes routing table entries. + + The Routes() function adds a route to or deletes a route from the routing table. + + Routes are determined by comparing the leftmost PrefixLength bits of Destination with + the destination IPv6 address arithmetically. The gateway address must be on the same subnet as the + configured station address. + + The default route is added with Destination and PrefixLegth both set to all zeros. The + default route matches all destination IPv6 addresses that do not match any other routes. + + All EFI IPv6 Protocol instances share a routing table. + + @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. + @param[in] DeleteRoute Set to TRUE to delete this route from the routing table. Set to + FALSE to add this route to the routing table. Destination, + PrefixLength and Gateway are used as the key to each + route entry. + @param[in] Destination The address prefix of the subnet that needs to be routed. + @param[in] PrefixLength The prefix length of Destination. Ignored if Destination + is NULL. + @param[in] GatewayAddress The unicast gateway IPv6 address for this route. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_NOT_STARTED The driver instance has not been started. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - When DeleteRoute is TRUE, both Destination and + GatewayAddress are NULL. + - When DeleteRoute is FALSE, either Destination or + GatewayAddress is NULL. + - *GatewayAddress is not a valid unicast IPv6 address. + - *GatewayAddress is one of the local configured IPv6 + addresses. + @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table. + @retval EFI_NOT_FOUND This route is not in the routing table (when DeleteRoute is TRUE). + @retval EFI_ACCESS_DENIED The route is already defined in the routing table (when + DeleteRoute is FALSE). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_ROUTES)( + IN EFI_IP6_PROTOCOL *This, + IN BOOLEAN DeleteRoute, + IN EFI_IPv6_ADDRESS *Destination OPTIONAL, + IN UINT8 PrefixLength, + IN EFI_IPv6_ADDRESS *GatewayAddress OPTIONAL + ); + +/** + Add or delete Neighbor cache entries. + + The Neighbors() function is used to add, update, or delete an entry from neighbor cache. + IPv6 neighbor cache entries are typically inserted and updated by the network protocol driver as + network traffic is processed. Most neighbor cache entries will time out and be deleted if the network + traffic stops. Neighbor cache entries that were inserted by Neighbors() may be static (will not + timeout) or dynamic (will time out). + + The implementation should follow the neighbor cache timeout mechanism which is defined in + RFC4861. The default neighbor cache timeout value should be tuned for the expected network + environment + + @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. + @param[in] DeleteFlag Set to TRUE to delete the specified cache entry, set to FALSE to + add (or update, if it already exists and Override is TRUE) the + specified cache entry. TargetIp6Address is used as the key + to find the requested cache entry. + @param[in] TargetIp6Address Pointer to Target IPv6 address. + @param[in] TargetLinkAddress Pointer to link-layer address of the target. Ignored if NULL. + @param[in] Timeout Time in 100-ns units that this entry will remain in the neighbor + cache, it will be deleted after Timeout. A value of zero means that + the entry is permanent. A non-zero value means that the entry is + dynamic. + @param[in] Override If TRUE, the cached link-layer address of the matching entry will + be overridden and updated; if FALSE, EFI_ACCESS_DENIED + will be returned if a corresponding cache entry already existed. + + @retval EFI_SUCCESS The data has been queued for transmission. + @retval EFI_NOT_STARTED This instance has not been started. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - TargetIpAddress is NULL. + - *TargetLinkAddress is invalid when not NULL. + - *TargetIpAddress is not a valid unicast IPv6 address. + - *TargetIpAddress is one of the local configured IPv6 + addresses. + @retval EFI_OUT_OF_RESOURCES Could not add the entry to the neighbor cache. + @retval EFI_NOT_FOUND This entry is not in the neighbor cache (when DeleteFlag is + TRUE or when DeleteFlag is FALSE while + TargetLinkAddress is NULL.). + @retval EFI_ACCESS_DENIED The to-be-added entry is already defined in the neighbor cache, + and that entry is tagged as un-overridden (when DeleteFlag + is FALSE). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_NEIGHBORS)( + IN EFI_IP6_PROTOCOL *This, + IN BOOLEAN DeleteFlag, + IN EFI_IPv6_ADDRESS *TargetIp6Address, + IN EFI_MAC_ADDRESS *TargetLinkAddress, + IN UINT32 Timeout, + IN BOOLEAN Override + ); + +/** + Places outgoing data packets into the transmit queue. + + The Transmit() function places a sending request in the transmit queue of this + EFI IPv6 Protocol instance. Whenever the packet in the token is sent out or some + errors occur, the event in the token will be signaled and the status is updated. + + @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. + @param[in] Token Pointer to the transmit token. + + @retval EFI_SUCCESS The data has been queued for transmission. + @retval EFI_NOT_STARTED This instance has not been started. + @retval EFI_NO_MAPPING The IPv6 driver was responsible for choosing a source address for + this transmission, but no source address was available for use. + @retval EFI_INVALID_PARAMETER One or more of the following is TRUE: + - This is NULL. + - Token is NULL. + - Token.Event is NULL. + - Token.Packet.TxData is NULL. + - Token.Packet.ExtHdrsLength is not zero and Token.Packet.ExtHdrs is NULL. + - Token.Packet.FragmentCount is zero. + - One or more of the Token.Packet.TxData.FragmentTable[].FragmentLength fields is zero. + - One or more of the Token.Packet.TxData.FragmentTable[].FragmentBuffer fields is NULL. + - Token.Packet.TxData.DataLength is zero or not equal to the sum of fragment lengths. + - Token.Packet.TxData.DestinationAddress is non-zero when DestinationAddress is configured as + non-zero when doing Configure() for this EFI IPv6 protocol instance. + - Token.Packet.TxData.DestinationAddress is unspecified when DestinationAddress is unspecified + when doing Configure() for this EFI IPv6 protocol instance. + @retval EFI_ACCESS_DENIED The transmit completion token with the same Token.Event + was already in the transmit queue. + @retval EFI_NOT_READY The completion token could not be queued because the transmit + queue is full. + @retval EFI_NOT_FOUND Not route is found to destination address. + @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data. + @retval EFI_BUFFER_TOO_SMALL Token.Packet.TxData.TotalDataLength is too + short to transmit. + @retval EFI_BAD_BUFFER_SIZE If Token.Packet.TxData.DataLength is beyond the + maximum that which can be described through the Fragment Offset + field in Fragment header when performing fragmentation. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_TRANSMIT)( + IN EFI_IP6_PROTOCOL *This, + IN EFI_IP6_COMPLETION_TOKEN *Token + ); + +/** + Places a receiving request into the receiving queue. + + The Receive() function places a completion token into the receive packet queue. + This function is always asynchronous. + + The Token.Event field in the completion token must be filled in by the caller + and cannot be NULL. When the receive operation completes, the EFI IPv6 Protocol + driver updates the Token.Status and Token.Packet.RxData fields and the Token.Event + is signaled. + + @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. + @param[in] Token Pointer to a token that is associated with the receive data descriptor. + + @retval EFI_SUCCESS The receive completion token was cached. + @retval EFI_NOT_STARTED This EFI IPv6 Protocol instance has not been started. + @retval EFI_NO_MAPPING When IP6 driver responsible for binding source address to this instance, + while no source address is available for use. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - Token is NULL. + - Token.Event is NULL. + @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of system + resources (usually memory). + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + The EFI IPv6 Protocol instance has been reset to startup defaults. + @retval EFI_ACCESS_DENIED The receive completion token with the same Token.Event was already + in the receive queue. + @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_RECEIVE)( + IN EFI_IP6_PROTOCOL *This, + IN EFI_IP6_COMPLETION_TOKEN *Token + ); + +/** + Abort an asynchronous transmit or receive request. + + The Cancel() function is used to abort a pending transmit or receive request. + If the token is in the transmit or receive request queues, after calling this + function, Token->Status will be set to EFI_ABORTED and then Token->Event will + be signaled. If the token is not in one of the queues, which usually means the + asynchronous operation has completed, this function will not signal the token + and EFI_NOT_FOUND is returned. + + @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. + @param[in] Token Pointer to a token that has been issued by + EFI_IP6_PROTOCOL.Transmit() or + EFI_IP6_PROTOCOL.Receive(). If NULL, all pending + tokens are aborted. Type EFI_IP6_COMPLETION_TOKEN is + defined in EFI_IP6_PROTOCOL.Transmit(). + + @retval EFI_SUCCESS The asynchronous I/O request was aborted and + Token->Event was signaled. When Token is NULL, all + pending requests were aborted and their events were signaled. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_STARTED This instance has not been started. + @retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O request was + not found in the transmit or receive queue. It has either completed + or was not issued by Transmit() and Receive(). + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_CANCEL)( + IN EFI_IP6_PROTOCOL *This, + IN EFI_IP6_COMPLETION_TOKEN *Token OPTIONAL + ); + +/** + Polls for incoming data packets and processes outgoing data packets. + + The Poll() function polls for incoming data packets and processes outgoing data + packets. Network drivers and applications can call the EFI_IP6_PROTOCOL.Poll() + function to increase the rate that data packets are moved between the communications + device and the transmit and receive queues. + + In some systems the periodic timer event may not poll the underlying communications + device fast enough to transmit and/or receive all data packets without missing + incoming packets or dropping outgoing packets. Drivers and applications that are + experiencing packet loss should try calling the EFI_IP6_PROTOCOL.Poll() function + more often. + + @param[in] This Pointer to the EFI_IP6_PROTOCOL instance. + + @retval EFI_SUCCESS Incoming or outgoing data was processed. + @retval EFI_NOT_STARTED This EFI IPv6 Protocol instance has not been started. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_NOT_READY No incoming or outgoing data is processed. + @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. + Consider increasing the polling rate. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_POLL)( + IN EFI_IP6_PROTOCOL *This + ); + +/// +/// The EFI IPv6 Protocol implements a simple packet-oriented interface that can be +/// used by drivers, daemons, and applications to transmit and receive network packets. +/// +struct _EFI_IP6_PROTOCOL { + EFI_IP6_GET_MODE_DATA GetModeData; + EFI_IP6_CONFIGURE Configure; + EFI_IP6_GROUPS Groups; + EFI_IP6_ROUTES Routes; + EFI_IP6_NEIGHBORS Neighbors; + EFI_IP6_TRANSMIT Transmit; + EFI_IP6_RECEIVE Receive; + EFI_IP6_CANCEL Cancel; + EFI_IP6_POLL Poll; +}; + +extern EFI_GUID gEfiIp6ServiceBindingProtocolGuid; +extern EFI_GUID gEfiIp6ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/LoadFile.h b/sys/contrib/edk2/Include/Protocol/LoadFile.h new file mode 100644 index 000000000000..5a341469a10f --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/LoadFile.h @@ -0,0 +1,82 @@ +/** @file + Load File protocol as defined in the UEFI 2.0 specification. + + The load file protocol exists to supports the addition of new boot devices, + and to support booting from devices that do not map well to file system. + Network boot is done via a LoadFile protocol. + + UEFI 2.0 can boot from any device that produces a LoadFile protocol. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_LOAD_FILE_PROTOCOL_H__ +#define __EFI_LOAD_FILE_PROTOCOL_H__ + +#define EFI_LOAD_FILE_PROTOCOL_GUID \ + { \ + 0x56EC3091, 0x954C, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ + } + +/// +/// Protocol Guid defined by EFI1.1. +/// +#define LOAD_FILE_PROTOCOL EFI_LOAD_FILE_PROTOCOL_GUID + +typedef struct _EFI_LOAD_FILE_PROTOCOL EFI_LOAD_FILE_PROTOCOL; + +/// +/// Backward-compatible with EFI1.1 +/// +typedef EFI_LOAD_FILE_PROTOCOL EFI_LOAD_FILE_INTERFACE; + +/** + Causes the driver to load a specified file. + + @param This Protocol instance pointer. + @param FilePath The device specific path of the file to load. + @param BootPolicy If TRUE, indicates that the request originates from the + boot manager is attempting to load FilePath as a boot + selection. If FALSE, then FilePath must match as exact file + to be loaded. + @param BufferSize On input the size of Buffer in bytes. On output with a return + code of EFI_SUCCESS, the amount of data transferred to + Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL, + the size of Buffer required to retrieve the requested file. + @param Buffer The memory buffer to transfer the file to. IF Buffer is NULL, + then the size of the requested file is returned in + BufferSize. + + @retval EFI_SUCCESS The file was loaded. + @retval EFI_UNSUPPORTED The device does not support the provided BootPolicy + @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or + BufferSize is NULL. + @retval EFI_NO_MEDIA No medium was present to load the file. + @retval EFI_DEVICE_ERROR The file was not loaded due to a device error. + @retval EFI_NO_RESPONSE The remote system did not respond. + @retval EFI_NOT_FOUND The file was not found. + @retval EFI_ABORTED The file load process was manually cancelled. + @retval EFI_WARN_FILE_SYSTEM The resulting Buffer contains UEFI-compliant file system. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_LOAD_FILE)( + IN EFI_LOAD_FILE_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN BOOLEAN BootPolicy, + IN OUT UINTN *BufferSize, + IN VOID *Buffer OPTIONAL + ); + +/// +/// The EFI_LOAD_FILE_PROTOCOL is a simple protocol used to obtain files from arbitrary devices. +/// +struct _EFI_LOAD_FILE_PROTOCOL { + EFI_LOAD_FILE LoadFile; +}; + +extern EFI_GUID gEfiLoadFileProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/LoadedImage.h b/sys/contrib/edk2/Include/Protocol/LoadedImage.h new file mode 100644 index 000000000000..3a693a7248a7 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/LoadedImage.h @@ -0,0 +1,82 @@ +/** @file + UEFI 2.0 Loaded image protocol definition. + + Every EFI driver and application is passed an image handle when it is loaded. + This image handle will contain a Loaded Image Protocol. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __LOADED_IMAGE_PROTOCOL_H__ +#define __LOADED_IMAGE_PROTOCOL_H__ + +#define EFI_LOADED_IMAGE_PROTOCOL_GUID \ + { \ + 0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ + } + +#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \ + { \ + 0xbc62157e, 0x3e33, 0x4fec, {0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } \ + } + +/// +/// Protocol GUID defined in EFI1.1. +/// +#define LOADED_IMAGE_PROTOCOL EFI_LOADED_IMAGE_PROTOCOL_GUID + +/// +/// EFI_SYSTEM_TABLE & EFI_IMAGE_UNLOAD are defined in EfiApi.h +/// +#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000 + +/// +/// Revision defined in EFI1.1. +/// +#define EFI_LOADED_IMAGE_INFORMATION_REVISION EFI_LOADED_IMAGE_PROTOCOL_REVISION + +/// +/// Can be used on any image handle to obtain information about the loaded image. +/// +typedef struct { + UINT32 Revision; ///< Defines the revision of the EFI_LOADED_IMAGE_PROTOCOL structure. + ///< All future revisions will be backward compatible to the current revision. + EFI_HANDLE ParentHandle; ///< Parent image's image handle. NULL if the image is loaded directly from + ///< the firmware's boot manager. + EFI_SYSTEM_TABLE *SystemTable; ///< the image's EFI system table pointer. + + // + // Source location of image + // + EFI_HANDLE DeviceHandle; ///< The device handle that the EFI Image was loaded from. + EFI_DEVICE_PATH_PROTOCOL *FilePath; ///< A pointer to the file path portion specific to DeviceHandle + ///< that the EFI Image was loaded from. + VOID *Reserved; ///< Reserved. DO NOT USE. + + // + // Images load options + // + UINT32 LoadOptionsSize; ///< The size in bytes of LoadOptions. + VOID *LoadOptions; ///< A pointer to the image's binary load options. + + // + // Location of where image was loaded + // + VOID *ImageBase; ///< The base address at which the image was loaded. + UINT64 ImageSize; ///< The size in bytes of the loaded image. + EFI_MEMORY_TYPE ImageCodeType; ///< The memory type that the code sections were loaded as. + EFI_MEMORY_TYPE ImageDataType; ///< The memory type that the data sections were loaded as. + EFI_IMAGE_UNLOAD Unload; +} EFI_LOADED_IMAGE_PROTOCOL; + +// +// For backward-compatible with EFI1.1. +// +typedef EFI_LOADED_IMAGE_PROTOCOL EFI_LOADED_IMAGE; + +extern EFI_GUID gEfiLoadedImageProtocolGuid; +extern EFI_GUID gEfiLoadedImageDevicePathProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/ManagedNetwork.h b/sys/contrib/edk2/Include/Protocol/ManagedNetwork.h new file mode 100644 index 000000000000..0230705da2a1 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/ManagedNetwork.h @@ -0,0 +1,364 @@ +/** @file + EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL as defined in UEFI 2.0. + EFI_MANAGED_NETWORK_PROTOCOL as defined in UEFI 2.0. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.0 + +**/ + +#ifndef __EFI_MANAGED_NETWORK_PROTOCOL_H__ +#define __EFI_MANAGED_NETWORK_PROTOCOL_H__ + +#include <Protocol/SimpleNetwork.h> + +#define EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0xf36ff770, 0xa7e1, 0x42cf, {0x9e, 0xd2, 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c } \ + } + +#define EFI_MANAGED_NETWORK_PROTOCOL_GUID \ + { \ + 0x7ab33a91, 0xace5, 0x4326, { 0xb5, 0x72, 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16 } \ + } + +typedef struct _EFI_MANAGED_NETWORK_PROTOCOL EFI_MANAGED_NETWORK_PROTOCOL; + +typedef struct { + /// + /// Timeout value for a UEFI one-shot timer event. A packet that has not been removed + /// from the MNP receive queue will be dropped if its receive timeout expires. + /// + UINT32 ReceivedQueueTimeoutValue; + /// + /// Timeout value for a UEFI one-shot timer event. A packet that has not been removed + /// from the MNP transmit queue will be dropped if its receive timeout expires. + /// + UINT32 TransmitQueueTimeoutValue; + /// + /// Ethernet type II 16-bit protocol type in host byte order. Valid + /// values are zero and 1,500 to 65,535. + /// + UINT16 ProtocolTypeFilter; + /// + /// Set to TRUE to receive packets that are sent to the network + /// device MAC address. The startup default value is FALSE. + /// + BOOLEAN EnableUnicastReceive; + /// + /// Set to TRUE to receive packets that are sent to any of the + /// active multicast groups. The startup default value is FALSE. + /// + BOOLEAN EnableMulticastReceive; + /// + /// Set to TRUE to receive packets that are sent to the network + /// device broadcast address. The startup default value is FALSE. + /// + BOOLEAN EnableBroadcastReceive; + /// + /// Set to TRUE to receive packets that are sent to any MAC address. + /// The startup default value is FALSE. + /// + BOOLEAN EnablePromiscuousReceive; + /// + /// Set to TRUE to drop queued packets when the configuration + /// is changed. The startup default value is FALSE. + /// + BOOLEAN FlushQueuesOnReset; + /// + /// Set to TRUE to timestamp all packets when they are received + /// by the MNP. Note that timestamps may be unsupported in some + /// MNP implementations. The startup default value is FALSE. + /// + BOOLEAN EnableReceiveTimestamps; + /// + /// Set to TRUE to disable background polling in this MNP + /// instance. Note that background polling may not be supported in + /// all MNP implementations. The startup default value is FALSE, + /// unless background polling is not supported. + /// + BOOLEAN DisableBackgroundPolling; +} EFI_MANAGED_NETWORK_CONFIG_DATA; + +typedef struct { + EFI_TIME Timestamp; + EFI_EVENT RecycleEvent; + UINT32 PacketLength; + UINT32 HeaderLength; + UINT32 AddressLength; + UINT32 DataLength; + BOOLEAN BroadcastFlag; + BOOLEAN MulticastFlag; + BOOLEAN PromiscuousFlag; + UINT16 ProtocolType; + VOID *DestinationAddress; + VOID *SourceAddress; + VOID *MediaHeader; + VOID *PacketData; +} EFI_MANAGED_NETWORK_RECEIVE_DATA; + +typedef struct { + UINT32 FragmentLength; + VOID *FragmentBuffer; +} EFI_MANAGED_NETWORK_FRAGMENT_DATA; + +typedef struct { + EFI_MAC_ADDRESS *DestinationAddress; // OPTIONAL + EFI_MAC_ADDRESS *SourceAddress; // OPTIONAL + UINT16 ProtocolType; // OPTIONAL + UINT32 DataLength; + UINT16 HeaderLength; // OPTIONAL + UINT16 FragmentCount; + EFI_MANAGED_NETWORK_FRAGMENT_DATA FragmentTable[1]; +} EFI_MANAGED_NETWORK_TRANSMIT_DATA; + +typedef struct { + /// + /// This Event will be signaled after the Status field is updated + /// by the MNP. The type of Event must be + /// EFI_NOTIFY_SIGNAL. The Task Priority Level (TPL) of + /// Event must be lower than or equal to TPL_CALLBACK. + /// + EFI_EVENT Event; + /// + /// The status that is returned to the caller at the end of the operation + /// to indicate whether this operation completed successfully. + /// + EFI_STATUS Status; + union { + /// + /// When this token is used for receiving, RxData is a pointer to the EFI_MANAGED_NETWORK_RECEIVE_DATA. + /// + EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData; + /// + /// When this token is used for transmitting, TxData is a pointer to the EFI_MANAGED_NETWORK_TRANSMIT_DATA. + /// + EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData; + } Packet; +} EFI_MANAGED_NETWORK_COMPLETION_TOKEN; + +/** + Returns the operational parameters for the current MNP child driver. + + @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. + @param MnpConfigData The pointer to storage for MNP operational parameters. + @param SnpModeData The pointer to storage for SNP operational parameters. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_UNSUPPORTED The requested feature is unsupported in this MNP implementation. + @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. The default + values are returned in MnpConfigData if it is not NULL. + @retval Other The mode data could not be read. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MANAGED_NETWORK_GET_MODE_DATA)( + IN EFI_MANAGED_NETWORK_PROTOCOL *This, + OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, + OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL + ); + +/** + Sets or clears the operational parameters for the MNP child driver. + + @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. + @param MnpConfigData The pointer to configuration data that will be assigned to the MNP + child driver instance. If NULL, the MNP child driver instance is + reset to startup defaults and all pending transmit and receive + requests are flushed. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Required system resources (usually memory) could not be + allocated. + @retval EFI_UNSUPPORTED The requested feature is unsupported in this [MNP] + implementation. + @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. + @retval Other The MNP child driver instance has been reset to startup defaults. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MANAGED_NETWORK_CONFIGURE)( + IN EFI_MANAGED_NETWORK_PROTOCOL *This, + IN EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL + ); + +/** + Translates an IP multicast address to a hardware (MAC) multicast address. + + @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. + @param Ipv6Flag Set to TRUE to if IpAddress is an IPv6 multicast address. + Set to FALSE if IpAddress is an IPv4 multicast address. + @param IpAddress The pointer to the multicast IP address (in network byte order) to convert. + @param MacAddress The pointer to the resulting multicast MAC address. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER One of the following conditions is TRUE: + - This is NULL. + - IpAddress is NULL. + - *IpAddress is not a valid multicast IP address. + - MacAddress is NULL. + @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. + @retval EFI_UNSUPPORTED The requested feature is unsupported in this MNP implementation. + @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. + @retval Other The address could not be converted. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MANAGED_NETWORK_MCAST_IP_TO_MAC)( + IN EFI_MANAGED_NETWORK_PROTOCOL *This, + IN BOOLEAN Ipv6Flag, + IN EFI_IP_ADDRESS *IpAddress, + OUT EFI_MAC_ADDRESS *MacAddress + ); + +/** + Enables and disables receive filters for multicast address. + + @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. + @param JoinFlag Set to TRUE to join this multicast group. + Set to FALSE to leave this multicast group. + @param MacAddress The pointer to the multicast MAC group (address) to join or leave. + + @retval EFI_SUCCESS The requested operation completed successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - JoinFlag is TRUE and MacAddress is NULL. + - *MacAddress is not a valid multicast MAC address. + @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. + @retval EFI_ALREADY_STARTED The supplied multicast group is already joined. + @retval EFI_NOT_FOUND The supplied multicast group is not joined. + @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. + @retval EFI_UNSUPPORTED The requested feature is unsupported in this MNP implementation. + @retval Other The requested operation could not be completed. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MANAGED_NETWORK_GROUPS)( + IN EFI_MANAGED_NETWORK_PROTOCOL *This, + IN BOOLEAN JoinFlag, + IN EFI_MAC_ADDRESS *MacAddress OPTIONAL + ); + +/** + Places asynchronous outgoing data packets into the transmit queue. + + @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. + @param Token The pointer to a token associated with the transmit data descriptor. + + @retval EFI_SUCCESS The transmit completion token was cached. + @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_ACCESS_DENIED The transmit completion token is already in the transmit queue. + @retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a lack of system resources + (usually memory). + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_NOT_READY The transmit request could not be queued because the transmit queue is full. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MANAGED_NETWORK_TRANSMIT)( + IN EFI_MANAGED_NETWORK_PROTOCOL *This, + IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token + ); + +/** + Places an asynchronous receiving request into the receiving queue. + + @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. + @param Token The pointer to a token associated with the receive data descriptor. + + @retval EFI_SUCCESS The receive completion token was cached. + @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - Token is NULL. + - Token.Event is NULL. + @retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a lack of system resources + (usually memory). + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_ACCESS_DENIED The receive completion token was already in the receive queue. + @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MANAGED_NETWORK_RECEIVE)( + IN EFI_MANAGED_NETWORK_PROTOCOL *This, + IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token + ); + +/** + Aborts an asynchronous transmit or receive request. + + @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. + @param Token The pointer to a token that has been issued by + EFI_MANAGED_NETWORK_PROTOCOL.Transmit() or + EFI_MANAGED_NETWORK_PROTOCOL.Receive(). If + NULL, all pending tokens are aborted. + + @retval EFI_SUCCESS The asynchronous I/O request was aborted and Token.Event + was signaled. When Token is NULL, all pending requests were + aborted and their events were signaled. + @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O request was + not found in the transmit or receive queue. It has either completed + or was not issued by Transmit() and Receive(). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MANAGED_NETWORK_CANCEL)( + IN EFI_MANAGED_NETWORK_PROTOCOL *This, + IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token OPTIONAL + ); + +/** + Polls for incoming data packets and processes outgoing data packets. + + @param This The pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance. + + @retval EFI_SUCCESS Incoming or outgoing data was processed. + @retval EFI_NOT_STARTED This MNP child driver instance has not been configured. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_NOT_READY No incoming or outgoing data was processed. Consider increasing + the polling rate. + @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. + Consider increasing the polling rate. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MANAGED_NETWORK_POLL)( + IN EFI_MANAGED_NETWORK_PROTOCOL *This + ); + +/// +/// The MNP is used by network applications (and drivers) to +/// perform raw (unformatted) asynchronous network packet I/O. +/// +struct _EFI_MANAGED_NETWORK_PROTOCOL { + EFI_MANAGED_NETWORK_GET_MODE_DATA GetModeData; + EFI_MANAGED_NETWORK_CONFIGURE Configure; + EFI_MANAGED_NETWORK_MCAST_IP_TO_MAC McastIpToMac; + EFI_MANAGED_NETWORK_GROUPS Groups; + EFI_MANAGED_NETWORK_TRANSMIT Transmit; + EFI_MANAGED_NETWORK_RECEIVE Receive; + EFI_MANAGED_NETWORK_CANCEL Cancel; + EFI_MANAGED_NETWORK_POLL Poll; +}; + +extern EFI_GUID gEfiManagedNetworkServiceBindingProtocolGuid; +extern EFI_GUID gEfiManagedNetworkProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Metronome.h b/sys/contrib/edk2/Include/Protocol/Metronome.h new file mode 100644 index 000000000000..f08c7f4d9e4b --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Metronome.h @@ -0,0 +1,74 @@ +/** @file + Metronome Architectural Protocol as defined in PI SPEC VOLUME 2 DXE + + This code abstracts the DXE core to provide delay services. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_METRONOME_H__ +#define __ARCH_PROTOCOL_METRONOME_H__ + +/// +/// Global ID for the Metronome Architectural Protocol +/// +#define EFI_METRONOME_ARCH_PROTOCOL_GUID \ + { 0x26baccb2, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +/// +/// Declare forward reference for the Metronome Architectural Protocol +/// +typedef struct _EFI_METRONOME_ARCH_PROTOCOL EFI_METRONOME_ARCH_PROTOCOL; + +/** + The WaitForTick() function waits for the number of ticks specified by + TickNumber from a known time source in the platform. If TickNumber of + ticks are detected, then EFI_SUCCESS is returned. The actual time passed + between entry of this function and the first tick is between 0 and + TickPeriod 100 nS units. If you want to guarantee that at least TickPeriod + time has elapsed, wait for two ticks. This function waits for a hardware + event to determine when a tick occurs. It is possible for interrupt + processing, or exception processing to interrupt the execution of the + WaitForTick() function. Depending on the hardware source for the ticks, it + is possible for a tick to be missed. This function cannot guarantee that + ticks will not be missed. If a timeout occurs waiting for the specified + number of ticks, then EFI_TIMEOUT is returned. + + @param This The EFI_METRONOME_ARCH_PROTOCOL instance. + @param TickNumber Number of ticks to wait. + + @retval EFI_SUCCESS The wait for the number of ticks specified by TickNumber + succeeded. + @retval EFI_TIMEOUT A timeout occurred waiting for the specified number of ticks. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_METRONOME_WAIT_FOR_TICK)( + IN EFI_METRONOME_ARCH_PROTOCOL *This, + IN UINT32 TickNumber + ); + +/// +/// This protocol provides access to a known time source in the platform to the +/// core. The core uses this known time source to produce core services that +/// require calibrated delays. +/// +struct _EFI_METRONOME_ARCH_PROTOCOL { + EFI_METRONOME_WAIT_FOR_TICK WaitForTick; + + /// + /// The period of platform's known time source in 100 nS units. + /// This value on any platform must be at least 10 uS, and must not + /// exceed 200 uS. The value in this field is a constant that must + /// not be modified after the Metronome architectural protocol is + /// installed. All consumers must treat this as a read-only field. + /// + UINT32 TickPeriod; +}; + +extern EFI_GUID gEfiMetronomeArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/MonotonicCounter.h b/sys/contrib/edk2/Include/Protocol/MonotonicCounter.h new file mode 100644 index 000000000000..fa14b8b70dfe --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/MonotonicCounter.h @@ -0,0 +1,22 @@ +/** @file + Monotonic Counter Architectural Protocol as defined in PI SPEC VOLUME 2 DXE + + This code provides the services required to access the system's monotonic counter + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_MONTONIC_COUNTER_H__ +#define __ARCH_PROTOCOL_MONTONIC_COUNTER_H__ + +/// +/// Global ID for the Monotonic Counter Architectural Protocol. +/// +#define EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL_GUID \ + {0x1da97072, 0xbddc, 0x4b30, {0x99, 0xf1, 0x72, 0xa0, 0xb5, 0x6f, 0xff, 0x2a} } + +extern EFI_GUID gEfiMonotonicCounterArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/MpService.h b/sys/contrib/edk2/Include/Protocol/MpService.h new file mode 100644 index 000000000000..9846c16fc230 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/MpService.h @@ -0,0 +1,674 @@ +/** @file + When installed, the MP Services Protocol produces a collection of services + that are needed for MP management. + + The MP Services Protocol provides a generalized way of performing following tasks: + - Retrieving information of multi-processor environment and MP-related status of + specific processors. + - Dispatching user-provided function to APs. + - Maintain MP-related processor status. + + The MP Services Protocol must be produced on any system with more than one logical + processor. + + The Protocol is available only during boot time. + + MP Services Protocol is hardware-independent. Most of the logic of this protocol + is architecturally neutral. It abstracts the multi-processor environment and + status of processors, and provides interfaces to retrieve information, maintain, + and dispatch. + + MP Services Protocol may be consumed by ACPI module. The ACPI module may use this + protocol to retrieve data that are needed for an MP platform and report them to OS. + MP Services Protocol may also be used to program and configure processors, such + as MTRR synchronization for memory space attributes setting in DXE Services. + MP Services Protocol may be used by non-CPU DXE drivers to speed up platform boot + by taking advantage of the processing capabilities of the APs, for example, using + APs to help test system memory in parallel with other device initialization. + Diagnostics applications may also use this protocol for multi-processor. + +Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is defined in the UEFI Platform Initialization Specification 1.2, + Volume 2:Driver Execution Environment Core Interface. + +**/ + +#ifndef _MP_SERVICE_PROTOCOL_H_ +#define _MP_SERVICE_PROTOCOL_H_ + +/// +/// Global ID for the EFI_MP_SERVICES_PROTOCOL. +/// +#define EFI_MP_SERVICES_PROTOCOL_GUID \ + { \ + 0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08} \ + } + +/// +/// Value used in the NumberProcessors parameter of the GetProcessorInfo function +/// +#define CPU_V2_EXTENDED_TOPOLOGY BIT24 + +/// +/// Forward declaration for the EFI_MP_SERVICES_PROTOCOL. +/// +typedef struct _EFI_MP_SERVICES_PROTOCOL EFI_MP_SERVICES_PROTOCOL; + +/// +/// Terminator for a list of failed CPUs returned by StartAllAPs(). +/// +#define END_OF_CPU_LIST 0xffffffff + +/// +/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and +/// indicates whether the processor is playing the role of BSP. If the bit is 1, +/// then the processor is BSP. Otherwise, it is AP. +/// +#define PROCESSOR_AS_BSP_BIT 0x00000001 + +/// +/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and +/// indicates whether the processor is enabled. If the bit is 1, then the +/// processor is enabled. Otherwise, it is disabled. +/// +#define PROCESSOR_ENABLED_BIT 0x00000002 + +/// +/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and +/// indicates whether the processor is healthy. If the bit is 1, then the +/// processor is healthy. Otherwise, some fault has been detected for the processor. +/// +#define PROCESSOR_HEALTH_STATUS_BIT 0x00000004 + +/// +/// Structure that describes the pyhiscal location of a logical CPU. +/// +typedef struct { + /// + /// Zero-based physical package number that identifies the cartridge of the processor. + /// + UINT32 Package; + /// + /// Zero-based physical core number within package of the processor. + /// + UINT32 Core; + /// + /// Zero-based logical thread number within core of the processor. + /// + UINT32 Thread; +} EFI_CPU_PHYSICAL_LOCATION; + +/// +/// Structure that defines the 6-level physical location of the processor +/// +typedef struct { + /// + /// Package Zero-based physical package number that identifies the cartridge of the processor. + /// + UINT32 Package; + /// + /// Module Zero-based physical module number within package of the processor. + /// + UINT32 Module; + /// + /// Tile Zero-based physical tile number within module of the processor. + /// + UINT32 Tile; + /// + /// Die Zero-based physical die number within tile of the processor. + /// + UINT32 Die; + /// + /// Core Zero-based physical core number within die of the processor. + /// + UINT32 Core; + /// + /// Thread Zero-based logical thread number within core of the processor. + /// + UINT32 Thread; +} EFI_CPU_PHYSICAL_LOCATION2; + +typedef union { + /// The 6-level physical location of the processor, including the + /// physical package number that identifies the cartridge, the physical + /// module number within package, the physical tile number within the module, + /// the physical die number within the tile, the physical core number within + /// package, and logical thread number within core. + EFI_CPU_PHYSICAL_LOCATION2 Location2; +} EXTENDED_PROCESSOR_INFORMATION; + +/// +/// Structure that describes information about a logical CPU. +/// +typedef struct { + /// + /// The unique processor ID determined by system hardware. For IA32 and X64, + /// the processor ID is the same as the Local APIC ID. Only the lower 8 bits + /// are used, and higher bits are reserved. For IPF, the lower 16 bits contains + /// id/eid, and higher bits are reserved. + /// + UINT64 ProcessorId; + /// + /// Flags indicating if the processor is BSP or AP, if the processor is enabled + /// or disabled, and if the processor is healthy. Bits 3..31 are reserved and + /// must be 0. + /// + /// <pre> + /// BSP ENABLED HEALTH Description + /// === ======= ====== =================================================== + /// 0 0 0 Unhealthy Disabled AP. + /// 0 0 1 Healthy Disabled AP. + /// 0 1 0 Unhealthy Enabled AP. + /// 0 1 1 Healthy Enabled AP. + /// 1 0 0 Invalid. The BSP can never be in the disabled state. + /// 1 0 1 Invalid. The BSP can never be in the disabled state. + /// 1 1 0 Unhealthy Enabled BSP. + /// 1 1 1 Healthy Enabled BSP. + /// </pre> + /// + UINT32 StatusFlag; + /// + /// The physical location of the processor, including the physical package number + /// that identifies the cartridge, the physical core number within package, and + /// logical thread number within core. + /// + EFI_CPU_PHYSICAL_LOCATION Location; + /// + /// The extended information of the processor. This field is filled only when + /// CPU_V2_EXTENDED_TOPOLOGY is set in parameter ProcessorNumber. + EXTENDED_PROCESSOR_INFORMATION ExtendedInformation; +} EFI_PROCESSOR_INFORMATION; + +/** + This service retrieves the number of logical processor in the platform + and the number of those logical processors that are enabled on this boot. + This service may only be called from the BSP. + + This function is used to retrieve the following information: + - The number of logical processors that are present in the system. + - The number of enabled logical processors in the system at the instant + this call is made. + + Because MP Service Protocol provides services to enable and disable processors + dynamically, the number of enabled logical processors may vary during the + course of a boot session. + + If this service is called from an AP, then EFI_DEVICE_ERROR is returned. + If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then + EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors + is returned in NumberOfProcessors, the number of currently enabled processor + is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[out] NumberOfProcessors Pointer to the total number of logical + processors in the system, including the BSP + and disabled APs. + @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical + processors that exist in system, including + the BSP. + + @retval EFI_SUCCESS The number of logical processors and enabled + logical processors was retrieved. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL. + @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS)( + IN EFI_MP_SERVICES_PROTOCOL *This, + OUT UINTN *NumberOfProcessors, + OUT UINTN *NumberOfEnabledProcessors + ); + +/** + Gets detailed MP-related information on the requested processor at the + instant this call is made. This service may only be called from the BSP. + + This service retrieves detailed MP-related information about any processor + on the platform. Note the following: + - The processor information may change during the course of a boot session. + - The information presented here is entirely MP related. + + Information regarding the number of caches and their sizes, frequency of operation, + slot numbers is all considered platform-related information and is not provided + by this service. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[in] ProcessorNumber The handle number of processor. + @param[out] ProcessorInfoBuffer A pointer to the buffer where information for + the requested processor is deposited. + + @retval EFI_SUCCESS Processor information was returned. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist in the platform. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MP_SERVICES_GET_PROCESSOR_INFO)( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer + ); + +/** + This service executes a caller provided function on all enabled APs. APs can + run either simultaneously or one at a time in sequence. This service supports + both blocking and non-blocking requests. The non-blocking requests use EFI + events so the BSP can detect when the APs have finished. This service may only + be called from the BSP. + + This function is used to dispatch all the enabled APs to the function specified + by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned + immediately and Procedure is not started on any AP. + + If SingleThread is TRUE, all the enabled APs execute the function specified by + Procedure one by one, in ascending order of processor handle number. Otherwise, + all the enabled APs execute the function specified by Procedure simultaneously. + + If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all + APs finish or TimeoutInMicroSecs expires. Otherwise, execution is in non-blocking + mode, and the BSP returns from this service without waiting for APs. If a + non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT + is signaled, then EFI_UNSUPPORTED must be returned. + + If the timeout specified by TimeoutInMicroseconds expires before all APs return + from Procedure, then Procedure on the failed APs is terminated. All enabled APs + are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its + content points to the list of processor handle numbers in which Procedure was + terminated. + + Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + to make sure that the nature of the code that is executed on the BSP and the + dispatched APs is well controlled. The MP Services Protocol does not guarantee + that the Procedure function is MP-safe. Hence, the tasks that can be run in + parallel are limited to certain independent tasks and well-controlled exclusive + code. EFI services and protocols may not be called by APs unless otherwise + specified. + + In blocking execution mode, BSP waits until all APs finish or + TimeoutInMicroSeconds expires. + + In non-blocking execution mode, BSP is freed to return to the caller and then + proceed to the next task without having to wait for APs. The following + sequence needs to occur in a non-blocking execution mode: + + -# The caller that intends to use this MP Services Protocol in non-blocking + mode creates WaitEvent by calling the EFI CreateEvent() service. The caller + invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent + is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests + the function specified by Procedure to be started on all the enabled APs, + and releases the BSP to continue with other tasks. + -# The caller can use the CheckEvent() and WaitForEvent() services to check + the state of the WaitEvent created in step 1. + -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP + Service signals WaitEvent by calling the EFI SignalEvent() function. If + FailedCpuList is not NULL, its content is available when WaitEvent is + signaled. If all APs returned from Procedure prior to the timeout, then + FailedCpuList is set to NULL. If not all APs return from Procedure before + the timeout, then FailedCpuList is filled in with the list of the failed + APs. The buffer is allocated by MP Service Protocol using AllocatePool(). + It is the caller's responsibility to free the buffer with FreePool() service. + -# This invocation of SignalEvent() function informs the caller that invoked + EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed + the specified task or a timeout occurred. The contents of FailedCpuList + can be examined to determine which APs did not complete the specified task + prior to the timeout. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. See type + EFI_AP_PROCEDURE. + @param[in] SingleThread If TRUE, then all the enabled APs execute + the function specified by Procedure one by + one, in ascending order of processor handle + number. If FALSE, then all the enabled APs + execute the function specified by Procedure + simultaneously. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until all APs finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on all the enabled + APs, and go on executing immediately. If + all return from Procedure, or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + all APs return from Procedure, then Procedure + on the failed APs is terminated. All enabled + APs are available for next function assigned + by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + or EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise, + if all APs finish successfully, then its + content is set to NULL. If not all APs + finish before timeout expires, then its + content is set to address of the buffer + holding handle numbers of the failed APs. + The buffer is allocated by MP Service Protocol, + and it's the caller's responsibility to + free the buffer with FreePool() service. + In blocking mode, it is ready for consumption + when the call returns. In non-blocking mode, + it is ready when WaitEvent is signaled. The + list of failed CPU is terminated by + END_OF_CPU_LIST. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_DEVICE_ERROR Caller processor is AP. + @retval EFI_NOT_STARTED No enabled APs exist in the system. + @retval EFI_NOT_READY Any enabled APs are busy. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + all enabled APs have finished. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MP_SERVICES_STARTUP_ALL_APS)( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroSeconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL + ); + +/** + This service lets the caller get one enabled AP to execute a caller-provided + function. The caller can request the BSP to either wait for the completion + of the AP or just proceed with the next task by using the EFI event mechanism. + See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking + execution support. This service may only be called from the BSP. + + This function is used to dispatch one enabled AP to the function specified by + Procedure passing in the argument specified by ProcedureArgument. If WaitEvent + is NULL, execution is in blocking mode. The BSP waits until the AP finishes or + TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode. + BSP proceeds to the next task without waiting for the AP. If a non-blocking mode + is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, + then EFI_UNSUPPORTED must be returned. + + If the timeout specified by TimeoutInMicroseconds expires before the AP returns + from Procedure, then execution of Procedure by the AP is terminated. The AP is + available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and + EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL + instance. + @param[in] Procedure A pointer to the function to be run on the + designated AP of the system. See type + EFI_AP_PROCEDURE. + @param[in] ProcessorNumber The handle number of the AP. The range is + from 0 to the total number of logical + processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. If it is NULL, then execute in + blocking mode. BSP waits until this AP finish + or TimeoutInMicroSeconds expires. If it's + not NULL, then execute in non-blocking mode. + BSP requests the function specified by + Procedure to be started on this AP, + and go on executing immediately. If this AP + return from Procedure or TimeoutInMicroSeconds + expires, this event is signaled. The BSP + can use the CheckEvent() or WaitForEvent() + services to check the state of event. Type + EFI_EVENT is defined in CreateEvent() in + the Unified Extensible Firmware Interface + Specification. + @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for + this AP to finish this Procedure, either for + blocking or non-blocking mode. Zero means + infinity. If the timeout expires before + this AP returns from Procedure, then Procedure + on the AP is terminated. The + AP is available for next function assigned + by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() + or EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). + If the timeout expires in blocking mode, + BSP returns EFI_TIMEOUT. If the timeout + expires in non-blocking mode, WaitEvent + is signaled with SignalEvent(). + @param[in] ProcedureArgument The parameter passed into Procedure on the + specified AP. + @param[out] Finished If NULL, this parameter is ignored. In + blocking mode, this parameter is ignored. + In non-blocking mode, if AP returns from + Procedure before the timeout expires, its + content is set to TRUE. Otherwise, the + value is set to FALSE. The caller can + determine if the AP returned from Procedure + by evaluating this value. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before + the timeout expires. + @retval EFI_SUCCESS In non-blocking mode, the function has been + dispatched to specified AP. + @retval EFI_UNSUPPORTED A non-blocking mode request was made after the + UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was + signaled. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_TIMEOUT In blocking mode, the timeout expired before + the specified AP has finished. + @retval EFI_NOT_READY The specified AP is busy. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. + @retval EFI_INVALID_PARAMETER Procedure is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MP_SERVICES_STARTUP_THIS_AP)( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL + ); + +/** + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. This call can only be performed + by the current BSP. + + This service switches the requested AP to be the BSP from that point onward. + This service changes the BSP for all purposes. The new BSP can take over the + execution of the old BSP and continue seamlessly from where the old one left + off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT + is signaled. + + If the BSP cannot be switched prior to the return from this service, then + EFI_UNSUPPORTED must be returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of AP that is to become the new + BSP. The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an + enabled AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to + this service returning. + @retval EFI_UNSUPPORTED Switching the BSP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND The processor with the handle specified by + ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or + a disabled AP. + @retval EFI_NOT_READY The specified AP is busy. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MP_SERVICES_SWITCH_BSP)( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ); + +/** + This service lets the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + This service allows the caller enable or disable an AP from this point onward. + The caller can optionally specify the health status of the AP by Health. If + an AP is being disabled, then the state of the disabled AP is implementation + dependent. If an AP is enabled, then the implementation must guarantee that a + complete initialization sequence is performed on the AP, so the AP is in a state + that is compatible with an MP operating system. This service may not be supported + after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. + + If the enable or disable AP operation cannot be completed prior to the return + from this service, then EFI_UNSUPPORTED must be returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. + @param[in] ProcessorNumber The handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + @param[in] EnableAP Specifies the new state for the processor for + enabled, FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies + the new health status of the AP. This flag + corresponds to StatusFlag defined in + EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only + the PROCESSOR_HEALTH_STATUS_BIT is used. All other + bits are ignored. If it is NULL, this parameter + is ignored. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed + prior to this service returning. + @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. + @retval EFI_DEVICE_ERROR The calling processor is an AP. + @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber + does not exist. + @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MP_SERVICES_ENABLEDISABLEAP)( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ); + +/** + This return the handle number for the calling processor. This service may be + called from the BSP and APs. + + This service returns the processor handle number for the calling processor. + The returned value is in the range from 0 to the total number of logical + processors minus 1. The total number of logical processors can be retrieved + with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be + called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER + is returned. Otherwise, the current processors handle number is returned in + ProcessorNumber, and EFI_SUCCESS is returned. + + @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. + @param[in] ProcessorNumber Pointer to the handle number of AP. + The range is from 0 to the total number of + logical processors minus 1. The total number of + logical processors can be retrieved by + EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). + + @retval EFI_SUCCESS The current processor handle number was returned + in ProcessorNumber. + @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MP_SERVICES_WHOAMI)( + IN EFI_MP_SERVICES_PROTOCOL *This, + OUT UINTN *ProcessorNumber + ); + +/// +/// When installed, the MP Services Protocol produces a collection of services +/// that are needed for MP management. +/// +/// Before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the module +/// that produces this protocol is required to place all APs into an idle state +/// whenever the APs are disabled or the APs are not executing code as requested +/// through the StartupAllAPs() or StartupThisAP() services. The idle state of +/// an AP before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled is +/// implementation dependent. +/// +/// After the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, all the APs +/// must be placed in the OS compatible CPU state as defined by the UEFI +/// Specification. Implementations of this protocol may use the UEFI event +/// EFI_EVENT_GROUP_READY_TO_BOOT to force APs into the OS compatible state as +/// defined by the UEFI Specification. Modules that use this protocol must +/// guarantee that all non-blocking mode requests on all APs have been completed +/// before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. Since the +/// order that event notification functions in the same event group are executed +/// is not deterministic, an event of type EFI_EVENT_GROUP_READY_TO_BOOT cannot +/// be used to guarantee that APs have completed their non-blocking mode requests. +/// +/// When the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the StartAllAPs() +/// and StartupThisAp() services must no longer support non-blocking mode requests. +/// The support for SwitchBSP() and EnableDisableAP() may no longer be supported +/// after this event is signaled. Since UEFI Applications and UEFI OS Loaders +/// execute after the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, these +/// UEFI images must be aware that the functionality of this protocol may be reduced. +/// +struct _EFI_MP_SERVICES_PROTOCOL { + EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors; + EFI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo; + EFI_MP_SERVICES_STARTUP_ALL_APS StartupAllAPs; + EFI_MP_SERVICES_STARTUP_THIS_AP StartupThisAP; + EFI_MP_SERVICES_SWITCH_BSP SwitchBSP; + EFI_MP_SERVICES_ENABLEDISABLEAP EnableDisableAP; + EFI_MP_SERVICES_WHOAMI WhoAmI; +}; + +extern EFI_GUID gEfiMpServiceProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Mtftp4.h b/sys/contrib/edk2/Include/Protocol/Mtftp4.h new file mode 100644 index 000000000000..28f54274a354 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Mtftp4.h @@ -0,0 +1,576 @@ +/** @file + EFI Multicast Trivial File Transfer Protocol Definition + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.0 + +**/ + +#ifndef __EFI_MTFTP4_PROTOCOL_H__ +#define __EFI_MTFTP4_PROTOCOL_H__ + +#define EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0x2FE800BE, 0x8F01, 0x4aa6, {0x94, 0x6B, 0xD7, 0x13, 0x88, 0xE1, 0x83, 0x3F } \ + } + +#define EFI_MTFTP4_PROTOCOL_GUID \ + { \ + 0x78247c57, 0x63db, 0x4708, {0x99, 0xc2, 0xa8, 0xb4, 0xa9, 0xa6, 0x1f, 0x6b } \ + } + +typedef struct _EFI_MTFTP4_PROTOCOL EFI_MTFTP4_PROTOCOL; +typedef struct _EFI_MTFTP4_TOKEN EFI_MTFTP4_TOKEN; + +// +// MTFTP4 packet opcode definition +// +#define EFI_MTFTP4_OPCODE_RRQ 1 +#define EFI_MTFTP4_OPCODE_WRQ 2 +#define EFI_MTFTP4_OPCODE_DATA 3 +#define EFI_MTFTP4_OPCODE_ACK 4 +#define EFI_MTFTP4_OPCODE_ERROR 5 +#define EFI_MTFTP4_OPCODE_OACK 6 +#define EFI_MTFTP4_OPCODE_DIR 7 +#define EFI_MTFTP4_OPCODE_DATA8 8 +#define EFI_MTFTP4_OPCODE_ACK8 9 + +// +// MTFTP4 error code definition +// +#define EFI_MTFTP4_ERRORCODE_NOT_DEFINED 0 +#define EFI_MTFTP4_ERRORCODE_FILE_NOT_FOUND 1 +#define EFI_MTFTP4_ERRORCODE_ACCESS_VIOLATION 2 +#define EFI_MTFTP4_ERRORCODE_DISK_FULL 3 +#define EFI_MTFTP4_ERRORCODE_ILLEGAL_OPERATION 4 +#define EFI_MTFTP4_ERRORCODE_UNKNOWN_TRANSFER_ID 5 +#define EFI_MTFTP4_ERRORCODE_FILE_ALREADY_EXISTS 6 +#define EFI_MTFTP4_ERRORCODE_NO_SUCH_USER 7 +#define EFI_MTFTP4_ERRORCODE_REQUEST_DENIED 8 + +// +// MTFTP4 pacekt definitions +// +#pragma pack(1) + +typedef struct { + UINT16 OpCode; + UINT8 Filename[1]; +} EFI_MTFTP4_REQ_HEADER; + +typedef struct { + UINT16 OpCode; + UINT8 Data[1]; +} EFI_MTFTP4_OACK_HEADER; + +typedef struct { + UINT16 OpCode; + UINT16 Block; + UINT8 Data[1]; +} EFI_MTFTP4_DATA_HEADER; + +typedef struct { + UINT16 OpCode; + UINT16 Block[1]; +} EFI_MTFTP4_ACK_HEADER; + +typedef struct { + UINT16 OpCode; + UINT64 Block; + UINT8 Data[1]; +} EFI_MTFTP4_DATA8_HEADER; + +typedef struct { + UINT16 OpCode; + UINT64 Block[1]; +} EFI_MTFTP4_ACK8_HEADER; + +typedef struct { + UINT16 OpCode; + UINT16 ErrorCode; + UINT8 ErrorMessage[1]; +} EFI_MTFTP4_ERROR_HEADER; + +typedef union { + /// + /// Type of packets as defined by the MTFTPv4 packet opcodes. + /// + UINT16 OpCode; + /// + /// Read request packet header. + /// + EFI_MTFTP4_REQ_HEADER Rrq; + /// + /// Write request packet header. + /// + EFI_MTFTP4_REQ_HEADER Wrq; + /// + /// Option acknowledge packet header. + /// + EFI_MTFTP4_OACK_HEADER Oack; + /// + /// Data packet header. + /// + EFI_MTFTP4_DATA_HEADER Data; + /// + /// Acknowledgement packet header. + /// + EFI_MTFTP4_ACK_HEADER Ack; + /// + /// Data packet header with big block number. + /// + EFI_MTFTP4_DATA8_HEADER Data8; + /// + /// Acknowledgement header with big block num. + /// + EFI_MTFTP4_ACK8_HEADER Ack8; + /// + /// Error packet header. + /// + EFI_MTFTP4_ERROR_HEADER Error; +} EFI_MTFTP4_PACKET; + +#pragma pack() + +/// +/// MTFTP4 option definition. +/// +typedef struct { + UINT8 *OptionStr; + UINT8 *ValueStr; +} EFI_MTFTP4_OPTION; + +typedef struct { + BOOLEAN UseDefaultSetting; + EFI_IPv4_ADDRESS StationIp; + EFI_IPv4_ADDRESS SubnetMask; + UINT16 LocalPort; + EFI_IPv4_ADDRESS GatewayIp; + EFI_IPv4_ADDRESS ServerIp; + UINT16 InitialServerPort; + UINT16 TryCount; + UINT16 TimeoutValue; +} EFI_MTFTP4_CONFIG_DATA; + +typedef struct { + EFI_MTFTP4_CONFIG_DATA ConfigData; + UINT8 SupportedOptionCount; + UINT8 **SupportedOptoins; + UINT8 UnsupportedOptionCount; + UINT8 **UnsupportedOptoins; +} EFI_MTFTP4_MODE_DATA; + +typedef struct { + EFI_IPv4_ADDRESS GatewayIp; + EFI_IPv4_ADDRESS ServerIp; + UINT16 ServerPort; + UINT16 TryCount; + UINT16 TimeoutValue; +} EFI_MTFTP4_OVERRIDE_DATA; + +// +// Protocol interfaces definition +// + +/** + A callback function that is provided by the caller to intercept + the EFI_MTFTP4_OPCODE_DATA or EFI_MTFTP4_OPCODE_DATA8 packets processed in the + EFI_MTFTP4_PROTOCOL.ReadFile() function, and alternatively to intercept + EFI_MTFTP4_OPCODE_OACK or EFI_MTFTP4_OPCODE_ERROR packets during a call to + EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory(). + + @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. + @param Token The token that the caller provided in the + EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile() + or ReadDirectory() function. + @param PacketLen Indicates the length of the packet. + @param Packet The pointer to an MTFTPv4 packet. + + @retval EFI_SUCCESS The operation was successful. + @retval Others Aborts the transfer process. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP4_CHECK_PACKET)( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_TOKEN *Token, + IN UINT16 PacketLen, + IN EFI_MTFTP4_PACKET *Paket + ); + +/** + Timeout callback function. + + @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. + @param Token The token that is provided in the + EFI_MTFTP4_PROTOCOL.ReadFile() or + EFI_MTFTP4_PROTOCOL.WriteFile() or + EFI_MTFTP4_PROTOCOL.ReadDirectory() functions + by the caller. + + @retval EFI_SUCCESS The operation was successful. + @retval Others Aborts download process. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP4_TIMEOUT_CALLBACK)( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_TOKEN *Token + ); + +/** + A callback function that the caller provides to feed data to the + EFI_MTFTP4_PROTOCOL.WriteFile() function. + + @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. + @param Token The token provided in the + EFI_MTFTP4_PROTOCOL.WriteFile() by the caller. + @param Length Indicates the length of the raw data wanted on input, and the + length the data available on output. + @param Buffer The pointer to the buffer where the data is stored. + + @retval EFI_SUCCESS The operation was successful. + @retval Others Aborts session. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP4_PACKET_NEEDED)( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_TOKEN *Token, + IN OUT UINT16 *Length, + OUT VOID **Buffer + ); + +/** + Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device. + + @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. + @param ModeData The pointer to storage for the EFI MTFTPv4 Protocol driver mode data. + + @retval EFI_SUCCESS The configuration data was successfully returned. + @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated. + @retval EFI_INVALID_PARAMETER This is NULL or ModeData is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP4_GET_MODE_DATA)( + IN EFI_MTFTP4_PROTOCOL *This, + OUT EFI_MTFTP4_MODE_DATA *ModeData + ); + +/** + Initializes, changes, or resets the default operational setting for this + EFI MTFTPv4 Protocol driver instance. + + @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. + @param MtftpConfigData The pointer to the configuration data structure. + + @retval EFI_SUCCESS The EFI MTFTPv4 Protocol driver was configured successfully. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_ACCESS_DENIED The EFI configuration could not be changed at this time because + there is one MTFTP background operation in progress. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, + RARP, etc.) has not finished yet. + @retval EFI_UNSUPPORTED A configuration protocol (DHCP, BOOTP, RARP, etc.) could not + be located when clients choose to use the default address + settings. + @retval EFI_OUT_OF_RESOURCES The EFI MTFTPv4 Protocol driver instance data could not be + allocated. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI + MTFTPv4 Protocol driver instance is not configured. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP4_CONFIGURE)( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_CONFIG_DATA *MtftpConfigData OPTIONAL + ); + +/** + Gets information about a file from an MTFTPv4 server. + + @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. + @param OverrideData Data that is used to override the existing parameters. If NULL, + the default parameters that were set in the + EFI_MTFTP4_PROTOCOL.Configure() function are used. + @param Filename The pointer to null-terminated ASCII file name string. + @param ModeStr The pointer to null-terminated ASCII mode string. If NULL, "octet" will be used. + @param OptionCount Number of option/value string pairs in OptionList. + @param OptionList The pointer to array of option/value string pairs. Ignored if + OptionCount is zero. + @param PacketLength The number of bytes in the returned packet. + @param Packet The pointer to the received packet. This buffer must be freed by + the caller. + + @retval EFI_SUCCESS An MTFTPv4 OACK packet was received and is in the Packet. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - Filename is NULL. + - OptionCount is not zero and OptionList is NULL. + - One or more options in OptionList have wrong format. + - PacketLength is NULL. + - One or more IPv4 addresses in OverrideData are not valid + unicast IPv4 addresses if OverrideData is not NULL. + @retval EFI_UNSUPPORTED One or more options in the OptionList are in the + unsupported list of structure EFI_MTFTP4_MODE_DATA. + @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, + RARP, etc.) has not finished yet. + @retval EFI_ACCESS_DENIED The previous operation has not completed yet. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_TFTP_ERROR An MTFTPv4 ERROR packet was received and is in the Packet. + @retval EFI_NETWORK_UNREACHABLE An ICMP network unreachable error packet was received and the Packet is set to NULL. + @retval EFI_HOST_UNREACHABLE An ICMP host unreachable error packet was received and the Packet is set to NULL. + @retval EFI_PROTOCOL_UNREACHABLE An ICMP protocol unreachable error packet was received and the Packet is set to NULL. + @retval EFI_PORT_UNREACHABLE An ICMP port unreachable error packet was received and the Packet is set to NULL. + @retval EFI_ICMP_ERROR Some other ICMP ERROR packet was received and is in the Buffer. + @retval EFI_PROTOCOL_ERROR An unexpected MTFTPv4 packet was received and is in the Packet. + @retval EFI_TIMEOUT No responses were received from the MTFTPv4 server. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. + @retval EFI_NO_MEDIA There was a media error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP4_GET_INFO)( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_OVERRIDE_DATA *OverrideData OPTIONAL, + IN UINT8 *Filename, + IN UINT8 *ModeStr OPTIONAL, + IN UINT8 OptionCount, + IN EFI_MTFTP4_OPTION *OptionList, + OUT UINT32 *PacketLength, + OUT EFI_MTFTP4_PACKET **Packet OPTIONAL + ); + +/** + Parses the options in an MTFTPv4 OACK packet. + + @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. + @param PacketLen Length of the OACK packet to be parsed. + @param Packet The pointer to the OACK packet to be parsed. + @param OptionCount The pointer to the number of options in following OptionList. + @param OptionList The pointer to EFI_MTFTP4_OPTION storage. Call the EFI Boot + Service FreePool() to release the OptionList if the options + in this OptionList are not needed any more. + + @retval EFI_SUCCESS The OACK packet was valid and the OptionCount and + OptionList parameters have been updated. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - PacketLen is 0. + - Packet is NULL or Packet is not a valid MTFTPv4 packet. + - OptionCount is NULL. + @retval EFI_NOT_FOUND No options were found in the OACK packet. + @retval EFI_OUT_OF_RESOURCES Storage for the OptionList array cannot be allocated. + @retval EFI_PROTOCOL_ERROR One or more of the option fields is invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP4_PARSE_OPTIONS)( + IN EFI_MTFTP4_PROTOCOL *This, + IN UINT32 PacketLen, + IN EFI_MTFTP4_PACKET *Packet, + OUT UINT32 *OptionCount, + OUT EFI_MTFTP4_OPTION **OptionList OPTIONAL + ); + +/** + Downloads a file from an MTFTPv4 server. + + @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. + @param Token The pointer to the token structure to provide the parameters that are + used in this operation. + + @retval EFI_SUCCESS The data file has been transferred successfully. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_BUFFER_TOO_SMALL BufferSize is not zero but not large enough to hold the + downloaded data in downloading process. + @retval EFI_ABORTED Current operation is aborted by user. + @retval EFI_NETWORK_UNREACHABLE An ICMP network unreachable error packet was received. + @retval EFI_HOST_UNREACHABLE An ICMP host unreachable error packet was received. + @retval EFI_PROTOCOL_UNREACHABLE An ICMP protocol unreachable error packet was received. + @retval EFI_PORT_UNREACHABLE An ICMP port unreachable error packet was received. + @retval EFI_ICMP_ERROR Some other ICMP ERROR packet was received. + @retval EFI_TIMEOUT No responses were received from the MTFTPv4 server. + @retval EFI_TFTP_ERROR An MTFTPv4 ERROR packet was received. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. + @retval EFI_NO_MEDIA There was a media error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP4_READ_FILE)( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_TOKEN *Token + ); + +/** + Sends a file to an MTFTPv4 server. + + @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. + @param Token The pointer to the token structure to provide the parameters that are + used in this operation. + + @retval EFI_SUCCESS The upload session has started. + @retval EFI_UNSUPPORTED The operation is not supported by this implementation. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are in + the unsupported list of structure EFI_MTFTP4_MODE_DATA. + @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, + RARP, etc.) is not finished yet. + @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv4 session. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_ACCESS_DENIED The previous operation has not completed yet. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP4_WRITE_FILE)( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_TOKEN *Token + ); + +/** + Downloads a data file "directory" from an MTFTPv4 server. May be unsupported in some EFI + implementations. + + @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. + @param Token The pointer to the token structure to provide the parameters that are + used in this operation. + + @retval EFI_SUCCESS The MTFTPv4 related file "directory" has been downloaded. + @retval EFI_UNSUPPORTED The operation is not supported by this implementation. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are in + the unsupported list of structure EFI_MTFTP4_MODE_DATA. + @retval EFI_NOT_STARTED The EFI MTFTPv4 Protocol driver has not been started. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, + RARP, etc.) is not finished yet. + @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv4 session. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_ACCESS_DENIED The previous operation has not completed yet. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP4_READ_DIRECTORY)( + IN EFI_MTFTP4_PROTOCOL *This, + IN EFI_MTFTP4_TOKEN *Token + ); + +/** + Polls for incoming data packets and processes outgoing data packets. + + @param This The pointer to the EFI_MTFTP4_PROTOCOL instance. + + @retval EFI_SUCCESS Incoming or outgoing data was processed. + @retval EFI_NOT_STARTED This EFI MTFTPv4 Protocol instance has not been started. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, + RARP, etc.) is not finished yet. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. + Consider increasing the polling rate. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP4_POLL)( + IN EFI_MTFTP4_PROTOCOL *This + ); + +/// +/// The EFI_MTFTP4_PROTOCOL is designed to be used by UEFI drivers and applications +/// to transmit and receive data files. The EFI MTFTPv4 Protocol driver uses +/// the underlying EFI UDPv4 Protocol driver and EFI IPv4 Protocol driver. +/// +struct _EFI_MTFTP4_PROTOCOL { + EFI_MTFTP4_GET_MODE_DATA GetModeData; + EFI_MTFTP4_CONFIGURE Configure; + EFI_MTFTP4_GET_INFO GetInfo; + EFI_MTFTP4_PARSE_OPTIONS ParseOptions; + EFI_MTFTP4_READ_FILE ReadFile; + EFI_MTFTP4_WRITE_FILE WriteFile; + EFI_MTFTP4_READ_DIRECTORY ReadDirectory; + EFI_MTFTP4_POLL Poll; +}; + +struct _EFI_MTFTP4_TOKEN { + /// + /// The status that is returned to the caller at the end of the operation + /// to indicate whether this operation completed successfully. + /// + EFI_STATUS Status; + /// + /// The event that will be signaled when the operation completes. If + /// set to NULL, the corresponding function will wait until the read or + /// write operation finishes. The type of Event must be + /// EVT_NOTIFY_SIGNAL. The Task Priority Level (TPL) of + /// Event must be lower than or equal to TPL_CALLBACK. + /// + EFI_EVENT Event; + /// + /// If not NULL, the data that will be used to override the existing configure data. + /// + EFI_MTFTP4_OVERRIDE_DATA *OverrideData; + /// + /// The pointer to the null-terminated ASCII file name string. + /// + UINT8 *Filename; + /// + /// The pointer to the null-terminated ASCII mode string. If NULL, "octet" is used. + /// + UINT8 *ModeStr; + /// + /// Number of option/value string pairs. + /// + UINT32 OptionCount; + /// + /// The pointer to an array of option/value string pairs. Ignored if OptionCount is zero. + /// + EFI_MTFTP4_OPTION *OptionList; + /// + /// The size of the data buffer. + /// + UINT64 BufferSize; + /// + /// The pointer to the data buffer. Data that is downloaded from the + /// MTFTPv4 server is stored here. Data that is uploaded to the + /// MTFTPv4 server is read from here. Ignored if BufferSize is zero. + /// + VOID *Buffer; + /// + /// The pointer to the context that will be used by CheckPacket, + /// TimeoutCallback and PacketNeeded. + /// + VOID *Context; + /// + /// The pointer to the callback function to check the contents of the received packet. + /// + EFI_MTFTP4_CHECK_PACKET CheckPacket; + /// + /// The pointer to the function to be called when a timeout occurs. + /// + EFI_MTFTP4_TIMEOUT_CALLBACK TimeoutCallback; + /// + /// The pointer to the function to provide the needed packet contents. + /// + EFI_MTFTP4_PACKET_NEEDED PacketNeeded; +}; + +extern EFI_GUID gEfiMtftp4ServiceBindingProtocolGuid; +extern EFI_GUID gEfiMtftp4ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Mtftp6.h b/sys/contrib/edk2/Include/Protocol/Mtftp6.h new file mode 100644 index 000000000000..47047b22c02c --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Mtftp6.h @@ -0,0 +1,818 @@ +/** @file + UEFI Multicast Trivial File Transfer Protocol v6 Definition, which is built upon + the EFI UDPv6 Protocol and provides basic services for client-side unicast and/or + multicast TFTP operations. + + Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR> + (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.2 + +**/ + +#ifndef __EFI_MTFTP6_PROTOCOL_H__ +#define __EFI_MTFTP6_PROTOCOL_H__ + +#define EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0xd9760ff3, 0x3cca, 0x4267, {0x80, 0xf9, 0x75, 0x27, 0xfa, 0xfa, 0x42, 0x23 } \ + } + +#define EFI_MTFTP6_PROTOCOL_GUID \ + { \ + 0xbf0a78ba, 0xec29, 0x49cf, {0xa1, 0xc9, 0x7a, 0xe5, 0x4e, 0xab, 0x6a, 0x51 } \ + } + +typedef struct _EFI_MTFTP6_PROTOCOL EFI_MTFTP6_PROTOCOL; +typedef struct _EFI_MTFTP6_TOKEN EFI_MTFTP6_TOKEN; + +/// +/// MTFTP Packet OpCodes +///@{ +#define EFI_MTFTP6_OPCODE_RRQ 1 ///< The MTFTPv6 packet is a read request. +#define EFI_MTFTP6_OPCODE_WRQ 2 ///< The MTFTPv6 packet is a write request. +#define EFI_MTFTP6_OPCODE_DATA 3 ///< The MTFTPv6 packet is a data packet. +#define EFI_MTFTP6_OPCODE_ACK 4 ///< The MTFTPv6 packet is an acknowledgement packet. +#define EFI_MTFTP6_OPCODE_ERROR 5 ///< The MTFTPv6 packet is an error packet. +#define EFI_MTFTP6_OPCODE_OACK 6 ///< The MTFTPv6 packet is an option acknowledgement packet. +#define EFI_MTFTP6_OPCODE_DIR 7 ///< The MTFTPv6 packet is a directory query packet. +#define EFI_MTFTP6_OPCODE_DATA8 8 ///< The MTFTPv6 packet is a data packet with a big block number. +#define EFI_MTFTP6_OPCODE_ACK8 9 ///< The MTFTPv6 packet is an acknowledgement packet with a big block number. +///@} + +/// +/// MTFTP ERROR Packet ErrorCodes +///@{ +/// +/// The error code is not defined. See the error message in the packet (if any) for details. +/// +#define EFI_MTFTP6_ERRORCODE_NOT_DEFINED 0 +/// +/// The file was not found. +/// +#define EFI_MTFTP6_ERRORCODE_FILE_NOT_FOUND 1 +/// +/// There was an access violation. +/// +#define EFI_MTFTP6_ERRORCODE_ACCESS_VIOLATION 2 +/// +/// The disk was full or its allocation was exceeded. +/// +#define EFI_MTFTP6_ERRORCODE_DISK_FULL 3 +/// +/// The MTFTPv6 operation was illegal. +/// +#define EFI_MTFTP6_ERRORCODE_ILLEGAL_OPERATION 4 +/// +/// The transfer ID is unknown. +/// +#define EFI_MTFTP6_ERRORCODE_UNKNOWN_TRANSFER_ID 5 +/// +/// The file already exists. +/// +#define EFI_MTFTP6_ERRORCODE_FILE_ALREADY_EXISTS 6 +/// +/// There is no such user. +/// +#define EFI_MTFTP6_ERRORCODE_NO_SUCH_USER 7 +/// +/// The request has been denied due to option negotiation. +/// +#define EFI_MTFTP6_ERRORCODE_REQUEST_DENIED 8 +///@} + +#pragma pack(1) + +/// +/// EFI_MTFTP6_REQ_HEADER +/// +typedef struct { + /// + /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_RRQ for a read request + /// or OpCode = EFI_MTFTP6_OPCODE_WRQ for a write request. + /// + UINT16 OpCode; + /// + /// The file name to be downloaded or uploaded. + /// + UINT8 Filename[1]; +} EFI_MTFTP6_REQ_HEADER; + +/// +/// EFI_MTFTP6_OACK_HEADER +/// +typedef struct { + /// + /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_OACK. + /// + UINT16 OpCode; + /// + /// The option strings in the option acknowledgement packet. + /// + UINT8 Data[1]; +} EFI_MTFTP6_OACK_HEADER; + +/// +/// EFI_MTFTP6_DATA_HEADER +/// +typedef struct { + /// + /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_DATA. + /// + UINT16 OpCode; + /// + /// Block number of this data packet. + /// + UINT16 Block; + /// + /// The content of this data packet. + /// + UINT8 Data[1]; +} EFI_MTFTP6_DATA_HEADER; + +/// +/// EFI_MTFTP6_ACK_HEADER +/// +typedef struct { + /// + /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_ACK. + /// + UINT16 OpCode; + /// + /// The block number of the data packet that is being acknowledged. + /// + UINT16 Block[1]; +} EFI_MTFTP6_ACK_HEADER; + +/// +/// EFI_MTFTP6_DATA8_HEADER +/// +typedef struct { + /// + /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_DATA8. + /// + UINT16 OpCode; + /// + /// The block number of data packet. + /// + UINT64 Block; + /// + /// The content of this data packet. + /// + UINT8 Data[1]; +} EFI_MTFTP6_DATA8_HEADER; + +/// +/// EFI_MTFTP6_ACK8_HEADER +/// +typedef struct { + /// + /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_ACK8. + /// + UINT16 OpCode; + /// + /// The block number of the data packet that is being acknowledged. + /// + UINT64 Block[1]; +} EFI_MTFTP6_ACK8_HEADER; + +/// +/// EFI_MTFTP6_ERROR_HEADER +/// +typedef struct { + /// + /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_ERROR. + /// + UINT16 OpCode; + /// + /// The error number as defined by the MTFTPv6 packet error codes. + /// + UINT16 ErrorCode; + /// + /// Error message string. + /// + UINT8 ErrorMessage[1]; +} EFI_MTFTP6_ERROR_HEADER; + +/// +/// EFI_MTFTP6_PACKET +/// +typedef union { + UINT16 OpCode; ///< Type of packets as defined by the MTFTPv6 packet opcodes. + EFI_MTFTP6_REQ_HEADER Rrq; ///< Read request packet header. + EFI_MTFTP6_REQ_HEADER Wrq; ///< write request packet header. + EFI_MTFTP6_OACK_HEADER Oack; ///< Option acknowledge packet header. + EFI_MTFTP6_DATA_HEADER Data; ///< Data packet header. + EFI_MTFTP6_ACK_HEADER Ack; ///< Acknowledgement packet header. + EFI_MTFTP6_DATA8_HEADER Data8; ///< Data packet header with big block number. + EFI_MTFTP6_ACK8_HEADER Ack8; ///< Acknowledgement header with big block number. + EFI_MTFTP6_ERROR_HEADER Error; ///< Error packet header. +} EFI_MTFTP6_PACKET; + +#pragma pack() + +/// +/// EFI_MTFTP6_CONFIG_DATA +/// +typedef struct { + /// + /// The local IP address to use. Set to zero to let the underlying IPv6 + /// driver choose a source address. If not zero it must be one of the + /// configured IP addresses in the underlying IPv6 driver. + /// + EFI_IPv6_ADDRESS StationIp; + /// + /// Local port number. Set to zero to use the automatically assigned port number. + /// + UINT16 LocalPort; + /// + /// The IP address of the MTFTPv6 server. + /// + EFI_IPv6_ADDRESS ServerIp; + /// + /// The initial MTFTPv6 server port number. Request packets are + /// sent to this port. This number is almost always 69 and using zero + /// defaults to 69. + UINT16 InitialServerPort; + /// + /// The number of times to transmit MTFTPv6 request packets and wait for a response. + /// + UINT16 TryCount; + /// + /// The number of seconds to wait for a response after sending the MTFTPv6 request packet. + /// + UINT16 TimeoutValue; +} EFI_MTFTP6_CONFIG_DATA; + +/// +/// EFI_MTFTP6_MODE_DATA +/// +typedef struct { + /// + /// The configuration data of this instance. + /// + EFI_MTFTP6_CONFIG_DATA ConfigData; + /// + /// The number of option strings in the following SupportedOptions array. + /// + UINT8 SupportedOptionCount; + /// + /// An array of null-terminated ASCII option strings that are recognized and supported by + /// this EFI MTFTPv6 Protocol driver implementation. The buffer is + /// read only to the caller and the caller should NOT free the buffer. + /// + UINT8 **SupportedOptions; +} EFI_MTFTP6_MODE_DATA; + +/// +/// EFI_MTFTP_OVERRIDE_DATA +/// +typedef struct { + /// + /// IP address of the MTFTPv6 server. If set to all zero, the value that + /// was set by the EFI_MTFTP6_PROTOCOL.Configure() function will be used. + /// + EFI_IPv6_ADDRESS ServerIp; + /// + /// MTFTPv6 server port number. If set to zero, it will use the value + /// that was set by the EFI_MTFTP6_PROTOCOL.Configure() function. + /// + UINT16 ServerPort; + /// + /// Number of times to transmit MTFTPv6 request packets and wait + /// for a response. If set to zero, the value that was set by + /// theEFI_MTFTP6_PROTOCOL.Configure() function will be used. + /// + UINT16 TryCount; + /// + /// Number of seconds to wait for a response after sending the + /// MTFTPv6 request packet. If set to zero, the value that was set by + /// the EFI_MTFTP6_PROTOCOL.Configure() function will be used. + /// + UINT16 TimeoutValue; +} EFI_MTFTP6_OVERRIDE_DATA; + +/// +/// EFI_MTFTP6_OPTION +/// +typedef struct { + UINT8 *OptionStr; ///< Pointer to the null-terminated ASCII MTFTPv6 option string. + UINT8 *ValueStr; ///< Pointer to the null-terminated ASCII MTFTPv6 value string. +} EFI_MTFTP6_OPTION; + +/** + EFI_MTFTP6_TIMEOUT_CALLBACK is a callback function that the caller provides to capture the + timeout event in the EFI_MTFTP6_PROTOCOL.ReadFile(), EFI_MTFTP6_PROTOCOL.WriteFile() or + EFI_MTFTP6_PROTOCOL.ReadDirectory() functions. + + Whenever a timeout occurs, the EFI MTFTPv6 Protocol driver will call the EFI_MTFTP6_TIMEOUT_CALLBACK + function to notify the caller of the timeout event. Any status code other than EFI_SUCCESS + that is returned from this function will abort the current download process. + + @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. + @param[in] Token The token that the caller provided in the EFI_MTFTP6_PROTOCOl.ReadFile(), + WriteFile() or ReadDirectory() function. + @param[in] PacketLen Indicates the length of the packet. + @param[in] Packet Pointer to an MTFTPv6 packet. + + @retval EFI_SUCCESS Operation success. + @retval Others Aborts session. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP6_CHECK_PACKET)( + IN EFI_MTFTP6_PROTOCOL *This, + IN EFI_MTFTP6_TOKEN *Token, + IN UINT16 PacketLen, + IN EFI_MTFTP6_PACKET *Packet + ); + +/** + EFI_MTFTP6_TIMEOUT_CALLBACK is a callback function that the caller provides to capture the + timeout event in the EFI_MTFTP6_PROTOCOL.ReadFile(), EFI_MTFTP6_PROTOCOL.WriteFile() or + EFI_MTFTP6_PROTOCOL.ReadDirectory() functions. + + Whenever a timeout occurs, the EFI MTFTPv6 Protocol driver will call the EFI_MTFTP6_TIMEOUT_CALLBACK + function to notify the caller of the timeout event. Any status code other than EFI_SUCCESS + that is returned from this function will abort the current download process. + + @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. + @param[in] Token The token that is provided in the EFI_MTFTP6_PROTOCOL.ReadFile() or + EFI_MTFTP6_PROTOCOL.WriteFile() or EFI_MTFTP6_PROTOCOL.ReadDirectory() + functions by the caller. + + @retval EFI_SUCCESS Operation success. + @retval Others Aborts session. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP6_TIMEOUT_CALLBACK)( + IN EFI_MTFTP6_PROTOCOL *This, + IN EFI_MTFTP6_TOKEN *Token + ); + +/** + EFI_MTFTP6_PACKET_NEEDED is a callback function that the caller provides to feed data to the + EFI_MTFTP6_PROTOCOL.WriteFile() function. + + EFI_MTFTP6_PACKET_NEEDED provides another mechanism for the caller to provide data to upload + other than a static buffer. The EFI MTFTP6 Protocol driver always calls EFI_MTFTP6_PACKET_NEEDED + to get packet data from the caller if no static buffer was given in the initial call to + EFI_MTFTP6_PROTOCOL.WriteFile() function. Setting *Length to zero signals the end of the session. + Returning a status code other than EFI_SUCCESS aborts the session. + + @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. + @param[in] Token The token provided in the EFI_MTFTP6_PROTOCOL.WriteFile() by the caller. + @param[in, out] Length Indicates the length of the raw data wanted on input, and the + length the data available on output. + @param[out] Buffer Pointer to the buffer where the data is stored. + + @retval EFI_SUCCESS Operation success. + @retval Others Aborts session. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP6_PACKET_NEEDED)( + IN EFI_MTFTP6_PROTOCOL *This, + IN EFI_MTFTP6_TOKEN *Token, + IN OUT UINT16 *Length, + OUT VOID **Buffer + ); + +struct _EFI_MTFTP6_TOKEN { + /// + /// The status that is returned to the caller at the end of the operation + /// to indicate whether this operation completed successfully. + /// Defined Status values are listed below. + /// + EFI_STATUS Status; + /// + /// The event that will be signaled when the operation completes. If + /// set to NULL, the corresponding function will wait until the read or + /// write operation finishes. The type of Event must be EVT_NOTIFY_SIGNAL. + /// + EFI_EVENT Event; + /// + /// If not NULL, the data that will be used to override the existing + /// configure data. + /// + EFI_MTFTP6_OVERRIDE_DATA *OverrideData; + /// + /// Pointer to the null-terminated ASCII file name string. + /// + UINT8 *Filename; + /// + /// Pointer to the null-terminated ASCII mode string. If NULL, octet is used. + /// + UINT8 *ModeStr; + /// + /// Number of option/value string pairs. + /// + UINT32 OptionCount; + /// + /// Pointer to an array of option/value string pairs. Ignored if + /// OptionCount is zero. Both a remote server and this driver + /// implementation should support these options. If one or more + /// options are unrecognized by this implementation, it is sent to the + /// remote server without being changed. + /// + EFI_MTFTP6_OPTION *OptionList; + /// + /// On input, the size, in bytes, of Buffer. On output, the number + /// of bytes transferred. + /// + UINT64 BufferSize; + /// + /// Pointer to the data buffer. Data that is downloaded from the + /// MTFTPv6 server is stored here. Data that is uploaded to the + /// MTFTPv6 server is read from here. Ignored if BufferSize is zero. + /// + VOID *Buffer; + /// + /// Pointer to the context that will be used by CheckPacket, + /// TimeoutCallback and PacketNeeded. + /// + VOID *Context; + /// + /// Pointer to the callback function to check the contents of the + /// received packet. + /// + EFI_MTFTP6_CHECK_PACKET CheckPacket; + /// + /// Pointer to the function to be called when a timeout occurs. + /// + EFI_MTFTP6_TIMEOUT_CALLBACK TimeoutCallback; + /// + /// Pointer to the function to provide the needed packet contents. + /// Only used in WriteFile() operation. + /// + EFI_MTFTP6_PACKET_NEEDED PacketNeeded; +}; + +/** + Read the current operational settings. + + The GetModeData() function reads the current operational settings of this EFI MTFTPv6 + Protocol driver instance. + + @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. + @param[out] ModeData The buffer in which the EFI MTFTPv6 Protocol driver mode + data is returned. + + @retval EFI_SUCCESS The configuration data was successfully returned. + @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated. + @retval EFI_INVALID_PARAMETER This is NULL or ModeData is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP6_GET_MODE_DATA)( + IN EFI_MTFTP6_PROTOCOL *This, + OUT EFI_MTFTP6_MODE_DATA *ModeData + ); + +/** + Initializes, changes, or resets the default operational setting for this EFI MTFTPv6 + Protocol driver instance. + + The Configure() function is used to set and change the configuration data for this EFI + MTFTPv6 Protocol driver instance. The configuration data can be reset to startup defaults by calling + Configure() with MtftpConfigData set to NULL. Whenever the instance is reset, any + pending operation is aborted. By changing the EFI MTFTPv6 Protocol driver instance configuration + data, the client can connect to different MTFTPv6 servers. The configuration parameters in + MtftpConfigData are used as the default parameters in later MTFTPv6 operations and can be + overridden in later operations. + + @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. + @param[in] MtftpConfigData Pointer to the configuration data structure. + + @retval EFI_SUCCESS The EFI MTFTPv6 Protocol instance was configured successfully. + @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE: + - This is NULL. + - MtftpConfigData.StationIp is neither zero nor one + of the configured IP addresses in the underlying IPv6 driver. + - MtftpCofigData.ServerIp is not a valid IPv6 unicast address. + @retval EFI_ACCESS_DENIED - The configuration could not be changed at this time because there + is some MTFTP background operation in progress. + - MtftpCofigData.LocalPort is already in use. + @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source + address for this instance, but no source address was available for use. + @retval EFI_OUT_OF_RESOURCES The EFI MTFTPv6 Protocol driver instance data could not be + allocated. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI + MTFTPv6 Protocol driver instance is not configured. + + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP6_CONFIGURE)( + IN EFI_MTFTP6_PROTOCOL *This, + IN EFI_MTFTP6_CONFIG_DATA *MtftpConfigData OPTIONAL + ); + +/** + Get information about a file from an MTFTPv6 server. + + The GetInfo() function assembles an MTFTPv6 request packet with options, sends it to the + MTFTPv6 server, and may return an MTFTPv6 OACK, MTFTPv6 ERROR, or ICMP ERROR packet. + Retries occur only if no response packets are received from the MTFTPv6 server before the + timeout expires. + + @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. + @param[in] OverrideData Data that is used to override the existing parameters. If NULL, the + default parameters that were set in the EFI_MTFTP6_PROTOCOL.Configure() + function are used. + @param[in] Filename Pointer to null-terminated ASCII file name string. + @param[in] ModeStr Pointer to null-terminated ASCII mode string. If NULL, octet will be used + @param[in] OptionCount Number of option/value string pairs in OptionList. + @param[in] OptionList Pointer to array of option/value string pairs. Ignored if + OptionCount is zero. + @param[out] PacketLength The number of bytes in the returned packet. + @param[out] Packet The pointer to the received packet. This buffer must be freed by + the caller. + + @retval EFI_SUCCESS An MTFTPv6 OACK packet was received and is in the Packet. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - Filename is NULL + - OptionCount is not zero and OptionList is NULL. + - One or more options in OptionList have wrong format. + - PacketLength is NULL. + - OverrideData.ServerIp is not valid unicast IPv6 addresses. + @retval EFI_UNSUPPORTED One or more options in the OptionList are unsupported by + this implementation. + @retval EFI_NOT_STARTED The EFI MTFTPv6 Protocol driver has not been started. + @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source + address for this instance, but no source address was available for use. + @retval EFI_ACCESS_DENIED The previous operation has not completed yet. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_TFTP_ERROR An MTFTPv6 ERROR packet was received and is in the Packet. + @retval EFI_NETWORK_UNREACHABLE An ICMP network unreachable error packet was received and the Packet is set to NULL. + @retval EFI_HOST_UNREACHABLE An ICMP host unreachable error packet was received and the Packet is set to NULL. + @retval EFI_PROTOCOL_UNREACHABLE An ICMP protocol unreachable error packet was received and the Packet is set to NULL. + @retval EFI_PORT_UNREACHABLE An ICMP port unreachable error packet was received and the Packet is set to NULL. + @retval EFI_ICMP_ERROR Some other ICMP ERROR packet was received and the Packet is set to NULL. + @retval EFI_PROTOCOL_ERROR An unexpected MTFTPv6 packet was received and is in the Packet. + @retval EFI_TIMEOUT No responses were received from the MTFTPv6 server. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. + @retval EFI_NO_MEDIA There was a media error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP6_GET_INFO)( + IN EFI_MTFTP6_PROTOCOL *This, + IN EFI_MTFTP6_OVERRIDE_DATA *OverrideData OPTIONAL, + IN UINT8 *Filename, + IN UINT8 *ModeStr OPTIONAL, + IN UINT8 OptionCount, + IN EFI_MTFTP6_OPTION *OptionList OPTIONAL, + OUT UINT32 *PacketLength, + OUT EFI_MTFTP6_PACKET **Packet OPTIONAL + ); + +/** + Parse the options in an MTFTPv6 OACK packet. + + The ParseOptions() function parses the option fields in an MTFTPv6 OACK packet and + returns the number of options that were found and optionally a list of pointers to + the options in the packet. + If one or more of the option fields are not valid, then EFI_PROTOCOL_ERROR is returned + and *OptionCount and *OptionList stop at the last valid option. + + @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. + @param[in] PacketLen Length of the OACK packet to be parsed. + @param[in] Packet Pointer to the OACK packet to be parsed. + @param[out] OptionCount Pointer to the number of options in the following OptionList. + @param[out] OptionList Pointer to EFI_MTFTP6_OPTION storage. Each pointer in the + OptionList points to the corresponding MTFTP option buffer + in the Packet. Call the EFI Boot Service FreePool() to + release the OptionList if the options in this OptionList + are not needed any more. + + @retval EFI_SUCCESS The OACK packet was valid and the OptionCount and + OptionList parameters have been updated. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - PacketLen is 0. + - Packet is NULL or Packet is not a valid MTFTPv6 packet. + - OptionCount is NULL. + @retval EFI_NOT_FOUND No options were found in the OACK packet. + @retval EFI_OUT_OF_RESOURCES Storage for the OptionList array can not be allocated. + @retval EFI_PROTOCOL_ERROR One or more of the option fields is invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP6_PARSE_OPTIONS)( + IN EFI_MTFTP6_PROTOCOL *This, + IN UINT32 PacketLen, + IN EFI_MTFTP6_PACKET *Packet, + OUT UINT32 *OptionCount, + OUT EFI_MTFTP6_OPTION **OptionList OPTIONAL + ); + +/** + Download a file from an MTFTPv6 server. + + The ReadFile() function is used to initialize and start an MTFTPv6 download process and + optionally wait for completion. When the download operation completes, whether successfully or + not, the Token.Status field is updated by the EFI MTFTPv6 Protocol driver and then + Token.Event is signaled if it is not NULL. + + Data can be downloaded from the MTFTPv6 server into either of the following locations: + - A fixed buffer that is pointed to by Token.Buffer + - A download service function that is pointed to by Token.CheckPacket + + If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket + will be called first. If the call is successful, the packet will be stored in Token.Buffer. + + @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. + @param[in] Token Pointer to the token structure to provide the parameters that are + used in this operation. + + @retval EFI_SUCCESS The data file has been transferred successfully. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_BUFFER_TOO_SMALL BufferSize is not zero but not large enough to hold the + downloaded data in downloading process. + @retval EFI_ABORTED Current operation is aborted by user. + @retval EFI_NETWORK_UNREACHABLE An ICMP network unreachable error packet was received. + @retval EFI_HOST_UNREACHABLE An ICMP host unreachable error packet was received. + @retval EFI_PROTOCOL_UNREACHABLE An ICMP protocol unreachable error packet was received. + @retval EFI_PORT_UNREACHABLE An ICMP port unreachable error packet was received. + @retval EFI_ICMP_ERROR An ICMP ERROR packet was received. + @retval EFI_TIMEOUT No responses were received from the MTFTPv6 server. + @retval EFI_TFTP_ERROR An MTFTPv6 ERROR packet was received. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. + @retval EFI_NO_MEDIA There was a media error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP6_READ_FILE)( + IN EFI_MTFTP6_PROTOCOL *This, + IN EFI_MTFTP6_TOKEN *Token + ); + +/** + Send a file to an MTFTPv6 server. May be unsupported in some implementations. + + The WriteFile() function is used to initialize an uploading operation with the given option list + and optionally wait for completion. If one or more of the options is not supported by the server, the + unsupported options are ignored and a standard TFTP process starts instead. When the upload + process completes, whether successfully or not, Token.Event is signaled, and the EFI MTFTPv6 + Protocol driver updates Token.Status. + + The caller can supply the data to be uploaded in the following two modes: + - Through the user-provided buffer + - Through a callback function + + With the user-provided buffer, the Token.BufferSize field indicates the length of the buffer, + and the driver will upload the data in the buffer. With an EFI_MTFTP6_PACKET_NEEDED + callback function, the driver will call this callback function to get more data from the user to upload. + See the definition of EFI_MTFTP6_PACKET_NEEDED for more information. These two modes + cannot be used at the same time. The callback function will be ignored if the user provides the + buffer. + + @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. + @param[in] Token Pointer to the token structure to provide the parameters that are + used in this operation. + + @retval EFI_SUCCESS The upload session has started. + @retval EFI_UNSUPPORTED The operation is not supported by this implementation. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - Token is NULL. + - Token.Filename is NULL. + - Token.OptionCount is not zero and Token.OptionList is NULL. + - One or more options in Token.OptionList have wrong format. + - Token.Buffer and Token.PacketNeeded are both NULL. + - Token.OverrideData.ServerIp is not valid unicast IPv6 addresses. + @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are not + supported by this implementation. + @retval EFI_NOT_STARTED The EFI MTFTPv6 Protocol driver has not been started. + @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source + address for this instance, but no source address was available for use. + @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv6 session. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_ACCESS_DENIED The previous operation has not completed yet. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP6_WRITE_FILE)( + IN EFI_MTFTP6_PROTOCOL *This, + IN EFI_MTFTP6_TOKEN *Token + ); + +/** + Download a data file directory from an MTFTPv6 server. May be unsupported in some implementations. + + The ReadDirectory() function is used to return a list of files on the MTFTPv6 server that are + logically (or operationally) related to Token.Filename. The directory request packet that is sent + to the server is built with the option list that was provided by caller, if present. + + The file information that the server returns is put into either of the following locations: + - A fixed buffer that is pointed to by Token.Buffer + - A download service function that is pointed to by Token.CheckPacket + + If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket + will be called first. If the call is successful, the packet will be stored in Token.Buffer. + + The returned directory listing in the Token.Buffer or EFI_MTFTP6_PACKET consists of a list + of two or three variable-length ASCII strings, each terminated by a null character, for each file in the + directory. If the multicast option is involved, the first field of each directory entry is the static + multicast IP address and UDP port number that is associated with the file name. The format of the + field is ip:ip:ip:ip:port. If the multicast option is not involved, this field and its terminating + null character are not present. + + The next field of each directory entry is the file name and the last field is the file information string. + The information string contains the file size and the create/modify timestamp. The format of the + information string is filesize yyyy-mm-dd hh:mm:ss:ffff. The timestamp is + Coordinated Universal Time (UTC; also known as Greenwich Mean Time [GMT]). + + @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. + @param[in] Token Pointer to the token structure to provide the parameters that are + used in this operation. + + @retval EFI_SUCCESS The MTFTPv6 related file "directory" has been downloaded. + @retval EFI_UNSUPPORTED The EFI MTFTPv6 Protocol driver does not support this function. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - Token is NULL. + - Token.Filename is NULL. + - Token.OptionCount is not zero and Token.OptionList is NULL. + - One or more options in Token.OptionList have wrong format. + - Token.Buffer and Token.CheckPacket are both NULL. + - Token.OverrideData.ServerIp is not valid unicast IPv6 addresses. + @retval EFI_UNSUPPORTED One or more options in the Token.OptionList are not + supported by this implementation. + @retval EFI_NOT_STARTED The EFI MTFTPv6 Protocol driver has not been started. + @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source + address for this instance, but no source address was available for use. + @retval EFI_ALREADY_STARTED This Token is already being used in another MTFTPv6 session. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + @retval EFI_ACCESS_DENIED The previous operation has not completed yet. + @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP6_READ_DIRECTORY)( + IN EFI_MTFTP6_PROTOCOL *This, + IN EFI_MTFTP6_TOKEN *Token + ); + +/** + Polls for incoming data packets and processes outgoing data packets. + + The Poll() function can be used by network drivers and applications to increase the rate that data + packets are moved between the communications device and the transmit and receive queues. + In some systems, the periodic timer event in the managed network driver may not poll the + underlying communications device fast enough to transmit and/or receive all data packets without + missing incoming packets or dropping outgoing packets. Drivers and applications that are + experiencing packet loss should try calling the Poll() function more often. + + @param[in] This Pointer to the EFI_MTFTP6_PROTOCOL instance. + + @retval EFI_SUCCESS Incoming or outgoing data was processed. + @retval EFI_NOT_STARTED This EFI MTFTPv6 Protocol instance has not been started. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. + Consider increasing the polling rate. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_MTFTP6_POLL)( + IN EFI_MTFTP6_PROTOCOL *This + ); + +/// +/// The EFI_MTFTP6_PROTOCOL is designed to be used by UEFI drivers and applications to transmit +/// and receive data files. The EFI MTFTPv6 Protocol driver uses the underlying EFI UDPv6 Protocol +/// driver and EFI IPv6 Protocol driver. +/// +struct _EFI_MTFTP6_PROTOCOL { + EFI_MTFTP6_GET_MODE_DATA GetModeData; + EFI_MTFTP6_CONFIGURE Configure; + EFI_MTFTP6_GET_INFO GetInfo; + EFI_MTFTP6_PARSE_OPTIONS ParseOptions; + EFI_MTFTP6_READ_FILE ReadFile; + EFI_MTFTP6_WRITE_FILE WriteFile; + EFI_MTFTP6_READ_DIRECTORY ReadDirectory; + EFI_MTFTP6_POLL Poll; +}; + +extern EFI_GUID gEfiMtftp6ServiceBindingProtocolGuid; +extern EFI_GUID gEfiMtftp6ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/NetworkInterfaceIdentifier.h b/sys/contrib/edk2/Include/Protocol/NetworkInterfaceIdentifier.h new file mode 100644 index 000000000000..bb9da21c07d8 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/NetworkInterfaceIdentifier.h @@ -0,0 +1,110 @@ +/** @file + EFI Network Interface Identifier Protocol. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in EFI Specification 1.10. + +**/ + +#ifndef __EFI_NETWORK_INTERFACE_IDENTIFER_H__ +#define __EFI_NETWORK_INTERFACE_IDENTIFER_H__ + +// +// GUID retired from UEFI Specification 2.1b +// +#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID \ + { \ + 0xE18541CD, 0xF755, 0x4f73, {0x92, 0x8D, 0x64, 0x3C, 0x8A, 0x79, 0xB2, 0x29 } \ + } + +// +// GUID intruduced in UEFI Specification 2.1b +// +#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID_31 \ + { \ + 0x1ACED566, 0x76ED, 0x4218, {0xBC, 0x81, 0x76, 0x7F, 0x1F, 0x97, 0x7A, 0x89 } \ + } + +// +// Revision defined in UEFI Specification 2.4 +// +#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION 0x00020000 + +/// +/// Revision defined in EFI1.1. +/// +#define EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE_REVISION EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION + +/// +/// Forward reference for pure ANSI compatability. +/// +typedef struct _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL; + +/// +/// Protocol defined in EFI1.1. +/// +typedef EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE; + +/// +/// An optional protocol that is used to describe details about the software +/// layer that is used to produce the Simple Network Protocol. +/// +struct _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL { + UINT64 Revision; ///< The revision of the EFI_NETWORK_INTERFACE_IDENTIFIER protocol. + UINT64 Id; ///< The address of the first byte of the identifying structure for this network + ///< interface. This is only valid when the network interface is started + ///< (see Start()). When the network interface is not started, this field is set to zero. + UINT64 ImageAddr; ///< The address of the first byte of the identifying structure for this + ///< network interface. This is set to zero if there is no structure. + UINT32 ImageSize; ///< The size of unrelocated network interface image. + CHAR8 StringId[4]; ///< A four-character ASCII string that is sent in the class identifier field of + ///< option 60 in DHCP. For a Type of EfiNetworkInterfaceUndi, this field is UNDI. + UINT8 Type; ///< Network interface type. This will be set to one of the values + ///< in EFI_NETWORK_INTERFACE_TYPE. + UINT8 MajorVer; ///< Major version number. + UINT8 MinorVer; ///< Minor version number. + BOOLEAN Ipv6Supported; ///< TRUE if the network interface supports IPv6; otherwise FALSE. + UINT16 IfNum; ///< The network interface number that is being identified by this Network + ///< Interface Identifier Protocol. This field must be less than or + ///< equal to the (IFcnt | IFcntExt <<8 ) fields in the !PXE structure. +}; + +/// +/// ******************************************************* +/// EFI_NETWORK_INTERFACE_TYPE +/// ******************************************************* +/// +typedef enum { + EfiNetworkInterfaceUndi = 1 +} EFI_NETWORK_INTERFACE_TYPE; + +/// +/// Forward reference for pure ANSI compatability. +/// +typedef struct undiconfig_table UNDI_CONFIG_TABLE; + +/// +/// The format of the configuration table for UNDI +/// +struct undiconfig_table { + UINT32 NumberOfInterfaces; ///< The number of NIC devices + ///< that this UNDI controls. + UINT32 reserved; + UNDI_CONFIG_TABLE *nextlink; ///< A pointer to the next UNDI + ///< configuration table. + /// + /// The length of this array is given in the NumberOfInterfaces field. + /// + struct { + VOID *NII_InterfacePointer; ///< Pointer to the NII interface structure. + VOID *DevicePathPointer; ///< Pointer to the device path for this NIC. + } NII_entry[1]; +}; + +extern EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid; +extern EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid_31; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Pcd.h b/sys/contrib/edk2/Include/Protocol/Pcd.h new file mode 100644 index 000000000000..03113cfddd3c --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Pcd.h @@ -0,0 +1,798 @@ +/** @file + Native Platform Configuration Database (PCD) Protocol + + Different with the EFI_PCD_PROTOCOL defined in PI 1.2 specification, the native + PCD protocol provide interfaces for dynamic and dynamic-ex type PCD. + The interfaces in dynamic type PCD do not require the token space guid as parameter, + but interfaces in dynamic-ex type PCD require token space guid as parameter. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol was introduced in PI Specification 1.2. + +**/ + +#ifndef __PCD_H__ +#define __PCD_H__ + +extern EFI_GUID gPcdProtocolGuid; + +#define PCD_PROTOCOL_GUID \ + { 0x11b34006, 0xd85b, 0x4d0a, { 0xa2, 0x90, 0xd5, 0xa5, 0x71, 0x31, 0xe, 0xf7 } } + +#define PCD_INVALID_TOKEN_NUMBER ((UINTN) 0) + +/** + Sets the SKU value for subsequent calls to set or get PCD token values. + + SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values. + SetSku() is normally called only once by the system. + + For each item (token), the database can hold a single value that applies to all SKUs, + or multiple values, where each value is associated with a specific SKU Id. Items with multiple, + SKU-specific values are called SKU enabled. + + The SKU Id of zero is reserved as a default. The valid SkuId range is 1 to 255. + For tokens that are not SKU enabled, the system ignores any set SKU Id and works with the + single value for that token. For SKU-enabled tokens, the system will use the SKU Id set by the + last call to SetSku(). If no SKU Id is set or the currently set SKU Id isn't valid for the specified token, + the system uses the default SKU Id. If the system attempts to use the default SKU Id and no value has been + set for that Id, the results are unpredictable. + + @param[in] SkuId The SKU value that will be used when the PCD service will retrieve and + set values associated with a PCD token. + + +**/ +typedef +VOID +(EFIAPI *PCD_PROTOCOL_SET_SKU)( + IN UINTN SkuId + ); + +/** + Retrieves an 8-bit value for a given PCD token. + + Retrieves the current byte-sized value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT8 value. + +**/ +typedef +UINT8 +(EFIAPI *PCD_PROTOCOL_GET8)( + IN UINTN TokenNumber + ); + +/** + Retrieves a 16-bit value for a given PCD token. + + Retrieves the current 16-bit value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT16 value. + +**/ +typedef +UINT16 +(EFIAPI *PCD_PROTOCOL_GET16)( + IN UINTN TokenNumber + ); + +/** + Retrieves a 32-bit value for a given PCD token. + + Retrieves the current 32-bit value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT32 value. + +**/ +typedef +UINT32 +(EFIAPI *PCD_PROTOCOL_GET32)( + IN UINTN TokenNumber + ); + +/** + Retrieves a 64-bit value for a given PCD token. + + Retrieves the current 64-bit value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT64 value. + +**/ +typedef +UINT64 +(EFIAPI *PCD_PROTOCOL_GET64)( + IN UINTN TokenNumber + ); + +/** + Retrieves a pointer to a value for a given PCD token. + + Retrieves the current pointer to the buffer for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The pointer to the buffer to be retrived. + +**/ +typedef +VOID * +(EFIAPI *PCD_PROTOCOL_GET_POINTER)( + IN UINTN TokenNumber + ); + +/** + Retrieves a Boolean value for a given PCD token. + + Retrieves the current boolean value for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The Boolean value. + +**/ +typedef +BOOLEAN +(EFIAPI *PCD_PROTOCOL_GET_BOOLEAN)( + IN UINTN TokenNumber + ); + +/** + Retrieves the size of the value for a given PCD token. + + Retrieves the current size of a particular PCD token. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The size of the value for the PCD token. + +**/ +typedef +UINTN +(EFIAPI *PCD_PROTOCOL_GET_SIZE)( + IN UINTN TokenNumber + ); + +/** + Retrieves an 8-bit value for a given PCD token. + + Retrieves the 8-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size 8-bit value for the PCD token. + +**/ +typedef +UINT8 +(EFIAPI *PCD_PROTOCOL_GET_EX_8)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves a 16-bit value for a given PCD token. + + Retrieves the 16-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size 16-bit value for the PCD token. + +**/ +typedef +UINT16 +(EFIAPI *PCD_PROTOCOL_GET_EX_16)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves a 32-bit value for a given PCD token. + + Retrieves the 32-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size 32-bit value for the PCD token. + +**/ +typedef +UINT32 +(EFIAPI *PCD_PROTOCOL_GET_EX_32)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves an 64-bit value for a given PCD token. + + Retrieves the 64-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size 64-bit value for the PCD token. + +**/ +typedef +UINT64 +(EFIAPI *PCD_PROTOCOL_GET_EX_64)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves a pointer to a value for a given PCD token. + + Retrieves the current pointer to the buffer for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The pointer to the buffer to be retrieved. + +**/ +typedef +VOID * +(EFIAPI *PCD_PROTOCOL_GET_EX_POINTER)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves a Boolean value for a given PCD token. + + Retrieves the Boolean value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size Boolean value for the PCD token. + +**/ +typedef +BOOLEAN +(EFIAPI *PCD_PROTOCOL_GET_EX_BOOLEAN)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves the size of the value for a given PCD token. + + Retrieves the current size of a particular PCD token. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size of the value for the PCD token. + +**/ +typedef +UINTN +(EFIAPI *PCD_PROTOCOL_GET_EX_SIZE)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Sets an 8-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET8)( + IN UINTN TokenNumber, + IN UINT8 Value + ); + +/** + Sets a 16-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET16)( + IN UINTN TokenNumber, + IN UINT16 Value + ); + +/** + Sets a 32-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET32)( + IN UINTN TokenNumber, + IN UINT32 Value + ); + +/** + Sets a 64-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET64)( + IN UINTN TokenNumber, + IN UINT64 Value + ); + +/** + Sets a value of a specified size for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token. + On input, if the SizeOfValue is greater than the maximum size supported + for this TokenNumber then the output value of SizeOfValue will reflect + the maximum size supported for this TokenNumber. + @param[in] Buffer The buffer to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET_POINTER)( + IN UINTN TokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ); + +/** + Sets a Boolean value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET_BOOLEAN)( + IN UINTN TokenNumber, + IN BOOLEAN Value + ); + +/** + Sets an 8-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET_EX_8)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT8 Value + ); + +/** + Sets an 16-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET_EX_16)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT16 Value + ); + +/** + Sets a 32-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET_EX_32)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT32 Value + ); + +/** + Sets a 64-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET_EX_64)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT64 Value + ); + +/** + Sets a value of a specified size for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token. + On input, if the SizeOfValue is greater than the maximum size supported + for this TokenNumber then the output value of SizeOfValue will reflect + the maximum size supported for this TokenNumber. + @param[in] Buffer The buffer to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET_EX_POINTER)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ); + +/** + Sets a Boolean value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_SET_EX_BOOLEAN)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN BOOLEAN Value + ); + +/** + Callback on SET function prototype definition. + + This notification function serves two purposes. + Firstly, it notifies the module which did the registration that the value + of this PCD token has been set. Secondly, it provides a mechanism for the + module that did the registration to intercept the set operation and override + the value that has been set, if necessary. After the invocation of the callback function, + TokenData will be used by PCD service DXE driver to modify the internal data in + PCD database. + + @param[in] CallBackGuid The PCD token GUID being set. + @param[in] CallBackToken The PCD token number being set. + @param[in, out] TokenData A pointer to the token data being set. + @param[in] TokenDataSize The size, in bytes, of the data being set. + + @retval VOID + +**/ +typedef +VOID +(EFIAPI *PCD_PROTOCOL_CALLBACK)( + IN CONST EFI_GUID *CallBackGuid OPTIONAL, + IN UINTN CallBackToken, + IN OUT VOID *TokenData, + IN UINTN TokenDataSize + ); + +/** + Specifies a function to be called anytime the value of a designated token is changed. + + @param[in] TokenNumber The PCD token number. + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call event + for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_CALLBACK_ONSET)( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN TokenNumber, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ); + +/** + Cancels a previously set callback function for a particular PCD token number. + + @param[in] TokenNumber The PCD token number. + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call event + for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_CANCEL_CALLBACK)( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN TokenNumber, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ); + +/** + Retrieves the next valid token number in a given namespace. + + This is useful since the PCD infrastructure contains a sparse list of token numbers, + and one cannot a priori know what token numbers are valid in the database. + + If TokenNumber is 0 and Guid is not NULL, then the first token from the token space specified by Guid is returned. + If TokenNumber is not 0 and Guid is not NULL, then the next token in the token space specified by Guid is returned. + If TokenNumber is 0 and Guid is NULL, then the first token in the default token space is returned. + If TokenNumber is not 0 and Guid is NULL, then the next token in the default token space is returned. + The token numbers in the default token space may not be related to token numbers in token spaces that are named by Guid. + If the next token number can be retrieved, then it is returned in TokenNumber, and EFI_SUCCESS is returned. + If TokenNumber represents the last token number in the token space specified by Guid, then EFI_NOT_FOUND is returned. + If TokenNumber is not present in the token space specified by Guid, then EFI_NOT_FOUND is returned. + + + @param[in] Guid The 128-bit unique value that designates the namespace from which to retrieve the next token. + This is an optional parameter that may be NULL. If this parameter is NULL, then a request is + being made to retrieve tokens from the default token space. + @param[in,out] TokenNumber + A pointer to the PCD token number to use to find the subsequent token number. + + @retval EFI_SUCCESS The PCD service has retrieved the next valid token number. + @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_GET_NEXT_TOKEN)( + IN CONST EFI_GUID *Guid OPTIONAL, + IN OUT UINTN *TokenNumber + ); + +/** + Retrieves the next valid PCD token namespace for a given namespace. + + Gets the next valid token namespace for a given namespace. This is useful to traverse the valid + token namespaces on a platform. + + @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token namespace + from which the search will start. On output, it designates the next valid token + namespace on the platform. If *Guid is NULL, then the GUID of the first token + space of the current platform is returned. If the search cannot locate the next valid + token namespace, an error is returned and the value of *Guid is undefined. + + @retval EFI_SUCCESS The PCD service retrieved the value requested. + @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace. + +**/ +typedef +EFI_STATUS +(EFIAPI *PCD_PROTOCOL_GET_NEXT_TOKENSPACE)( + IN OUT CONST EFI_GUID **Guid + ); + +/// +/// This service abstracts the ability to set/get Platform Configuration Database (PCD). +/// +typedef struct { + PCD_PROTOCOL_SET_SKU SetSku; + + PCD_PROTOCOL_GET8 Get8; + PCD_PROTOCOL_GET16 Get16; + PCD_PROTOCOL_GET32 Get32; + PCD_PROTOCOL_GET64 Get64; + PCD_PROTOCOL_GET_POINTER GetPtr; + PCD_PROTOCOL_GET_BOOLEAN GetBool; + PCD_PROTOCOL_GET_SIZE GetSize; + + PCD_PROTOCOL_GET_EX_8 Get8Ex; + PCD_PROTOCOL_GET_EX_16 Get16Ex; + PCD_PROTOCOL_GET_EX_32 Get32Ex; + PCD_PROTOCOL_GET_EX_64 Get64Ex; + PCD_PROTOCOL_GET_EX_POINTER GetPtrEx; + PCD_PROTOCOL_GET_EX_BOOLEAN GetBoolEx; + PCD_PROTOCOL_GET_EX_SIZE GetSizeEx; + + PCD_PROTOCOL_SET8 Set8; + PCD_PROTOCOL_SET16 Set16; + PCD_PROTOCOL_SET32 Set32; + PCD_PROTOCOL_SET64 Set64; + PCD_PROTOCOL_SET_POINTER SetPtr; + PCD_PROTOCOL_SET_BOOLEAN SetBool; + + PCD_PROTOCOL_SET_EX_8 Set8Ex; + PCD_PROTOCOL_SET_EX_16 Set16Ex; + PCD_PROTOCOL_SET_EX_32 Set32Ex; + PCD_PROTOCOL_SET_EX_64 Set64Ex; + PCD_PROTOCOL_SET_EX_POINTER SetPtrEx; + PCD_PROTOCOL_SET_EX_BOOLEAN SetBoolEx; + + PCD_PROTOCOL_CALLBACK_ONSET CallbackOnSet; + PCD_PROTOCOL_CANCEL_CALLBACK CancelCallback; + PCD_PROTOCOL_GET_NEXT_TOKEN GetNextToken; + PCD_PROTOCOL_GET_NEXT_TOKENSPACE GetNextTokenSpace; +} PCD_PROTOCOL; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/PciEnumerationComplete.h b/sys/contrib/edk2/Include/Protocol/PciEnumerationComplete.h new file mode 100644 index 000000000000..4999b7637cf0 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/PciEnumerationComplete.h @@ -0,0 +1,24 @@ +/** @file + PCI Enumeration Complete Protocol as defined in the PI 1.1 specification. + This protocol indicates that pci enumeration complete + + Copyright (c) 2009, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is defined in UEFI Platform Initialization Specification 1.2 + Volume 5: Standards + +**/ + +#ifndef _PCI_ENUMERATION_COMPLETE_H_ +#define _PCI_ENUMERATION_COMPLETE_H_ + +#define EFI_PCI_ENUMERATION_COMPLETE_GUID \ + { \ + 0x30cfe3e7, 0x3de1, 0x4586, { 0xbe, 0x20, 0xde, 0xab, 0xa1, 0xb3, 0xb7, 0x93 } \ + } + +extern EFI_GUID gEfiPciEnumerationCompleteProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/PciHostBridgeResourceAllocation.h b/sys/contrib/edk2/Include/Protocol/PciHostBridgeResourceAllocation.h new file mode 100644 index 000000000000..cd0fc9585367 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/PciHostBridgeResourceAllocation.h @@ -0,0 +1,422 @@ +/** @file + This file declares PCI Host Bridge Resource Allocation Protocol which + provides the basic interfaces to abstract a PCI host bridge resource allocation. + This protocol is mandatory if the system includes PCI devices. + +Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is defined in UEFI Platform Initialization Specification 1.2 + Volume 5: Standards. + +**/ + +#ifndef _PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_H_ +#define _PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_H_ + +// +// This file must be included because EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL +// uses EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS +// +#include <Protocol/PciRootBridgeIo.h> + +/// +/// Global ID for the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. +/// +#define EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GUID \ + { \ + 0xCF8034BE, 0x6768, 0x4d8b, {0xB7,0x39,0x7C,0xCE,0x68,0x3A,0x9F,0xBE } \ + } + +/// +/// Forward declaration for EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. +/// +typedef struct _EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL; + +/// If this bit is set, then the PCI Root Bridge does not +/// support separate windows for Non-prefetchable and Prefetchable +/// memory. A PCI bus driver needs to include requests for Prefetchable +/// memory in the Non-prefetchable memory pool. +/// +#define EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM 1 + +/// +/// If this bit is set, then the PCI Root Bridge supports +/// 64 bit memory windows. If this bit is not set, +/// the PCI bus driver needs to include requests for 64 bit +/// memory address in the corresponding 32 bit memory pool. +/// +#define EFI_PCI_HOST_BRIDGE_MEM64_DECODE 2 + +/// +/// A UINT64 value that contains the status of a PCI resource requested +/// in the Configuration parameter returned by GetProposedResources() +/// The legal values are EFI_RESOURCE_SATISFIED and EFI_RESOURCE_NOT_SATISFIED +/// +typedef UINT64 EFI_RESOURCE_ALLOCATION_STATUS; + +/// +/// The request of this resource type could be fulfilled. Used in the +/// Configuration parameter returned by GetProposedResources() to identify +/// a PCI resources request that can be satisfied. +/// +#define EFI_RESOURCE_SATISFIED 0x0000000000000000ULL + +/// +/// The request of this resource type could not be fulfilled for its +/// absence in the host bridge resource pool. Used in the Configuration parameter +/// returned by GetProposedResources() to identify a PCI resources request that +/// can not be satisfied. +/// +#define EFI_RESOURCE_NOT_SATISFIED 0xFFFFFFFFFFFFFFFFULL + +/// +/// This enum is used to specify the phase of the PCI enumaeration process. +/// +typedef enum { + /// + /// Reset the host bridge PCI apertures and internal data structures. + /// PCI enumerator should issue this notification before starting fresh + /// enumeration process. Enumeration cannot be restarted after sending + /// any other notification such as EfiPciHostBridgeBeginBusAllocation. + /// + EfiPciHostBridgeBeginEnumeration, + + /// + /// The bus allocation phase is about to begin. No specific action + /// is required here. This notification can be used to perform any + /// chipset specific programming. + /// + EfiPciHostBridgeBeginBusAllocation, + + /// + /// The bus allocation and bus programming phase is complete. No specific + /// action is required here. This notification can be used to perform any + /// chipset specific programming. + /// + EfiPciHostBridgeEndBusAllocation, + + /// + /// The resource allocation phase is about to begin.No specific action is + /// required here. This notification can be used to perform any chipset specific programming. + /// + EfiPciHostBridgeBeginResourceAllocation, + + /// + /// Allocate resources per previously submitted requests for all the PCI Root + /// Bridges. These resource settings are returned on the next call to + /// GetProposedResources(). + /// + EfiPciHostBridgeAllocateResources, + + /// + /// Program the Host Bridge hardware to decode previously allocated resources + /// (proposed resources) for all the PCI Root Bridges. + /// + EfiPciHostBridgeSetResources, + + /// + /// De-allocate previously allocated resources previously for all the PCI + /// Root Bridges and reset the I/O and memory apertures to initial state. + /// + EfiPciHostBridgeFreeResources, + + /// + /// The resource allocation phase is completed. No specific action is required + /// here. This notification can be used to perform any chipset specific programming. + /// + EfiPciHostBridgeEndResourceAllocation, + + /// + /// The Host Bridge Enumeration is completed. No specific action is required here. + /// This notification can be used to perform any chipset specific programming. + /// + EfiPciHostBridgeEndEnumeration, + EfiMaxPciHostBridgeEnumerationPhase +} EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE; + +/// +/// Definitions of 2 notification points. +/// +typedef enum { + /// + /// This notification is only applicable to PCI-PCI bridges and + /// indicates that the PCI enumerator is about to begin enumerating + /// the bus behind the PCI-PCI Bridge. This notification is sent after + /// the primary bus number, the secondary bus number and the subordinate + /// bus number registers in the PCI-PCI Bridge are programmed to valid + /// (not necessary final) values + /// + EfiPciBeforeChildBusEnumeration, + + /// + /// This notification is sent before the PCI enumerator probes BAR registers + /// for every valid PCI function. + /// + EfiPciBeforeResourceCollection +} EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE; + +/** + These are the notifications from the PCI bus driver that it is about to enter a certain phase of the PCI + enumeration process. + + @param[in] This The pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + instance. + @param[in] Phase The phase during enumeration. + + @retval EFI_SUCCESS The notification was accepted without any errors. + @retval EFI_INVALID_PARAMETER The Phase is invalid. + @retval EFI_NOT_READY This phase cannot be entered at this time. For example, this error + is valid for a Phase of EfiPciHostBridgeAllocateResources if + SubmitResources() has not been called for one or more + PCI root bridges before this call. + @retval EFI_DEVICE_ERROR Programming failed due to a hardware error. This error is valid for + a Phase of EfiPciHostBridgeSetResources. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + This error is valid for a Phase of EfiPciHostBridgeAllocateResources + if the previously submitted resource requests cannot be fulfilled or were only + partially fulfilled + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_NOTIFY_PHASE)( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase + ); + +/** + Returns the device handle of the next PCI root bridge that is associated with this host bridge. + + @param[in] This The pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + instance. + @param[in,out] RootBridgeHandle Returns the device handle of the next PCI root bridge. On input, it holds the + RootBridgeHandle that was returned by the most recent call to + GetNextRootBridge(). If RootBridgeHandle is NULL on input, the handle + for the first PCI root bridge is returned. + + @retval EFI_SUCCESS The requested attribute information was returned. + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not an EFI_HANDLE that was returned + on a previous call to GetNextRootBridge(). + @retval EFI_NOT_FOUND There are no more PCI root bridge device handles. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_NEXT_ROOT_BRIDGE)( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN OUT EFI_HANDLE *RootBridgeHandle + ); + +/** + Returns the allocation attributes of a PCI root bridge. + + @param[in] This The pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + instance. + @param[in] RootBridgeHandle The device handle of the PCI root bridge in which the caller is interested. + @param[out] Attribute The pointer to attributes of the PCI root bridge. + + @retval EFI_SUCCESS The requested attribute information was returned. + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle. + @retval EFI_INVALID_PARAMETER Attributes is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_ATTRIBUTES)( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + OUT UINT64 *Attributes + ); + +/** + Sets up the specified PCI root bridge for the bus enumeration process. + + @param[in] This The pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + instance. + @param[in] RootBridgeHandle The PCI root bridge to be set up. + @param[out] Configuration The pointer to the pointer to the PCI bus resource descriptor. + + @retval EFI_SUCCESS The PCI root bridge was set up and the bus range was returned in + Configuration. + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle. + @retval EFI_DEVICE_ERROR Programming failed due to a hardware error. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_START_BUS_ENUMERATION)( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + OUT VOID **Configuration + ); + +/** + Programs the PCI root bridge hardware so that it decodes the specified PCI bus range. + + @param[in] This The pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + instance. + @param[in] RootBridgeHandle The PCI root bridge whose bus range is to be programmed. + @param[in] Configuration The pointer to the PCI bus resource descriptor. + + @retval EFI_SUCCESS The bus range for the PCI root bridge was programmed. + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle. + @retval EFI_INVALID_PARAMETER Configuration is NULL + @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI (2.0 & 3.0) + resource descriptor. + @retval EFI_INVALID_PARAMETER Configuration does not include a valid ACPI 2.0 bus resource + descriptor. + @retval EFI_INVALID_PARAMETER Configuration includes valid ACPI (2.0 & 3.0) resource + descriptors other than bus descriptors. + @retval EFI_INVALID_PARAMETER Configuration contains one or more invalid ACPI resource + descriptors. + @retval EFI_INVALID_PARAMETER "Address Range Minimum" is invalid for this root bridge. + @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this root bridge. + @retval EFI_DEVICE_ERROR Programming failed due to a hardware error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_SET_BUS_NUMBERS)( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + IN VOID *Configuration + ); + +/** + Submits the I/O and memory resource requirements for the specified PCI root bridge. + + @param[in] This The pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + instance. + @param[in] RootBridgeHandle The PCI root bridge whose I/O and memory resource requirements are being + submitted. + @param[in] Configuration The pointer to the PCI I/O and PCI memory resource descriptor. + + @retval EFI_SUCCESS The I/O and memory resource requests for a PCI root bridge were + accepted. + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI (2.0 & 3.0) + resource descriptor. + @retval EFI_INVALID_PARAMETER Configuration includes requests for one or more resource + types that are not supported by this PCI root bridge. This error will + happen if the caller did not combine resources according to + Attributes that were returned by GetAllocAttributes(). + @retval EFI_INVALID_PARAMETER "Address Range Maximum" is invalid. + @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this PCI root bridge. + @retval EFI_INVALID_PARAMETER "Address Space Granularity" is invalid for this PCI root bridge. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_SUBMIT_RESOURCES)( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + IN VOID *Configuration + ); + +/** + Returns the proposed resource settings for the specified PCI root bridge. + + @param[in] This The pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + instance. + @param[in] RootBridgeHandle The PCI root bridge handle. + @param[out] Configuration The pointer to the pointer to the PCI I/O and memory resource descriptor. + + @retval EFI_SUCCESS The requested parameters were returned. + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle. + @retval EFI_DEVICE_ERROR Programming failed due to a hardware error. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_PROPOSED_RESOURCES)( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + OUT VOID **Configuration + ); + +/** + Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various + stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual + PCI controllers before enumeration. + + @param[in] This The pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance. + @param[in] RootBridgeHandle The associated PCI root bridge handle. + @param[in] PciAddress The address of the PCI device on the PCI bus. + @param[in] Phase The phase of the PCI device enumeration. + + @retval EFI_SUCCESS The requested parameters were returned. + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle. + @retval EFI_INVALID_PARAMETER Phase is not a valid phase that is defined in + EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE. + @retval EFI_DEVICE_ERROR Programming failed due to a hardware error. The PCI enumerator + should not enumerate this device, including its child devices if it is + a PCI-to-PCI bridge. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_PREPROCESS_CONTROLLER)( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress, + IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase + ); + +/// +/// Provides the basic interfaces to abstract a PCI host bridge resource allocation. +/// +struct _EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL { + /// + /// The notification from the PCI bus enumerator that it is about to enter + /// a certain phase during the enumeration process. + /// + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_NOTIFY_PHASE NotifyPhase; + + /// + /// Retrieves the device handle for the next PCI root bridge that is produced by the + /// host bridge to which this instance of the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is attached. + /// + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_NEXT_ROOT_BRIDGE GetNextRootBridge; + + /// + /// Retrieves the allocation-related attributes of a PCI root bridge. + /// + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_ATTRIBUTES GetAllocAttributes; + + /// + /// Sets up a PCI root bridge for bus enumeration. + /// + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_START_BUS_ENUMERATION StartBusEnumeration; + + /// + /// Sets up the PCI root bridge so that it decodes a specific range of bus numbers. + /// + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_SET_BUS_NUMBERS SetBusNumbers; + + /// + /// Submits the resource requirements for the specified PCI root bridge. + /// + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_SUBMIT_RESOURCES SubmitResources; + + /// + /// Returns the proposed resource assignment for the specified PCI root bridges. + /// + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_PROPOSED_RESOURCES GetProposedResources; + + /// + /// Provides hooks from the PCI bus driver to every PCI controller + /// (device/function) at various stages of the PCI enumeration process that + /// allow the host bridge driver to preinitialize individual PCI controllers + /// before enumeration. + /// + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_PREPROCESS_CONTROLLER PreprocessController; +}; + +extern EFI_GUID gEfiPciHostBridgeResourceAllocationProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/PciHotPlugInit.h b/sys/contrib/edk2/Include/Protocol/PciHotPlugInit.h new file mode 100644 index 000000000000..5d5a86a4ca11 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/PciHotPlugInit.h @@ -0,0 +1,272 @@ +/** @file + This file declares EFI PCI Hot Plug Init Protocol. + + This protocol provides the necessary functionality to initialize the Hot Plug + Controllers (HPCs) and the buses that they control. This protocol also provides + information regarding resource padding. + + @par Note: + This protocol is required only on platforms that support one or more PCI Hot + Plug* slots or CardBus sockets. + + The EFI_PCI_HOT_PLUG_INIT_PROTOCOL provides a mechanism for the PCI bus enumerator + to properly initialize the HPCs and CardBus sockets that require initialization. + The HPC initialization takes place before the PCI enumeration process is complete. + There cannot be more than one instance of this protocol in a system. This protocol + is installed on its own separate handle. + + Because the system may include multiple HPCs, one instance of this protocol + should represent all of them. The protocol functions use the device path of + the HPC to identify the HPC. When the PCI bus enumerator finds a root HPC, it + will call EFI_PCI_HOT_PLUG_INIT_PROTOCOL.InitializeRootHpc(). If InitializeRootHpc() + is unable to initialize a root HPC, the PCI enumerator will ignore that root HPC + and continue the enumeration process. If the HPC is not initialized, the devices + that it controls may not be initialized, and no resource padding will be provided. + + From the standpoint of the PCI bus enumerator, HPCs are divided into the following + two classes: + + - Root HPC: + These HPCs must be initialized by calling InitializeRootHpc() during the + enumeration process. These HPCs will also require resource padding. The + platform code must have a priori knowledge of these devices and must know + how to initialize them. There may not be any way to access their PCI + configuration space before the PCI enumerator programs all the upstream + bridges and thus enables the path to these devices. The PCI bus enumerator + is responsible for determining the PCI bus address of the HPC before it + calls InitializeRootHpc(). + - Nonroot HPC: + These HPCs will not need explicit initialization during enumeration process. + These HPCs will require resource padding. The platform code does not have + to have a priori knowledge of these devices. + + Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is defined in UEFI Platform Initialization Specification 1.2 + Volume 5: Standards + +**/ + +#ifndef _EFI_PCI_HOT_PLUG_INIT_H_ +#define _EFI_PCI_HOT_PLUG_INIT_H_ + +/// +/// Global ID for the EFI_PCI_HOT_PLUG_INIT_PROTOCOL +/// +#define EFI_PCI_HOT_PLUG_INIT_PROTOCOL_GUID \ + { \ + 0xaa0e8bc1, 0xdabc, 0x46b0, {0xa8, 0x44, 0x37, 0xb8, 0x16, 0x9b, 0x2b, 0xea } \ + } + +/// +/// Forward declaration for EFI_PCI_HOT_PLUG_INIT_PROTOCOL +/// +typedef struct _EFI_PCI_HOT_PLUG_INIT_PROTOCOL EFI_PCI_HOT_PLUG_INIT_PROTOCOL; + +/// +/// Describes the current state of an HPC +/// +typedef UINT16 EFI_HPC_STATE; + +/// +/// The HPC initialization function was called and the HPC completed +/// initialization, but it was not enabled for some reason. The HPC may be +/// disabled in hardware, or it may be disabled due to user preferences, +/// hardware failure, or other reasons. No resource padding is required. +/// +#define EFI_HPC_STATE_INITIALIZED 0x01 + +/// +/// The HPC initialization function was called, the HPC completed +/// initialization, and it was enabled. Resource padding is required. +/// +#define EFI_HPC_STATE_ENABLED 0x02 + +/// +/// Location definition for PCI Hot Plug Controller +/// +typedef struct { + /// + /// + /// The device path to the root HPC. An HPC cannot control its parent buses. + /// The PCI bus driver requires this information so that it can pass the + /// correct HpcPciAddress to the InitializeRootHpc() and GetResourcePadding() + /// functions. + /// + EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath; + /// + /// The device path to the Hot Plug Bus (HPB) that is controlled by the root + /// HPC. The PCI bus driver uses this information to check if a particular PCI + /// bus has hot-plug slots. The device path of a PCI bus is the same as the + /// device path of its parent. For Standard(PCI) Hot Plug Controllers (SHPCs) + /// and PCI Express*, HpbDevicePath is the same as HpcDevicePath. + /// + EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath; +} EFI_HPC_LOCATION; + +/// +/// Describes how resource padding should be applied +/// +typedef enum { + /// + /// Apply the padding at a PCI bus level. In other words, the resources + /// that are allocated to the bus containing hot-plug slots are padded by + /// the specified amount. If the hot-plug bus is behind a PCI-to-PCI + /// bridge, the PCI-to-PCI bridge apertures will indicate the padding + /// + EfiPaddingPciBus, + /// + /// Apply the padding at a PCI root bridge level. If a PCI root bridge + /// includes more than one hot-plug bus, the resource padding requests + /// for these buses are added together and the resources that are + /// allocated to the root bridge are padded by the specified amount. This + /// strategy may reduce the total amount of padding, but requires + /// reprogramming of PCI-to-PCI bridges in a hot-add event. If the hotplug + /// bus is behind a PCI-to-PCI bridge, the PCI-to-PCI bridge + /// apertures do not indicate the padding for that bus. + /// + EfiPaddingPciRootBridge +} EFI_HPC_PADDING_ATTRIBUTES; + +/** + Returns a list of root Hot Plug Controllers (HPCs) that require initialization + during the boot process. + + This procedure returns a list of root HPCs. The PCI bus driver must initialize + these controllers during the boot process. The PCI bus driver may or may not be + able to detect these HPCs. If the platform includes a PCI-to-CardBus bridge, it + can be included in this list if it requires initialization. The HpcList must be + self consistent. An HPC cannot control any of its parent buses. Only one HPC can + control a PCI bus. Because this list includes only root HPCs, no HPC in the list + can be a child of another HPC. This policy must be enforced by the + EFI_PCI_HOT_PLUG_INIT_PROTOCOL. The PCI bus driver may not check for such + invalid conditions. The callee allocates the buffer HpcList + + @param[in] This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL instance. + @param[out] HpcCount The number of root HPCs that were returned. + @param[out] HpcList The list of root HPCs. HpcCount defines the number of + elements in this list. + + @retval EFI_SUCCESS HpcList was returned. + @retval EFI_OUT_OF_RESOURCES HpcList was not returned due to insufficient + resources. + @retval EFI_INVALID_PARAMETER HpcCount is NULL or HpcList is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_GET_ROOT_HPC_LIST)( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + OUT UINTN *HpcCount, + OUT EFI_HPC_LOCATION **HpcList + ); + +/** + Initializes one root Hot Plug Controller (HPC). This process may causes + initialization of its subordinate buses. + + This function initializes the specified HPC. At the end of initialization, + the hot-plug slots or sockets (controlled by this HPC) are powered and are + connected to the bus. All the necessary registers in the HPC are set up. For + a Standard (PCI) Hot Plug Controller (SHPC), the registers that must be set + up are defined in the PCI Standard Hot Plug Controller and Subsystem + Specification. + + @param[in] This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL instance. + @param[in] HpcDevicePath The device path to the HPC that is being initialized. + @param[in] HpcPciAddress The address of the HPC function on the PCI bus. + @param[in] Event The event that should be signaled when the HPC + initialization is complete. Set to NULL if the + caller wants to wait until the entire initialization + process is complete. + @param[out] HpcState The state of the HPC hardware. The state is + EFI_HPC_STATE_INITIALIZED or EFI_HPC_STATE_ENABLED. + + @retval EFI_SUCCESS If Event is NULL, the specific HPC was successfully + initialized. If Event is not NULL, Event will be + signaled at a later time when initialization is complete. + @retval EFI_UNSUPPORTED This instance of EFI_PCI_HOT_PLUG_INIT_PROTOCOL + does not support the specified HPC. + @retval EFI_OUT_OF_RESOURCES Initialization failed due to insufficient + resources. + @retval EFI_INVALID_PARAMETER HpcState is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_INITIALIZE_ROOT_HPC)( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, + IN UINT64 HpcPciAddress, + IN EFI_EVENT Event OPTIONAL, + OUT EFI_HPC_STATE *HpcState + ); + +/** + Returns the resource padding that is required by the PCI bus that is controlled + by the specified Hot Plug Controller (HPC). + + This function returns the resource padding that is required by the PCI bus that + is controlled by the specified HPC. This member function is called for all the + root HPCs and nonroot HPCs that are detected by the PCI bus enumerator. This + function will be called before PCI resource allocation is completed. This function + must be called after all the root HPCs, with the possible exception of a + PCI-to-CardBus bridge, have completed initialization. + + @param[in] This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL instance. + @param[in] HpcDevicePath The device path to the HPC. + @param[in] HpcPciAddress The address of the HPC function on the PCI bus. + @param[in] HpcState The state of the HPC hardware. + @param[out] Padding The amount of resource padding that is required by the + PCI bus under the control of the specified HPC. + @param[out] Attributes Describes how padding is accounted for. The padding + is returned in the form of ACPI 2.0 resource descriptors. + + @retval EFI_SUCCESS The resource padding was successfully returned. + @retval EFI_UNSUPPORTED This instance of the EFI_PCI_HOT_PLUG_INIT_PROTOCOL + does not support the specified HPC. + @retval EFI_NOT_READY This function was called before HPC initialization + is complete. + @retval EFI_INVALID_PARAMETER HpcState or Padding or Attributes is NULL. + @retval EFI_OUT_OF_RESOURCES ACPI 2.0 resource descriptors for Padding + cannot be allocated due to insufficient resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_GET_HOT_PLUG_PADDING)( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, + IN UINT64 HpcPciAddress, + OUT EFI_HPC_STATE *HpcState, + OUT VOID **Padding, + OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes + ); + +/// +/// This protocol provides the necessary functionality to initialize the +/// Hot Plug Controllers (HPCs) and the buses that they control. This protocol +/// also provides information regarding resource padding. +/// +struct _EFI_PCI_HOT_PLUG_INIT_PROTOCOL { + /// + /// Returns a list of root HPCs and the buses that they control. + /// + EFI_GET_ROOT_HPC_LIST GetRootHpcList; + + /// + /// Initializes the specified root HPC. + /// + EFI_INITIALIZE_ROOT_HPC InitializeRootHpc; + + /// + /// Returns the resource padding that is required by the HPC. + /// + EFI_GET_HOT_PLUG_PADDING GetResourcePadding; +}; + +extern EFI_GUID gEfiPciHotPlugInitProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/PciHotPlugRequest.h b/sys/contrib/edk2/Include/Protocol/PciHotPlugRequest.h new file mode 100644 index 000000000000..1b460fbb9226 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/PciHotPlugRequest.h @@ -0,0 +1,164 @@ +/** @file + Provides services to notify the PCI bus driver that some events have happened + in a hot-plug controller (such as a PC Card socket, or PHPC), and to ask the + PCI bus driver to create or destroy handles for PCI-like devices. + + A hot-plug capable PCI bus driver should produce the EFI PCI Hot Plug Request + protocol. When a PCI device or a PCI-like device (for example, 32-bit PC Card) + is installed after PCI bus does the enumeration, the PCI bus driver can be + notified through this protocol. For example, when a 32-bit PC Card is inserted + into the PC Card socket, the PC Card bus driver can call interface of this + protocol to notify PCI bus driver to allocate resource and create handles for + this PC Card. + + The EFI_PCI_HOTPLUG_REQUEST_PROTOCOL is installed by the PCI bus driver on a + separate handle when PCI bus driver starts up. There is only one instance in + the system. Any driver that wants to use this protocol must locate it globally. + The EFI_PCI_HOTPLUG_REQUEST_PROTOCOL allows the driver of hot-plug controller, + for example, PC Card Bus driver, to notify PCI bus driver that an event has + happened in the hot-plug controller, and the PCI bus driver is requested to + create (add) or destroy (remove) handles for the specified PCI-like devices. + For example, when a 32-bit PC Card is inserted, this protocol interface will + be called with an add operation, and the PCI bus driver will enumerate and + start the devices inserted; when a 32-bit PC Card is removed, this protocol + interface will be called with a remove operation, and the PCI bus driver will + stop the devices and destroy their handles. The existence of this protocol + represents the capability of the PCI bus driver. If this protocol exists in + system, it means PCI bus driver is hot-plug capable, thus together with the + effort of PC Card bus driver, hot-plug of PC Card can be supported. Otherwise, + the hot-plug capability is not provided. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is defined in UEFI Platform Initialization Specification 1.2 + Volume 5: Standards + +**/ + +#ifndef __PCI_HOTPLUG_REQUEST_H_ +#define __PCI_HOTPLUG_REQUEST_H_ + +/// +/// Global ID for EFI_PCI_HOTPLUG_REQUEST_PROTOCOL +/// +#define EFI_PCI_HOTPLUG_REQUEST_PROTOCOL_GUID \ + { \ + 0x19cb87ab, 0x2cb9, 0x4665, {0x83, 0x60, 0xdd, 0xcf, 0x60, 0x54, 0xf7, 0x9d} \ + } + +/// +/// Forward declaration for EFI_PCI_HOTPLUG_REQUEST_PROTOCOL +/// +typedef struct _EFI_PCI_HOTPLUG_REQUEST_PROTOCOL EFI_PCI_HOTPLUG_REQUEST_PROTOCOL; + +/// +/// Enumeration of PCI hot plug operations +/// +typedef enum { + /// + /// The PCI bus driver is requested to create handles for the specified devices. + /// An array of EFI_HANDLE is returned, with a NULL element marking the end of + /// the array. + /// + EfiPciHotPlugRequestAdd, + + /// + /// The PCI bus driver is requested to destroy handles for the specified devices. + /// + EfiPciHotplugRequestRemove +} EFI_PCI_HOTPLUG_OPERATION; + +/** + This function is used to notify PCI bus driver that some events happened in a + hot-plug controller, and the PCI bus driver is requested to start or stop + specified PCI-like devices. + + This function allows the PCI bus driver to be notified to act as requested when + a hot-plug event has happened on the hot-plug controller. Currently, the + operations include add operation and remove operation. If it is a add operation, + the PCI bus driver will enumerate, allocate resources for devices behind the + hot-plug controller, and create handle for the device specified by RemainingDevicePath. + The RemainingDevicePath is an optional parameter. If it is not NULL, only the + specified device is started; if it is NULL, all devices behind the hot-plug + controller are started. The newly created handles of PC Card functions are + returned in the ChildHandleBuffer, together with the number of child handle in + NumberOfChildren. If it is a remove operation, when NumberOfChildren contains + a non-zero value, child handles specified in ChildHandleBuffer are stopped and + destroyed; otherwise, PCI bus driver is notified to stop managing the controller + handle. + + @param[in] This A pointer to the EFI_PCI_HOTPLUG_REQUEST_PROTOCOL + instance. + @param[in] Operation The operation the PCI bus driver is requested + to make. + @param[in] Controller The handle of the hot-plug controller. + @param[in] RemainingDevicePath The remaining device path for the PCI-like + hot-plug device. It only contains device + path nodes behind the hot-plug controller. + It is an optional parameter and only valid + when the Operation is a add operation. If + it is NULL, all devices behind the PC Card + socket are started. + @param[in,out] NumberOfChildren The number of child handles. For an add + operation, it is an output parameter. For + a remove operation, it's an input parameter. + When it contains a non-zero value, children + handles specified in ChildHandleBuffer are + destroyed. Otherwise, PCI bus driver is + notified to stop managing the controller + handle. + @param[in,out] ChildHandleBuffer The buffer which contains the child handles. + For an add operation, it is an output + parameter and contains all newly created + child handles. For a remove operation, it + contains child handles to be destroyed when + NumberOfChildren contains a non-zero value. + It can be NULL when NumberOfChildren is 0. + It's the caller's responsibility to allocate + and free memory for this buffer. + + @retval EFI_SUCCESS The handles for the specified device have been + created or destroyed as requested, and for an + add operation, the new handles are returned in + ChildHandleBuffer. + @retval EFI_INVALID_PARAMETER Operation is not a legal value. + @retval EFI_INVALID_PARAMETER Controller is NULL or not a valid handle. + @retval EFI_INVALID_PARAMETER NumberOfChildren is NULL. + @retval EFI_INVALID_PARAMETER ChildHandleBuffer is NULL while Operation is + remove and NumberOfChildren contains a non-zero + value. + @retval EFI_INVALID_PARAMETER ChildHandleBuffer is NULL while Operation is add. + @retval EFI_OUT_OF_RESOURCES There are no enough resources to start the + devices. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_HOTPLUG_REQUEST_NOTIFY)( + IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL *This, + IN EFI_PCI_HOTPLUG_OPERATION Operation, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, + IN OUT UINT8 *NumberOfChildren, + IN OUT EFI_HANDLE *ChildHandleBuffer + ); + +/// +/// Provides services to notify PCI bus driver that some events have happened in +/// a hot-plug controller (for example, PC Card socket, or PHPC), and ask PCI bus +/// driver to create or destroy handles for the PCI-like devices. +/// +struct _EFI_PCI_HOTPLUG_REQUEST_PROTOCOL { + /// + /// Notify the PCI bus driver that some events have happened in a hot-plug + /// controller (for example, PC Card socket, or PHPC), and ask PCI bus driver + /// to create or destroy handles for the PCI-like devices. See Section 0 for + /// a detailed description. + /// + EFI_PCI_HOTPLUG_REQUEST_NOTIFY Notify; +}; + +extern EFI_GUID gEfiPciHotPlugRequestProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/PciIo.h b/sys/contrib/edk2/Include/Protocol/PciIo.h new file mode 100644 index 000000000000..cc2dbde24352 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/PciIo.h @@ -0,0 +1,551 @@ +/** @file + EFI PCI I/O Protocol provides the basic Memory, I/O, PCI configuration, + and DMA interfaces that a driver uses to access its PCI controller. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PCI_IO_H__ +#define __PCI_IO_H__ + +/// +/// Global ID for the PCI I/O Protocol +/// +#define EFI_PCI_IO_PROTOCOL_GUID \ + { \ + 0x4cf5b200, 0x68b8, 0x4ca5, {0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x2, 0x9a } \ + } + +typedef struct _EFI_PCI_IO_PROTOCOL EFI_PCI_IO_PROTOCOL; + +/// +/// ******************************************************* +/// EFI_PCI_IO_PROTOCOL_WIDTH +/// ******************************************************* +/// +typedef enum { + EfiPciIoWidthUint8 = 0, + EfiPciIoWidthUint16, + EfiPciIoWidthUint32, + EfiPciIoWidthUint64, + EfiPciIoWidthFifoUint8, + EfiPciIoWidthFifoUint16, + EfiPciIoWidthFifoUint32, + EfiPciIoWidthFifoUint64, + EfiPciIoWidthFillUint8, + EfiPciIoWidthFillUint16, + EfiPciIoWidthFillUint32, + EfiPciIoWidthFillUint64, + EfiPciIoWidthMaximum +} EFI_PCI_IO_PROTOCOL_WIDTH; + +// +// Complete PCI address generater +// +#define EFI_PCI_IO_PASS_THROUGH_BAR 0xff ///< Special BAR that passes a memory or I/O cycle through unchanged +#define EFI_PCI_IO_ATTRIBUTE_MASK 0x077f ///< All the following I/O and Memory cycles +#define EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO 0x0001 ///< I/O cycles 0x0000-0x00FF (10 bit decode) +#define EFI_PCI_IO_ATTRIBUTE_ISA_IO 0x0002 ///< I/O cycles 0x0100-0x03FF or greater (10 bit decode) +#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO 0x0004 ///< I/O cycles 0x3C6, 0x3C8, 0x3C9 (10 bit decode) +#define EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY 0x0008 ///< MEM cycles 0xA0000-0xBFFFF (24 bit decode) +#define EFI_PCI_IO_ATTRIBUTE_VGA_IO 0x0010 ///< I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (10 bit decode) +#define EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO 0x0020 ///< I/O cycles 0x1F0-0x1F7, 0x3F6, 0x3F7 (10 bit decode) +#define EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO 0x0040 ///< I/O cycles 0x170-0x177, 0x376, 0x377 (10 bit decode) +#define EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080 ///< Map a memory range so writes are combined +#define EFI_PCI_IO_ATTRIBUTE_IO 0x0100 ///< Enable the I/O decode bit in the PCI Config Header +#define EFI_PCI_IO_ATTRIBUTE_MEMORY 0x0200 ///< Enable the Memory decode bit in the PCI Config Header +#define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER 0x0400 ///< Enable the DMA bit in the PCI Config Header +#define EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED 0x0800 ///< Map a memory range so all r/w accesses are cached +#define EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 ///< Disable a memory range +#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE 0x2000 ///< Clear for an add-in PCI Device +#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM 0x4000 ///< Clear for a physical PCI Option ROM accessed through ROM BAR +#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000 ///< Clear for PCI controllers that can not genrate a DAC +#define EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 0x10000 ///< I/O cycles 0x0100-0x03FF or greater (16 bit decode) +#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000 ///< I/O cycles 0x3C6, 0x3C8, 0x3C9 (16 bit decode) +#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 0x40000 ///< I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (16 bit decode) + +#define EFI_PCI_DEVICE_ENABLE (EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) +#define EFI_VGA_DEVICE_ENABLE (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_IO) + +/// +/// ******************************************************* +/// EFI_PCI_IO_PROTOCOL_OPERATION +/// ******************************************************* +/// +typedef enum { + /// + /// A read operation from system memory by a bus master. + /// + EfiPciIoOperationBusMasterRead, + /// + /// A write operation from system memory by a bus master. + /// + EfiPciIoOperationBusMasterWrite, + /// + /// Provides both read and write access to system memory by both the processor and a + /// bus master. The buffer is coherent from both the processor's and the bus master's point of view. + /// + EfiPciIoOperationBusMasterCommonBuffer, + EfiPciIoOperationMaximum +} EFI_PCI_IO_PROTOCOL_OPERATION; + +/// +/// ******************************************************* +/// EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION +/// ******************************************************* +/// +typedef enum { + /// + /// Retrieve the PCI controller's current attributes, and return them in Result. + /// + EfiPciIoAttributeOperationGet, + /// + /// Set the PCI controller's current attributes to Attributes. + /// + EfiPciIoAttributeOperationSet, + /// + /// Enable the attributes specified by the bits that are set in Attributes for this PCI controller. + /// + EfiPciIoAttributeOperationEnable, + /// + /// Disable the attributes specified by the bits that are set in Attributes for this PCI controller. + /// + EfiPciIoAttributeOperationDisable, + /// + /// Retrieve the PCI controller's supported attributes, and return them in Result. + /// + EfiPciIoAttributeOperationSupported, + EfiPciIoAttributeOperationMaximum +} EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION; + +/** + Reads from the memory space of a PCI controller. Returns either when the polling exit criteria is + satisfied or after a defined duration. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param Width Signifies the width of the memory or I/O operations. + @param BarIndex The BAR index of the standard PCI Configuration header to use as the + base address for the memory operation to perform. + @param Offset The offset within the selected BAR to start the memory operation. + @param Mask Mask used for the polling criteria. + @param Value The comparison value used for the polling exit criteria. + @param Delay The number of 100 ns units to poll. + @param Result Pointer to the last value read from the memory location. + + @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria. + @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. + @retval EFI_UNSUPPORTED Offset is not valid for the BarIndex of this PCI controller. + @retval EFI_TIMEOUT Delay expired before a match occurred. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_POLL_IO_MEM)( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ); + +/** + Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param Width Signifies the width of the memory or I/O operations. + @param BarIndex The BAR index of the standard PCI Configuration header to use as the + base address for the memory or I/O operation to perform. + @param Offset The offset within the selected BAR to start the memory or I/O operation. + @param Count The number of memory or I/O operations to perform. + @param Buffer For read operations, the destination buffer to store the results. For write + operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI controller. + @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. + @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not + valid for the PCI BAR specified by BarIndex. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_IO_MEM)( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +typedef struct { + /// + /// Read PCI controller registers in the PCI memory or I/O space. + /// + EFI_PCI_IO_PROTOCOL_IO_MEM Read; + /// + /// Write PCI controller registers in the PCI memory or I/O space. + /// + EFI_PCI_IO_PROTOCOL_IO_MEM Write; +} EFI_PCI_IO_PROTOCOL_ACCESS; + +/** + Enable a PCI driver to access PCI controller registers in PCI configuration space. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param Width Signifies the width of the memory operations. + @param Offset The offset within the PCI configuration space for the PCI controller. + @param Count The number of PCI configuration operations to perform. + @param Buffer For read operations, the destination buffer to store the results. For write + operations, the source buffer to write data from. + + + @retval EFI_SUCCESS The data was read from or written to the PCI controller. + @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not + valid for the PCI configuration header of the PCI controller. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_CONFIG)( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Offset, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +typedef struct { + /// + /// Read PCI controller registers in PCI configuration space. + /// + EFI_PCI_IO_PROTOCOL_CONFIG Read; + /// + /// Write PCI controller registers in PCI configuration space. + /// + EFI_PCI_IO_PROTOCOL_CONFIG Write; +} EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS; + +/** + Enables a PCI driver to copy one region of PCI memory space to another region of PCI + memory space. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param Width Signifies the width of the memory operations. + @param DestBarIndex The BAR index in the standard PCI Configuration header to use as the + base address for the memory operation to perform. + @param DestOffset The destination offset within the BAR specified by DestBarIndex to + start the memory writes for the copy operation. + @param SrcBarIndex The BAR index in the standard PCI Configuration header to use as the + base address for the memory operation to perform. + @param SrcOffset The source offset within the BAR specified by SrcBarIndex to start + the memory reads for the copy operation. + @param Count The number of memory operations to perform. Bytes moved is Width + size * Count, starting at DestOffset and SrcOffset. + + @retval EFI_SUCCESS The data was copied from one memory region to another memory region. + @retval EFI_UNSUPPORTED DestBarIndex not valid for this PCI controller. + @retval EFI_UNSUPPORTED SrcBarIndex not valid for this PCI controller. + @retval EFI_UNSUPPORTED The address range specified by DestOffset, Width, and Count + is not valid for the PCI BAR specified by DestBarIndex. + @retval EFI_UNSUPPORTED The address range specified by SrcOffset, Width, and Count is + not valid for the PCI BAR specified by SrcBarIndex. + @retval EFI_INVALID_PARAMETER Width is invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_COPY_MEM)( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 DestBarIndex, + IN UINT64 DestOffset, + IN UINT8 SrcBarIndex, + IN UINT64 SrcOffset, + IN UINTN Count + ); + +/** + Provides the PCI controller-specific addresses needed to access system memory. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param Operation Indicates if the bus master is going to read or write to system memory. + @param HostAddress The system memory address to map to the PCI controller. + @param NumberOfBytes On input the number of bytes to map. On output the number of bytes + that were mapped. + @param DeviceAddress The resulting map address for the bus master PCI controller to use to + access the hosts HostAddress. + @param Mapping A resulting value to pass to Unmap(). + + @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_MAP)( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ); + +/** + Completes the Map() operation and releases any corresponding resources. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param Mapping The mapping value returned from Map(). + + @retval EFI_SUCCESS The range was unmapped. + @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_UNMAP)( + IN EFI_PCI_IO_PROTOCOL *This, + IN VOID *Mapping + ); + +/** + Allocates pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer + or EfiPciOperationBusMasterCommonBuffer64 mapping. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param Type This parameter is not used and must be ignored. + @param MemoryType The type of memory to allocate, EfiBootServicesData or + EfiRuntimeServicesData. + @param Pages The number of pages to allocate. + @param HostAddress A pointer to store the base system memory address of the + allocated range. + @param Attributes The requested bit mask of attributes for the allocated range. + + @retval EFI_SUCCESS The requested memory pages were allocated. + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are + MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER)( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes + ); + +/** + Frees memory that was allocated with AllocateBuffer(). + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param Pages The number of pages to free. + @param HostAddress The base system memory address of the allocated range. + + @retval EFI_SUCCESS The requested memory pages were freed. + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages + was not allocated with AllocateBuffer(). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_FREE_BUFFER)( + IN EFI_PCI_IO_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress + ); + +/** + Flushes all PCI posted write transactions from a PCI host bridge to system memory. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + + @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host + bridge to system memory. + @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI + host bridge due to a hardware error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_FLUSH)( + IN EFI_PCI_IO_PROTOCOL *This + ); + +/** + Retrieves this PCI controller's current PCI bus number, device number, and function number. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param SegmentNumber The PCI controller's current PCI segment number. + @param BusNumber The PCI controller's current PCI bus number. + @param DeviceNumber The PCI controller's current PCI device number. + @param FunctionNumber The PCI controller's current PCI function number. + + @retval EFI_SUCCESS The PCI controller location was returned. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_GET_LOCATION)( + IN EFI_PCI_IO_PROTOCOL *This, + OUT UINTN *SegmentNumber, + OUT UINTN *BusNumber, + OUT UINTN *DeviceNumber, + OUT UINTN *FunctionNumber + ); + +/** + Performs an operation on the attributes that this PCI controller supports. The operations include + getting the set of supported attributes, retrieving the current attributes, setting the current + attributes, enabling attributes, and disabling attributes. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param Operation The operation to perform on the attributes for this PCI controller. + @param Attributes The mask of attributes that are used for Set, Enable, and Disable + operations. + @param Result A pointer to the result mask of attributes that are returned for the Get + and Supported operations. + + @retval EFI_SUCCESS The operation on the PCI controller's attributes was completed. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED one or more of the bits set in + Attributes are not supported by this PCI controller or one of + its parent bridges when Operation is Set, Enable or Disable. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_ATTRIBUTES)( + IN EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, + IN UINT64 Attributes, + OUT UINT64 *Result OPTIONAL + ); + +/** + Gets the attributes that this PCI controller supports setting on a BAR using + SetBarAttributes(), and retrieves the list of resource descriptors for a BAR. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param BarIndex The BAR index of the standard PCI Configuration header to use as the + base address for resource range. The legal range for this field is 0..5. + @param Supports A pointer to the mask of attributes that this PCI controller supports + setting for this BAR with SetBarAttributes(). + @param Resources A pointer to the resource descriptors that describe the current + configuration of this BAR of the PCI controller. + + @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI + controller supports are returned in Supports. If Resources + is not NULL, then the resource descriptors that the PCI + controller is currently using are returned in Resources. + @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL. + @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to allocate + Resources. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES)( + IN EFI_PCI_IO_PROTOCOL *This, + IN UINT8 BarIndex, + OUT UINT64 *Supports OPTIONAL, + OUT VOID **Resources OPTIONAL + ); + +/** + Sets the attributes for a range of a BAR on a PCI controller. + + @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. + @param Attributes The mask of attributes to set for the resource range specified by + BarIndex, Offset, and Length. + @param BarIndex The BAR index of the standard PCI Configuration header to use as the + base address for resource range. The legal range for this field is 0..5. + @param Offset A pointer to the BAR relative base address of the resource range to be + modified by the attributes specified by Attributes. + @param Length A pointer to the length of the resource range to be modified by the + attributes specified by Attributes. + + @retval EFI_SUCCESS The set of attributes specified by Attributes for the resource + range specified by BarIndex, Offset, and Length were + set on the PCI controller, and the actual resource range is returned + in Offset and Length. + @retval EFI_INVALID_PARAMETER Offset or Length is NULL. + @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. + @retval EFI_OUT_OF_RESOURCES There are not enough resources to set the attributes on the + resource range specified by BarIndex, Offset, and + Length. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES)( + IN EFI_PCI_IO_PROTOCOL *This, + IN UINT64 Attributes, + IN UINT8 BarIndex, + IN OUT UINT64 *Offset, + IN OUT UINT64 *Length + ); + +/// +/// The EFI_PCI_IO_PROTOCOL provides the basic Memory, I/O, PCI configuration, +/// and DMA interfaces used to abstract accesses to PCI controllers. +/// There is one EFI_PCI_IO_PROTOCOL instance for each PCI controller on a PCI bus. +/// A device driver that wishes to manage a PCI controller in a system will have to +/// retrieve the EFI_PCI_IO_PROTOCOL instance that is associated with the PCI controller. +/// +struct _EFI_PCI_IO_PROTOCOL { + EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollMem; + EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollIo; + EFI_PCI_IO_PROTOCOL_ACCESS Mem; + EFI_PCI_IO_PROTOCOL_ACCESS Io; + EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS Pci; + EFI_PCI_IO_PROTOCOL_COPY_MEM CopyMem; + EFI_PCI_IO_PROTOCOL_MAP Map; + EFI_PCI_IO_PROTOCOL_UNMAP Unmap; + EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer; + EFI_PCI_IO_PROTOCOL_FREE_BUFFER FreeBuffer; + EFI_PCI_IO_PROTOCOL_FLUSH Flush; + EFI_PCI_IO_PROTOCOL_GET_LOCATION GetLocation; + EFI_PCI_IO_PROTOCOL_ATTRIBUTES Attributes; + EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES GetBarAttributes; + EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES SetBarAttributes; + + /// + /// The size, in bytes, of the ROM image. + /// + UINT64 RomSize; + + /// + /// A pointer to the in memory copy of the ROM image. The PCI Bus Driver is responsible + /// for allocating memory for the ROM image, and copying the contents of the ROM to memory. + /// The contents of this buffer are either from the PCI option ROM that can be accessed + /// through the ROM BAR of the PCI controller, or it is from a platform-specific location. + /// The Attributes() function can be used to determine from which of these two sources + /// the RomImage buffer was initialized. + /// + VOID *RomImage; +}; + +extern EFI_GUID gEfiPciIoProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/PciOverride.h b/sys/contrib/edk2/Include/Protocol/PciOverride.h new file mode 100644 index 000000000000..bf033a7877d5 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/PciOverride.h @@ -0,0 +1,39 @@ +/** @file + This file declares EFI PCI Override protocol which provides the interface between + the PCI bus driver/PCI Host Bridge Resource Allocation driver and an implementation's + driver to describe the unique features of a platform. + This protocol is optional. + + Copyright (c) 2009, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is defined in UEFI Platform Initialization Specification 1.2 + Volume 5: Standards + +**/ + +#ifndef _PCI_OVERRIDE_H_ +#define _PCI_OVERRIDE_H_ + +/// +/// EFI_PCI_OVERRIDE_PROTOCOL has the same structure with EFI_PCI_PLATFORM_PROTOCOL +/// +#include <Protocol/PciPlatform.h> + +/// +/// Global ID for the EFI_PCI_OVERRIDE_PROTOCOL +/// +#define EFI_PCI_OVERRIDE_GUID \ + { \ + 0xb5b35764, 0x460c, 0x4a06, {0x99, 0xfc, 0x77, 0xa1, 0x7c, 0x1b, 0x5c, 0xeb} \ + } + +/// +/// Declaration for EFI_PCI_OVERRIDE_PROTOCOL +/// +typedef EFI_PCI_PLATFORM_PROTOCOL EFI_PCI_OVERRIDE_PROTOCOL; + +extern EFI_GUID gEfiPciOverrideProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/PciPlatform.h b/sys/contrib/edk2/Include/Protocol/PciPlatform.h new file mode 100644 index 000000000000..e4b7b46b8676 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/PciPlatform.h @@ -0,0 +1,338 @@ +/** @file + This file declares PlatfromOpRom protocols that provide the interface between + the PCI bus driver/PCI Host Bridge Resource Allocation driver and a platform-specific + driver to describe the unique features of a platform. + This protocol is optional. + +Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is defined in UEFI Platform Initialization Specification 1.2 + Volume 5: Standards + +**/ + +#ifndef _PCI_PLATFORM_H_ +#define _PCI_PLATFORM_H_ + +/// +/// This file must be included because the EFI_PCI_PLATFORM_PROTOCOL uses +/// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE. +/// +#include <Protocol/PciHostBridgeResourceAllocation.h> + +/// +/// Global ID for the EFI_PCI_PLATFORM_PROTOCOL. +/// +#define EFI_PCI_PLATFORM_PROTOCOL_GUID \ + { \ + 0x7d75280, 0x27d4, 0x4d69, {0x90, 0xd0, 0x56, 0x43, 0xe2, 0x38, 0xb3, 0x41} \ + } + +/// +/// Forward declaration for EFI_PCI_PLATFORM_PROTOCOL. +/// +typedef struct _EFI_PCI_PLATFORM_PROTOCOL EFI_PCI_PLATFORM_PROTOCOL; + +/// +/// EFI_PCI_PLATFORM_POLICY that is a bitmask with the following legal combinations: +/// - EFI_RESERVE_NONE_IO_ALIAS:<BR> +/// Does not set aside either ISA or VGA I/O resources during PCI +/// enumeration. By using this selection, the platform indicates that it does +/// not want to support a PCI device that requires ISA or legacy VGA +/// resources. If a PCI device driver asks for these resources, the request +/// will be turned down. +/// - EFI_RESERVE_ISA_IO_ALIAS | EFI_RESERVE_VGA_IO_ALIAS:<BR> +/// Sets aside the ISA I/O range and all the aliases during PCI +/// enumeration. VGA I/O ranges and aliases are included in ISA alias +/// ranges. In this scheme, seventy-five percent of the I/O space remains unused. +/// By using this selection, the platform indicates that it wants to support +/// PCI devices that require the following, at the cost of wasted I/O space: +/// ISA range and its aliases +/// Legacy VGA range and its aliases +/// The PCI bus driver will not allocate I/O addresses out of the ISA I/O +/// range and its aliases. The following are the ISA I/O ranges: +/// - n100..n3FF +/// - n500..n7FF +/// - n900..nBFF +/// - nD00..nFFF +/// +/// In this case, the PCI bus driver will ask the PCI host bridge driver for +/// larger I/O ranges. The PCI host bridge driver is not aware of the ISA +/// aliasing policy and merely attempts to allocate the requested ranges. +/// The first device that requests the legacy VGA range will get all the +/// legacy VGA range plus its aliased addresses forwarded to it. The first +/// device that requests the legacy ISA range will get all the legacy ISA +/// range, plus its aliased addresses, forwarded to it. +/// - EFI_RESERVE_ISA_IO_NO_ALIAS | EFI_RESERVE_VGA_IO_ALIAS:<BR> +/// Sets aside the ISA I/O range (0x100 - 0x3FF) during PCI enumeration +/// and the aliases of the VGA I/O ranges. By using this selection, the +/// platform indicates that it will support VGA devices that require VGA +/// ranges, including those that require VGA aliases. The platform further +/// wants to support non-VGA devices that ask for the ISA range (0x100 - +/// 3FF), but not if it also asks for the ISA aliases. The PCI bus driver will +/// not allocate I/O addresses out of the legacy ISA I/O range (0x100 - +/// 0x3FF) range or the aliases of the VGA I/O range. If a PCI device +/// driver asks for the ISA I/O ranges, including aliases, the request will be +/// turned down. The first device that requests the legacy VGA range will +/// get all the legacy VGA range plus its aliased addresses forwarded to +/// it. When the legacy VGA device asks for legacy VGA ranges and its +/// aliases, all the upstream PCI-to-PCI bridges must be set up to perform +/// 10-bit decode on legacy VGA ranges. To prevent two bridges from +/// positively decoding the same address, all PCI-to-PCI bridges that are +/// peers to this bridge will have to be set up to not decode ISA aliased +/// ranges. In that case, all the devices behind the peer bridges can +/// occupy only I/O addresses that are not ISA aliases. This is a limitation +/// of PCI-to-PCI bridges and is described in the white paper PCI-to-PCI +/// Bridges and Card Bus Controllers on Windows 2000, Windows XP, +/// and Windows Server 2003. The PCI enumeration process must be +/// cognizant of this restriction. +/// - EFI_RESERVE_ISA_IO_NO_ALIAS | EFI_RESERVE_VGA_IO_NO_ALIAS:<BR> +/// Sets aside the ISA I/O range (0x100 - 0x3FF) during PCI enumeration. +/// VGA I/O ranges are included in the ISA range. By using this selection, +/// the platform indicates that it wants to support PCI devices that require +/// the ISA range and legacy VGA range, but it does not want to support +/// devices that require ISA alias ranges or VGA alias ranges. The PCI +/// bus driver will not allocate I/O addresses out of the legacy ISA I/O +/// range (0x100-0x3FF). If a PCI device driver asks for the ISA I/O +/// ranges, including aliases, the request will be turned down. By using +/// this selection, the platform indicates that it will support VGA devices +/// that require VGA ranges, but it will not support VGA devices that +/// require VGA aliases. To truly support 16-bit VGA decode, all the PCIto- +/// PCI bridges that are upstream to a VGA device, as well as +/// upstream to the parent PCI root bridge, must support 16-bit VGA I/O +/// decode. See the PCI-to-PCI Bridge Architecture Specification for +/// information regarding the 16-bit VGA decode support. This +/// requirement must hold true for every VGA device in the system. If any +/// of these bridges does not support 16-bit VGA decode, it will positively +/// decode all the aliases of the VGA I/O ranges and this selection must +/// be treated like EFI_RESERVE_ISA_IO_NO_ALIAS | +/// EFI_RESERVE_VGA_IO_ALIAS. +/// +typedef UINT32 EFI_PCI_PLATFORM_POLICY; + +/// +/// Does not set aside either ISA or VGA I/O resources during PCI +/// enumeration. +/// +#define EFI_RESERVE_NONE_IO_ALIAS 0x0000 + +/// +/// Sets aside ISA I/O range and all aliases: +/// - n100..n3FF +/// - n500..n7FF +/// - n900..nBFF +/// - nD00..nFFF. +/// +#define EFI_RESERVE_ISA_IO_ALIAS 0x0001 + +/// +/// Sets aside ISA I/O range 0x100-0x3FF. +/// +#define EFI_RESERVE_ISA_IO_NO_ALIAS 0x0002 + +/// +/// Sets aside VGA I/O ranges and all aliases. +/// +#define EFI_RESERVE_VGA_IO_ALIAS 0x0004 + +/// +/// Sets aside VGA I/O ranges +/// +#define EFI_RESERVE_VGA_IO_NO_ALIAS 0x0008 + +/// +/// EFI_PCI_EXECUTION_PHASE is used to call a platform protocol and execute +/// platform-specific code. +/// +typedef enum { + /// + /// The phase that indicates the entry point to the PCI Bus Notify phase. This + /// platform hook is called before the PCI bus driver calls the + /// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL driver. + /// + BeforePciHostBridge = 0, + /// + /// The phase that indicates the entry point to the PCI Bus Notify phase. This + /// platform hook is called before the PCI bus driver calls the + /// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL driver. + /// + ChipsetEntry = 0, + /// + /// The phase that indicates the exit point to the Chipset Notify phase before + /// returning to the PCI Bus Driver Notify phase. This platform hook is called after + /// the PCI bus driver calls the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + /// driver. + /// + AfterPciHostBridge = 1, + /// + /// The phase that indicates the exit point to the Chipset Notify phase before + /// returning to the PCI Bus Driver Notify phase. This platform hook is called after + /// the PCI bus driver calls the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + /// driver. + /// + ChipsetExit = 1, + MaximumChipsetPhase +} EFI_PCI_EXECUTION_PHASE; + +typedef EFI_PCI_EXECUTION_PHASE EFI_PCI_CHIPSET_EXECUTION_PHASE; + +/** + The notification from the PCI bus enumerator to the platform that it is + about to enter a certain phase during the enumeration process. + + The PlatformNotify() function can be used to notify the platform driver so that + it can perform platform-specific actions. No specific actions are required. + Eight notification points are defined at this time. More synchronization points + may be added as required in the future. The PCI bus driver calls the platform driver + twice for every Phase-once before the PCI Host Bridge Resource Allocation Protocol + driver is notified, and once after the PCI Host Bridge Resource Allocation Protocol + driver has been notified. + This member function may not perform any error checking on the input parameters. It + also does not return any error codes. If this member function detects any error condition, + it needs to handle those errors on its own because there is no way to surface any + errors to the caller. + + @param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL instance. + @param[in] HostBridge The handle of the host bridge controller. + @param[in] Phase The phase of the PCI bus enumeration. + @param[in] ExecPhase Defines the execution phase of the PCI chipset driver. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_PLATFORM_PHASE_NOTIFY)( + IN EFI_PCI_PLATFORM_PROTOCOL *This, + IN EFI_HANDLE HostBridge, + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase, + IN EFI_PCI_EXECUTION_PHASE ExecPhase + ); + +/** + The notification from the PCI bus enumerator to the platform for each PCI + controller at several predefined points during PCI controller initialization. + + The PlatformPrepController() function can be used to notify the platform driver so that + it can perform platform-specific actions. No specific actions are required. + Several notification points are defined at this time. More synchronization points may be + added as required in the future. The PCI bus driver calls the platform driver twice for + every PCI controller-once before the PCI Host Bridge Resource Allocation Protocol driver + is notified, and once after the PCI Host Bridge Resource Allocation Protocol driver has + been notified. + This member function may not perform any error checking on the input parameters. It also + does not return any error codes. If this member function detects any error condition, it + needs to handle those errors on its own because there is no way to surface any errors to + the caller. + + @param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL instance. + @param[in] HostBridge The associated PCI host bridge handle. + @param[in] RootBridge The associated PCI root bridge handle. + @param[in] PciAddress The address of the PCI device on the PCI bus. + @param[in] Phase The phase of the PCI controller enumeration. + @param[in] ExecPhase Defines the execution phase of the PCI chipset driver. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_PLATFORM_PREPROCESS_CONTROLLER)( + IN EFI_PCI_PLATFORM_PROTOCOL *This, + IN EFI_HANDLE HostBridge, + IN EFI_HANDLE RootBridge, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress, + IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase, + IN EFI_PCI_EXECUTION_PHASE ExecPhase + ); + +/** + Retrieves the platform policy regarding enumeration. + + The GetPlatformPolicy() function retrieves the platform policy regarding PCI + enumeration. The PCI bus driver and the PCI Host Bridge Resource Allocation Protocol + driver can call this member function to retrieve the policy. + + @param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL instance. + @param[out] PciPolicy The platform policy with respect to VGA and ISA aliasing. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER PciPolicy is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_PLATFORM_GET_PLATFORM_POLICY)( + IN CONST EFI_PCI_PLATFORM_PROTOCOL *This, + OUT EFI_PCI_PLATFORM_POLICY *PciPolicy + ); + +/** + Gets the PCI device's option ROM from a platform-specific location. + + The GetPciRom() function gets the PCI device's option ROM from a platform-specific location. + The option ROM will be loaded into memory. This member function is used to return an image + that is packaged as a PCI 2.2 option ROM. The image may contain both legacy and EFI option + ROMs. See the UEFI 2.0 Specification for details. This member function can be used to return + option ROM images for embedded controllers. Option ROMs for embedded controllers are typically + stored in platform-specific storage, and this member function can retrieve it from that storage + and return it to the PCI bus driver. The PCI bus driver will call this member function before + scanning the ROM that is attached to any controller, which allows a platform to specify a ROM + image that is different from the ROM image on a PCI card. + + @param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL instance. + @param[in] PciHandle The handle of the PCI device. + @param[out] RomImage If the call succeeds, the pointer to the pointer to the option ROM image. + Otherwise, this field is undefined. The memory for RomImage is allocated + by EFI_PCI_PLATFORM_PROTOCOL.GetPciRom() using the EFI Boot Service AllocatePool(). + It is the caller's responsibility to free the memory using the EFI Boot Service + FreePool(), when the caller is done with the option ROM. + @param[out] RomSize If the call succeeds, a pointer to the size of the option ROM size. Otherwise, + this field is undefined. + + @retval EFI_SUCCESS The option ROM was available for this device and loaded into memory. + @retval EFI_NOT_FOUND No option ROM was available for this device. + @retval EFI_OUT_OF_RESOURCES No memory was available to load the option ROM. + @retval EFI_DEVICE_ERROR An error occurred in obtaining the option ROM. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_PLATFORM_GET_PCI_ROM)( + IN CONST EFI_PCI_PLATFORM_PROTOCOL *This, + IN EFI_HANDLE PciHandle, + OUT VOID **RomImage, + OUT UINTN *RomSize + ); + +/// +/// This protocol provides the interface between the PCI bus driver/PCI Host +/// Bridge Resource Allocation driver and a platform-specific driver to describe +/// the unique features of a platform. +/// +struct _EFI_PCI_PLATFORM_PROTOCOL { + /// + /// The notification from the PCI bus enumerator to the platform that it is about to + /// enter a certain phase during the enumeration process. + /// + EFI_PCI_PLATFORM_PHASE_NOTIFY PlatformNotify; + /// + /// The notification from the PCI bus enumerator to the platform for each PCI + /// controller at several predefined points during PCI controller initialization. + /// + EFI_PCI_PLATFORM_PREPROCESS_CONTROLLER PlatformPrepController; + /// + /// Retrieves the platform policy regarding enumeration. + /// + EFI_PCI_PLATFORM_GET_PLATFORM_POLICY GetPlatformPolicy; + /// + /// Gets the PCI device's option ROM from a platform-specific location. + /// + EFI_PCI_PLATFORM_GET_PCI_ROM GetPciRom; +}; + +extern EFI_GUID gEfiPciPlatformProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/PciRootBridgeIo.h b/sys/contrib/edk2/Include/Protocol/PciRootBridgeIo.h new file mode 100644 index 000000000000..0077548ed305 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/PciRootBridgeIo.h @@ -0,0 +1,436 @@ +/** @file + PCI Root Bridge I/O protocol as defined in the UEFI 2.0 specification. + + PCI Root Bridge I/O protocol is used by PCI Bus Driver to perform PCI Memory, PCI I/O, + and PCI Configuration cycles on a PCI Root Bridge. It also provides services to perform + defferent types of bus mastering DMA. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PCI_ROOT_BRIDGE_IO_H__ +#define __PCI_ROOT_BRIDGE_IO_H__ + +#include <Library/BaseLib.h> + +#define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID \ + { \ + 0x2f707ebb, 0x4a1a, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +typedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL; + +/// +/// ******************************************************* +/// EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH +/// ******************************************************* +/// +typedef enum { + EfiPciWidthUint8, + EfiPciWidthUint16, + EfiPciWidthUint32, + EfiPciWidthUint64, + EfiPciWidthFifoUint8, + EfiPciWidthFifoUint16, + EfiPciWidthFifoUint32, + EfiPciWidthFifoUint64, + EfiPciWidthFillUint8, + EfiPciWidthFillUint16, + EfiPciWidthFillUint32, + EfiPciWidthFillUint64, + EfiPciWidthMaximum +} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH; + +/// +/// ******************************************************* +/// EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION +/// ******************************************************* +/// +typedef enum { + /// + /// A read operation from system memory by a bus master that is not capable of producing + /// PCI dual address cycles. + /// + EfiPciOperationBusMasterRead, + /// + /// A write operation from system memory by a bus master that is not capable of producing + /// PCI dual address cycles. + /// + EfiPciOperationBusMasterWrite, + /// + /// Provides both read and write access to system memory by both the processor and a bus + /// master that is not capable of producing PCI dual address cycles. + /// + EfiPciOperationBusMasterCommonBuffer, + /// + /// A read operation from system memory by a bus master that is capable of producing PCI + /// dual address cycles. + /// + EfiPciOperationBusMasterRead64, + /// + /// A write operation to system memory by a bus master that is capable of producing PCI + /// dual address cycles. + /// + EfiPciOperationBusMasterWrite64, + /// + /// Provides both read and write access to system memory by both the processor and a bus + /// master that is capable of producing PCI dual address cycles. + /// + EfiPciOperationBusMasterCommonBuffer64, + EfiPciOperationMaximum +} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION; + +#define EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO 0x0001 +#define EFI_PCI_ATTRIBUTE_ISA_IO 0x0002 +#define EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO 0x0004 +#define EFI_PCI_ATTRIBUTE_VGA_MEMORY 0x0008 +#define EFI_PCI_ATTRIBUTE_VGA_IO 0x0010 +#define EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO 0x0020 +#define EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO 0x0040 +#define EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080 +#define EFI_PCI_ATTRIBUTE_MEMORY_CACHED 0x0800 +#define EFI_PCI_ATTRIBUTE_MEMORY_DISABLE 0x1000 +#define EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000 +#define EFI_PCI_ATTRIBUTE_ISA_IO_16 0x10000 +#define EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000 +#define EFI_PCI_ATTRIBUTE_VGA_IO_16 0x40000 + +#define EFI_PCI_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER (EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED | EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) + +#define EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER (~EFI_PCI_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER) + +#define EFI_PCI_ADDRESS(bus, dev, func, reg) \ + (UINT64) ( \ + (((UINTN) bus) << 24) | \ + (((UINTN) dev) << 16) | \ + (((UINTN) func) << 8) | \ + (((UINTN) (reg)) < 256 ? ((UINTN) (reg)) : (UINT64) (LShiftU64 ((UINT64) (reg), 32)))) + +typedef struct { + UINT8 Register; + UINT8 Function; + UINT8 Device; + UINT8 Bus; + UINT32 ExtendedRegister; +} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS; + +/** + Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is + satisfied or after a defined duration. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Width Signifies the width of the memory or I/O operations. + @param Address The base address of the memory or I/O operations. + @param Mask Mask used for the polling criteria. + @param Value The comparison value used for the polling exit criteria. + @param Delay The number of 100 ns units to poll. + @param Result Pointer to the last value read from the memory location. + + @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria. + @retval EFI_TIMEOUT Delay expired before a match occurred. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM)( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ); + +/** + Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Width Signifies the width of the memory operations. + @param Address The base address of the memory operations. + @param Count The number of memory operations to perform. + @param Buffer For read operations, the destination buffer to store the results. For write + operations, the source buffer to write data from. + + @retval EFI_SUCCESS The data was read from or written to the PCI root bridge. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM)( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +typedef struct { + /// + /// Read PCI controller registers in the PCI root bridge memory space. + /// + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Read; + /// + /// Write PCI controller registers in the PCI root bridge memory space. + /// + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Write; +} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS; + +/** + Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI + root bridge memory space. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance. + @param Width Signifies the width of the memory operations. + @param DestAddress The destination address of the memory operation. + @param SrcAddress The source address of the memory operation. + @param Count The number of memory operations to perform. + + @retval EFI_SUCCESS The data was copied from one memory region to another memory region. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM)( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 DestAddress, + IN UINT64 SrcAddress, + IN UINTN Count + ); + +/** + Provides the PCI controller-specific addresses required to access system memory from a + DMA bus master. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Operation Indicates if the bus master is going to read or write to system memory. + @param HostAddress The system memory address to map to the PCI controller. + @param NumberOfBytes On input the number of bytes to map. On output the number of bytes + that were mapped. + @param DeviceAddress The resulting map address for the bus master PCI controller to use to + access the hosts HostAddress. + @param Mapping A resulting value to pass to Unmap(). + + @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP)( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ); + +/** + Completes the Map() operation and releases any corresponding resources. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Mapping The mapping value returned from Map(). + + @retval EFI_SUCCESS The range was unmapped. + @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map(). + @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP)( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN VOID *Mapping + ); + +/** + Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or + EfiPciOperationBusMasterCommonBuffer64 mapping. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Type This parameter is not used and must be ignored. + @param MemoryType The type of memory to allocate, EfiBootServicesData or + EfiRuntimeServicesData. + @param Pages The number of pages to allocate. + @param HostAddress A pointer to store the base system memory address of the + allocated range. + @param Attributes The requested bit mask of attributes for the allocated range. + + @retval EFI_SUCCESS The requested memory pages were allocated. + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are + MEMORY_WRITE_COMBINE and MEMORY_CACHED. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER)( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT VOID **HostAddress, + IN UINT64 Attributes + ); + +/** + Frees memory that was allocated with AllocateBuffer(). + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Pages The number of pages to free. + @param HostAddress The base system memory address of the allocated range. + + @retval EFI_SUCCESS The requested memory pages were freed. + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages + was not allocated with AllocateBuffer(). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER)( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress + ); + +/** + Flushes all PCI posted write transactions from a PCI host bridge to system memory. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + + @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host + bridge to system memory. + @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI + host bridge due to a hardware error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH)( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This + ); + +/** + Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the + attributes that a PCI root bridge is currently using. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Supports A pointer to the mask of attributes that this PCI root bridge supports + setting with SetAttributes(). + @param Attributes A pointer to the mask of attributes that this PCI root bridge is currently + using. + + @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI root + bridge supports is returned in Supports. If Attributes is + not NULL, then the attributes that the PCI root bridge is currently + using is returned in Attributes. + @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL. + + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES)( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + OUT UINT64 *Supports, + OUT UINT64 *Attributes + ); + +/** + Sets attributes for a resource range on a PCI root bridge. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Attributes The mask of attributes to set. + @param ResourceBase A pointer to the base address of the resource range to be modified by the + attributes specified by Attributes. + @param ResourceLength A pointer to the length of the resource range to be modified by the + attributes specified by Attributes. + + @retval EFI_SUCCESS The set of attributes specified by Attributes for the resource + range specified by ResourceBase and ResourceLength + were set on the PCI root bridge, and the actual resource range is + returned in ResuourceBase and ResourceLength. + @retval EFI_UNSUPPORTED A bit is set in Attributes that is not supported by the PCI Root + Bridge. + @retval EFI_OUT_OF_RESOURCES There are not enough resources to set the attributes on the + resource range specified by BaseAddress and Length. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES)( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN UINT64 Attributes, + IN OUT UINT64 *ResourceBase, + IN OUT UINT64 *ResourceLength + ); + +/** + Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI + resource descriptors. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Resources A pointer to the resource descriptors that describe the current + configuration of this PCI root bridge. + + @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in + Resources. + @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be + retrieved. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION)( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + OUT VOID **Resources + ); + +/// +/// Provides the basic Memory, I/O, PCI configuration, and DMA interfaces that are +/// used to abstract accesses to PCI controllers behind a PCI Root Bridge Controller. +/// +struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL { + /// + /// The EFI_HANDLE of the PCI Host Bridge of which this PCI Root Bridge is a member. + /// + EFI_HANDLE ParentHandle; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollMem; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollIo; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Mem; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Io; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Pci; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM CopyMem; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP Map; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP Unmap; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER FreeBuffer; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH Flush; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES GetAttributes; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES SetAttributes; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION Configuration; + + /// + /// The segment number that this PCI root bridge resides. + /// + UINT32 SegmentNumber; +}; + +extern EFI_GUID gEfiPciRootBridgeIoProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/PiPcd.h b/sys/contrib/edk2/Include/Protocol/PiPcd.h new file mode 100644 index 000000000000..f4d8061f0100 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/PiPcd.h @@ -0,0 +1,418 @@ +/** @file + Platform Configuration Database (PCD) Protocol defined in PI 1.2 Vol3 + + A platform database that contains a variety of current platform settings or + directives that can be accessed by a driver or application. + PI PCD protocol only provide the accessing interfaces for Dynamic-Ex type PCD. + + Callers to this protocol must be at a TPL_APPLICATION task priority level. + This is the base PCD service API that provides an abstraction for accessing configuration content in + the platform. It a seamless mechanism for extracting information regardless of where the + information is stored (such as in Read-only data, or an EFI Variable). + This protocol allows access to data through size-granular APIs and provides a mechanism for a + firmware component to monitor specific settings and be alerted when a setting is changed. + + Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + PI Version 1.2 Vol 3. +**/ + +#ifndef __PI_PCD_H__ +#define __PI_PCD_H__ + +extern EFI_GUID gEfiPcdProtocolGuid; + +#define EFI_PCD_PROTOCOL_GUID \ + { 0x13a3f0f6, 0x264a, 0x3ef0, { 0xf2, 0xe0, 0xde, 0xc5, 0x12, 0x34, 0x2f, 0x34 } } + +#define EFI_PCD_INVALID_TOKEN_NUMBER ((UINTN) 0) + +/** + SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values. SetSku() is + normally called only once by the system. + For each item (token), the database can hold a single value that applies to all SKUs, or multiple + values, where each value is associated with a specific SKU Id. Items with multiple, SKU-specific + values are called SKU enabled. + The SKU Id of zero is reserved as a default. The valid SkuId range is 1 to 255. For tokens that are + not SKU enabled, the system ignores any set SKU Id and works with the single value for that token. + For SKU-enabled tokens, the system will use the SKU Id set by the last call to SetSku(). If no SKU + Id is set or the currently set SKU Id isn't valid for the specified token, the system uses the default + SKU Id. If the system attempts to use the default SKU Id and no value has been set for that Id, the + results are unpredictable. + + @param[in] SkuId The SKU value to set. +**/ +typedef +VOID +(EFIAPI *EFI_PCD_PROTOCOL_SET_SKU)( + IN UINTN SkuId + ); + +/** + Retrieves an 8-bit value for a given PCD token. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + + @return 8-bit value for a given PCD token. +**/ +typedef +UINT8 +(EFIAPI *EFI_PCD_PROTOCOL_GET_8)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves the current word-sized value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + + @return word-sized value for a given PCD token. +**/ +typedef +UINT16 +(EFIAPI *EFI_PCD_PROTOCOL_GET_16)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves the current 32-bit sized value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + + @return 32-bit value for a given PCD token. +**/ +typedef +UINT32 +(EFIAPI *EFI_PCD_PROTOCOL_GET_32)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves the 64-bit sized value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + + @return 64-bit value for a given PCD token. + +**/ +typedef +UINT64 +(EFIAPI *EFI_PCD_PROTOCOL_GET_64)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves the current pointer to the value for a PCD token number. Do not make any assumptions + about the alignment of the pointer that is returned by this function call. If the TokenNumber is + invalid, the results are unpredictable. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + + @return pointer to a value for a given PCD token. +**/ +typedef +VOID * +(EFIAPI *EFI_PCD_PROTOCOL_GET_POINTER)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves the current BOOLEAN-sized value for a PCD token number. If the TokenNumber is + invalid, the results are unpredictable. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + + @return Boolean value for a given PCD token. +**/ +typedef +BOOLEAN +(EFIAPI *EFI_PCD_PROTOCOL_GET_BOOLEAN)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves the current size of a particular PCD token. If the TokenNumber is invalid, the results are + unpredictable. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + + @return the size of the value for a given PCD token. +**/ +typedef +UINTN +(EFIAPI *EFI_PCD_PROTOCOL_GET_SIZE)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Sets an 8-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the size of the value being set is + compatible with the Token's existing definition. If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The PCD service has set the value requested + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was + incompatible with a call to this function. Use GetSizeEx() to + retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCD_PROTOCOL_SET_8)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT8 Value + ); + +/** + Sets an 16-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the size of the value being set is + compatible with the Token's existing definition. If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The PCD service has set the value requested + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was + incompatible with a call to this function. Use GetSizeEx() to + retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCD_PROTOCOL_SET_16)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT16 Value + ); + +/** + Sets an 32-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the size of the value being set is + compatible with the Token's existing definition. If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The PCD service has set the value requested + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was + incompatible with a call to this function. Use GetSizeEx() to + retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCD_PROTOCOL_SET_32)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT32 Value + ); + +/** + Sets an 64-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the size of the value being set is + compatible with the Token's existing definition. If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The PCD service has set the value requested + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was + incompatible with a call to this function. Use GetSizeEx() to + retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCD_PROTOCOL_SET_64)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT64 Value + ); + +/** + Sets a value of a specified size for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the size of the value being set is + compatible with the Token's existing definition. If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] SizeOfValue The length of the value being set for the PCD token. If too large of a length is + specified, upon return from this function the value of SizeOfValue will + reflect the maximum size for the PCD token. + @param[in] Buffer A pointer to the buffer containing the value to set for the PCD token. + + @retval EFI_SUCCESS The PCD service has set the value requested + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was + incompatible with a call to this function. Use GetSizeEx() to + retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCD_PROTOCOL_SET_POINTER)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN OUT UINTN *SizeOfValue, + IN VOID *Buffer + ); + +/** + Sets a Boolean value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the size of the value being set is + compatible with the Token's existing definition. If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS The PCD service has set the value requested + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data being set was + incompatible with a call to this function. Use GetSizeEx() to + retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCD_PROTOCOL_SET_BOOLEAN)( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN BOOLEAN Value + ); + +typedef +VOID +(EFIAPI *EFI_PCD_PROTOCOL_CALLBACK)( + IN EFI_GUID *Guid OPTIONAL, + IN UINTN CallBackToken, + IN OUT VOID *TokenData, + IN UINTN TokenDataSize + ); + +/** + Specifies a function to be called anytime the value of a designated token is changed. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] CallBackToken The PCD token number to monitor. + @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call event for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCD_PROTOCOL_CALLBACK_ON_SET)( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN CallBackToken, + IN EFI_PCD_PROTOCOL_CALLBACK CallBackFunction + ); + +/** + Cancels a callback function that was set through a previous call to the CallBackOnSet function. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] CallBackToken The PCD token number to monitor. + @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call event for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCD_PROTOCOL_CANCEL_CALLBACK)( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN CallBackToken, + IN EFI_PCD_PROTOCOL_CALLBACK CallBackFunction + ); + +/** + Gets the next valid token number in a given namespace. This is useful since the PCD infrastructure + contains a sparse list of token numbers, and one cannot a priori know what token numbers are valid + in the database. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to retrieve the next token. + @param[in] TokenNumber A pointer to the PCD token number to use to find the subsequent token number. To + retrieve the "first" token, have the pointer reference a TokenNumber value of 0. + @retval EFI_SUCCESS The PCD service has retrieved the value requested + @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCD_PROTOCOL_GET_NEXT_TOKEN)( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN *TokenNumber + ); + +/** + Gets the next valid token namespace for a given namespace. This is useful to traverse the valid + token namespaces on a platform. + + @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token namespace + from which the search will start. On output, it designates the next valid token + namespace on the platform. If *Guid is NULL, then the GUID of the first token + space of the current platform is returned. If the search cannot locate the next valid + token namespace, an error is returned and the value of *Guid is undefined. + + @retval EFI_SUCCESS The PCD service retrieved the value requested. + @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PCD_PROTOCOL_GET_NEXT_TOKEN_SPACE)( + IN OUT CONST EFI_GUID **Guid + ); + +typedef struct _EFI_PCD_PROTOCOL { + EFI_PCD_PROTOCOL_SET_SKU SetSku; + EFI_PCD_PROTOCOL_GET_8 Get8; + EFI_PCD_PROTOCOL_GET_16 Get16; + EFI_PCD_PROTOCOL_GET_32 Get32; + EFI_PCD_PROTOCOL_GET_64 Get64; + EFI_PCD_PROTOCOL_GET_POINTER GetPtr; + EFI_PCD_PROTOCOL_GET_BOOLEAN GetBool; + EFI_PCD_PROTOCOL_GET_SIZE GetSize; + EFI_PCD_PROTOCOL_SET_8 Set8; + EFI_PCD_PROTOCOL_SET_16 Set16; + EFI_PCD_PROTOCOL_SET_32 Set32; + EFI_PCD_PROTOCOL_SET_64 Set64; + EFI_PCD_PROTOCOL_SET_POINTER SetPtr; + EFI_PCD_PROTOCOL_SET_BOOLEAN SetBool; + EFI_PCD_PROTOCOL_CALLBACK_ON_SET CallbackOnSet; + EFI_PCD_PROTOCOL_CANCEL_CALLBACK CancelCallback; + EFI_PCD_PROTOCOL_GET_NEXT_TOKEN GetNextToken; + EFI_PCD_PROTOCOL_GET_NEXT_TOKEN_SPACE GetNextTokenSpace; +} EFI_PCD_PROTOCOL; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/PxeBaseCode.h b/sys/contrib/edk2/Include/Protocol/PxeBaseCode.h new file mode 100644 index 000000000000..e01f6fed71e7 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/PxeBaseCode.h @@ -0,0 +1,933 @@ +/** @file + EFI PXE Base Code Protocol definitions, which is used to access PXE-compatible + devices for network access and network booting. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> +Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in EFI Specification 1.10. + +**/ + +#ifndef __PXE_BASE_CODE_PROTOCOL_H__ +#define __PXE_BASE_CODE_PROTOCOL_H__ + +/// +/// PXE Base Code protocol. +/// +#define EFI_PXE_BASE_CODE_PROTOCOL_GUID \ + { \ + 0x03c4e603, 0xac28, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +typedef struct _EFI_PXE_BASE_CODE_PROTOCOL EFI_PXE_BASE_CODE_PROTOCOL; + +/// +/// Protocol defined in EFI1.1. +/// +typedef EFI_PXE_BASE_CODE_PROTOCOL EFI_PXE_BASE_CODE; + +/// +/// Default IP TTL and ToS. +/// +#define DEFAULT_TTL 64 +#define DEFAULT_ToS 0 + +/// +/// ICMP error format. +/// +typedef struct { + UINT8 Type; + UINT8 Code; + UINT16 Checksum; + union { + UINT32 reserved; + UINT32 Mtu; + UINT32 Pointer; + struct { + UINT16 Identifier; + UINT16 Sequence; + } Echo; + } u; + UINT8 Data[494]; +} EFI_PXE_BASE_CODE_ICMP_ERROR; + +/// +/// TFTP error format. +/// +typedef struct { + UINT8 ErrorCode; + CHAR8 ErrorString[127]; +} EFI_PXE_BASE_CODE_TFTP_ERROR; + +/// +/// IP Receive Filter definitions. +/// +#define EFI_PXE_BASE_CODE_MAX_IPCNT 8 + +/// +/// IP Receive Filter structure. +/// +typedef struct { + UINT8 Filters; + UINT8 IpCnt; + UINT16 reserved; + EFI_IP_ADDRESS IpList[EFI_PXE_BASE_CODE_MAX_IPCNT]; +} EFI_PXE_BASE_CODE_IP_FILTER; + +#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP 0x0001 +#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST 0x0002 +#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS 0x0004 +#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST 0x0008 + +/// +/// ARP cache entries. +/// +typedef struct { + EFI_IP_ADDRESS IpAddr; + EFI_MAC_ADDRESS MacAddr; +} EFI_PXE_BASE_CODE_ARP_ENTRY; + +/// +/// ARP route table entries. +/// +typedef struct { + EFI_IP_ADDRESS IpAddr; + EFI_IP_ADDRESS SubnetMask; + EFI_IP_ADDRESS GwAddr; +} EFI_PXE_BASE_CODE_ROUTE_ENTRY; + +// +// UDP definitions +// +typedef UINT16 EFI_PXE_BASE_CODE_UDP_PORT; + +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP 0x0001 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT 0x0002 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP 0x0004 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT 0x0008 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER 0x0010 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT 0x0020 + +// +// Discover() definitions +// +#define EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP 0 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_MS_WINNT_RIS 1 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_INTEL_LCM 2 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_DOSUNDI 3 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_NEC_ESMPRO 4 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_WSoD 5 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_LCCM 6 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_CA_UNICENTER_TNG 7 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_HP_OPENVIEW 8 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_9 9 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_10 10 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_11 11 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_NOT_USED_12 12 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_INSTALL 13 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_BOOT 14 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REMBO 15 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_BEOBOOT 16 +// +// 17 through 32767 are reserved +// 32768 through 65279 are for vendor use +// 65280 through 65534 are reserved +// +#define EFI_PXE_BASE_CODE_BOOT_TYPE_PXETEST 65535 + +#define EFI_PXE_BASE_CODE_BOOT_LAYER_MASK 0x7FFF +#define EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL 0x0000 + +// +// PXE Tag definition that identifies the processor +// and programming environment of the client system. +// These identifiers are defined by IETF: +// http://www.ietf.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml +// +#if defined (MDE_CPU_IA32) +#define EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE 0x0006 +#elif defined (MDE_CPU_X64) +#define EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE 0x0007 +#elif defined (MDE_CPU_ARM) +#define EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE 0x000A +#elif defined (MDE_CPU_AARCH64) +#define EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE 0x000B +#elif defined (MDE_CPU_RISCV64) +#define EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE 0x001B +#elif defined (MDE_CPU_LOONGARCH64) +#define EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE 0x0027 +#endif + +/// +/// Discover() server list structure. +/// +typedef struct { + UINT16 Type; + BOOLEAN AcceptAnyResponse; + UINT8 Reserved; + EFI_IP_ADDRESS IpAddr; +} EFI_PXE_BASE_CODE_SRVLIST; + +/// +/// Discover() information override structure. +/// +typedef struct { + BOOLEAN UseMCast; + BOOLEAN UseBCast; + BOOLEAN UseUCast; + BOOLEAN MustUseList; + EFI_IP_ADDRESS ServerMCastIp; + UINT16 IpCnt; + EFI_PXE_BASE_CODE_SRVLIST SrvList[1]; +} EFI_PXE_BASE_CODE_DISCOVER_INFO; + +/// +/// TFTP opcode definitions. +/// +typedef enum { + EFI_PXE_BASE_CODE_TFTP_FIRST, + EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, + EFI_PXE_BASE_CODE_TFTP_READ_FILE, + EFI_PXE_BASE_CODE_TFTP_WRITE_FILE, + EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY, + EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE, + EFI_PXE_BASE_CODE_MTFTP_READ_FILE, + EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY, + EFI_PXE_BASE_CODE_MTFTP_LAST +} EFI_PXE_BASE_CODE_TFTP_OPCODE; + +/// +/// MTFTP information. This information is required +/// to start or join a multicast TFTP session. It is also required to +/// perform the "get file size" and "read directory" operations of MTFTP. +/// +typedef struct { + EFI_IP_ADDRESS MCastIp; + EFI_PXE_BASE_CODE_UDP_PORT CPort; + EFI_PXE_BASE_CODE_UDP_PORT SPort; + UINT16 ListenTimeout; + UINT16 TransmitTimeout; +} EFI_PXE_BASE_CODE_MTFTP_INFO; + +/// +/// DHCPV4 Packet structure. +/// +typedef struct { + UINT8 BootpOpcode; + UINT8 BootpHwType; + UINT8 BootpHwAddrLen; + UINT8 BootpGateHops; + UINT32 BootpIdent; + UINT16 BootpSeconds; + UINT16 BootpFlags; + UINT8 BootpCiAddr[4]; + UINT8 BootpYiAddr[4]; + UINT8 BootpSiAddr[4]; + UINT8 BootpGiAddr[4]; + UINT8 BootpHwAddr[16]; + UINT8 BootpSrvName[64]; + UINT8 BootpBootFile[128]; + UINT32 DhcpMagik; + UINT8 DhcpOptions[56]; +} EFI_PXE_BASE_CODE_DHCPV4_PACKET; + +/// +/// DHCPV6 Packet structure. +/// +typedef struct { + UINT32 MessageType : 8; + UINT32 TransactionId : 24; + UINT8 DhcpOptions[1024]; +} EFI_PXE_BASE_CODE_DHCPV6_PACKET; + +/// +/// Packet structure. +/// +typedef union { + UINT8 Raw[1472]; + EFI_PXE_BASE_CODE_DHCPV4_PACKET Dhcpv4; + EFI_PXE_BASE_CODE_DHCPV6_PACKET Dhcpv6; +} EFI_PXE_BASE_CODE_PACKET; + +// +// PXE Base Code Mode structure +// +#define EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES 8 +#define EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES 8 + +/// +/// EFI_PXE_BASE_CODE_MODE. +/// The data values in this structure are read-only and +/// are updated by the code that produces the +/// EFI_PXE_BASE_CODE_PROTOCOL functions. +/// +typedef struct { + BOOLEAN Started; + BOOLEAN Ipv6Available; + BOOLEAN Ipv6Supported; + BOOLEAN UsingIpv6; + BOOLEAN BisSupported; + BOOLEAN BisDetected; + BOOLEAN AutoArp; + BOOLEAN SendGUID; + BOOLEAN DhcpDiscoverValid; + BOOLEAN DhcpAckReceived; + BOOLEAN ProxyOfferReceived; + BOOLEAN PxeDiscoverValid; + BOOLEAN PxeReplyReceived; + BOOLEAN PxeBisReplyReceived; + BOOLEAN IcmpErrorReceived; + BOOLEAN TftpErrorReceived; + BOOLEAN MakeCallbacks; + UINT8 TTL; + UINT8 ToS; + EFI_IP_ADDRESS StationIp; + EFI_IP_ADDRESS SubnetMask; + EFI_PXE_BASE_CODE_PACKET DhcpDiscover; + EFI_PXE_BASE_CODE_PACKET DhcpAck; + EFI_PXE_BASE_CODE_PACKET ProxyOffer; + EFI_PXE_BASE_CODE_PACKET PxeDiscover; + EFI_PXE_BASE_CODE_PACKET PxeReply; + EFI_PXE_BASE_CODE_PACKET PxeBisReply; + EFI_PXE_BASE_CODE_IP_FILTER IpFilter; + UINT32 ArpCacheEntries; + EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache[EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES]; + UINT32 RouteTableEntries; + EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable[EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES]; + EFI_PXE_BASE_CODE_ICMP_ERROR IcmpError; + EFI_PXE_BASE_CODE_TFTP_ERROR TftpError; +} EFI_PXE_BASE_CODE_MODE; + +// +// PXE Base Code Interface Function definitions +// + +/** + Enables the use of the PXE Base Code Protocol functions. + + This function enables the use of the PXE Base Code Protocol functions. If the + Started field of the EFI_PXE_BASE_CODE_MODE structure is already TRUE, then + EFI_ALREADY_STARTED will be returned. If UseIpv6 is TRUE, then IPv6 formatted + addresses will be used in this session. If UseIpv6 is FALSE, then IPv4 formatted + addresses will be used in this session. If UseIpv6 is TRUE, and the Ipv6Supported + field of the EFI_PXE_BASE_CODE_MODE structure is FALSE, then EFI_UNSUPPORTED will + be returned. If there is not enough memory or other resources to start the PXE + Base Code Protocol, then EFI_OUT_OF_RESOURCES will be returned. Otherwise, the + PXE Base Code Protocol will be started, and all of the fields of the EFI_PXE_BASE_CODE_MODE + structure will be initialized as follows: + StartedSet to TRUE. + Ipv6SupportedUnchanged. + Ipv6AvailableUnchanged. + UsingIpv6Set to UseIpv6. + BisSupportedUnchanged. + BisDetectedUnchanged. + AutoArpSet to TRUE. + SendGUIDSet to FALSE. + TTLSet to DEFAULT_TTL. + ToSSet to DEFAULT_ToS. + DhcpCompletedSet to FALSE. + ProxyOfferReceivedSet to FALSE. + StationIpSet to an address of all zeros. + SubnetMaskSet to a subnet mask of all zeros. + DhcpDiscoverZero-filled. + DhcpAckZero-filled. + ProxyOfferZero-filled. + PxeDiscoverValidSet to FALSE. + PxeDiscoverZero-filled. + PxeReplyValidSet to FALSE. + PxeReplyZero-filled. + PxeBisReplyValidSet to FALSE. + PxeBisReplyZero-filled. + IpFilterSet the Filters field to 0 and the IpCnt field to 0. + ArpCacheEntriesSet to 0. + ArpCacheZero-filled. + RouteTableEntriesSet to 0. + RouteTableZero-filled. + IcmpErrorReceivedSet to FALSE. + IcmpErrorZero-filled. + TftpErroReceivedSet to FALSE. + TftpErrorZero-filled. + MakeCallbacksSet to TRUE if the PXE Base Code Callback Protocol is available. + Set to FALSE if the PXE Base Code Callback Protocol is not available. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + @param UseIpv6 Specifies the type of IP addresses that are to be used during the session + that is being started. Set to TRUE for IPv6 addresses, and FALSE for + IPv4 addresses. + + @retval EFI_SUCCESS The PXE Base Code Protocol was started. + @retval EFI_DEVICE_ERROR The network device encountered an error during this oper + @retval EFI_UNSUPPORTED UseIpv6 is TRUE, but the Ipv6Supported field of the + EFI_PXE_BASE_CODE_MODE structure is FALSE. + @retval EFI_ALREADY_STARTED The PXE Base Code Protocol is already in the started state. + @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid + EFI_PXE_BASE_CODE_PROTOCOL structure. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough memory or other resources to start the + PXE Base Code Protocol. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_START)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN BOOLEAN UseIpv6 + ); + +/** + Disables the use of the PXE Base Code Protocol functions. + + This function stops all activity on the network device. All the resources allocated + in Start() are released, the Started field of the EFI_PXE_BASE_CODE_MODE structure is + set to FALSE and EFI_SUCCESS is returned. If the Started field of the EFI_PXE_BASE_CODE_MODE + structure is already FALSE, then EFI_NOT_STARTED will be returned. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + + @retval EFI_SUCCESS The PXE Base Code Protocol was stopped. + @retval EFI_NOT_STARTED The PXE Base Code Protocol is already in the stopped state. + @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid + EFI_PXE_BASE_CODE_PROTOCOL structure. + @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_STOP)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This + ); + +/** + Attempts to complete a DHCPv4 D.O.R.A. (discover / offer / request / acknowledge) or DHCPv6 + S.A.R.R (solicit / advertise / request / reply) sequence. + + This function attempts to complete the DHCP sequence. If this sequence is completed, + then EFI_SUCCESS is returned, and the DhcpCompleted, ProxyOfferReceived, StationIp, + SubnetMask, DhcpDiscover, DhcpAck, and ProxyOffer fields of the EFI_PXE_BASE_CODE_MODE + structure are filled in. + If SortOffers is TRUE, then the cached DHCP offer packets will be sorted before + they are tried. If SortOffers is FALSE, then the cached DHCP offer packets will + be tried in the order in which they are received. Please see the Preboot Execution + Environment (PXE) Specification for additional details on the implementation of DHCP. + This function can take at least 31 seconds to timeout and return control to the + caller. If the DHCP sequence does not complete, then EFI_TIMEOUT will be returned. + If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, + then the DHCP sequence will be stopped and EFI_ABORTED will be returned. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + @param SortOffers TRUE if the offers received should be sorted. Set to FALSE to try the + offers in the order that they are received. + + @retval EFI_SUCCESS Valid DHCP has completed. + @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. + @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid + EFI_PXE_BASE_CODE_PROTOCOL structure. + @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough memory to complete the DHCP Protocol. + @retval EFI_ABORTED The callback function aborted the DHCP Protocol. + @retval EFI_TIMEOUT The DHCP Protocol timed out. + @retval EFI_ICMP_ERROR An ICMP error packet was received during the DHCP session. + @retval EFI_NO_RESPONSE Valid PXE offer was not received. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_DHCP)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN BOOLEAN SortOffers + ); + +/** + Attempts to complete the PXE Boot Server and/or boot image discovery sequence. + + This function attempts to complete the PXE Boot Server and/or boot image discovery + sequence. If this sequence is completed, then EFI_SUCCESS is returned, and the + PxeDiscoverValid, PxeDiscover, PxeReplyReceived, and PxeReply fields of the + EFI_PXE_BASE_CODE_MODE structure are filled in. If UseBis is TRUE, then the + PxeBisReplyReceived and PxeBisReply fields of the EFI_PXE_BASE_CODE_MODE structure + will also be filled in. If UseBis is FALSE, then PxeBisReplyValid will be set to FALSE. + In the structure referenced by parameter Info, the PXE Boot Server list, SrvList[], + has two uses: It is the Boot Server IP address list used for unicast discovery + (if the UseUCast field is TRUE), and it is the list used for Boot Server verification + (if the MustUseList field is TRUE). Also, if the MustUseList field in that structure + is TRUE and the AcceptAnyResponse field in the SrvList[] array is TRUE, any Boot + Server reply of that type will be accepted. If the AcceptAnyResponse field is + FALSE, only responses from Boot Servers with matching IP addresses will be accepted. + This function can take at least 10 seconds to timeout and return control to the + caller. If the Discovery sequence does not complete, then EFI_TIMEOUT will be + returned. Please see the Preboot Execution Environment (PXE) Specification for + additional details on the implementation of the Discovery sequence. + If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, + then the Discovery sequence is stopped and EFI_ABORTED will be returned. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + @param Type The type of bootstrap to perform. + @param Layer The pointer to the boot server layer number to discover, which must be + PXE_BOOT_LAYER_INITIAL when a new server type is being + discovered. + @param UseBis TRUE if Boot Integrity Services are to be used. FALSE otherwise. + @param Info The pointer to a data structure that contains additional information on the + type of discovery operation that is to be performed. + + @retval EFI_SUCCESS The Discovery sequence has been completed. + @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough memory to complete Discovery. + @retval EFI_ABORTED The callback function aborted the Discovery sequence. + @retval EFI_TIMEOUT The Discovery sequence timed out. + @retval EFI_ICMP_ERROR An ICMP error packet was received during the PXE discovery + session. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_DISCOVER)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN UINT16 Type, + IN UINT16 *Layer, + IN BOOLEAN UseBis, + IN EFI_PXE_BASE_CODE_DISCOVER_INFO *Info OPTIONAL + ); + +/** + Used to perform TFTP and MTFTP services. + + This function is used to perform TFTP and MTFTP services. This includes the + TFTP operations to get the size of a file, read a directory, read a file, and + write a file. It also includes the MTFTP operations to get the size of a file, + read a directory, and read a file. The type of operation is specified by Operation. + If the callback function that is invoked during the TFTP/MTFTP operation does + not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then EFI_ABORTED will + be returned. + For read operations, the return data will be placed in the buffer specified by + BufferPtr. If BufferSize is too small to contain the entire downloaded file, + then EFI_BUFFER_TOO_SMALL will be returned and BufferSize will be set to zero + or the size of the requested file (the size of the requested file is only returned + if the TFTP server supports TFTP options). If BufferSize is large enough for the + read operation, then BufferSize will be set to the size of the downloaded file, + and EFI_SUCCESS will be returned. Applications using the PxeBc.Mtftp() services + should use the get-file-size operations to determine the size of the downloaded + file prior to using the read-file operations--especially when downloading large + (greater than 64 MB) files--instead of making two calls to the read-file operation. + Following this recommendation will save time if the file is larger than expected + and the TFTP server does not support TFTP option extensions. Without TFTP option + extension support, the client has to download the entire file, counting and discarding + the received packets, to determine the file size. + For write operations, the data to be sent is in the buffer specified by BufferPtr. + BufferSize specifies the number of bytes to send. If the write operation completes + successfully, then EFI_SUCCESS will be returned. + For TFTP "get file size" operations, the size of the requested file or directory + is returned in BufferSize, and EFI_SUCCESS will be returned. If the TFTP server + does not support options, the file will be downloaded into a bit bucket and the + length of the downloaded file will be returned. For MTFTP "get file size" operations, + if the MTFTP server does not support the "get file size" option, EFI_UNSUPPORTED + will be returned. + This function can take up to 10 seconds to timeout and return control to the caller. + If the TFTP sequence does not complete, EFI_TIMEOUT will be returned. + If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, + then the TFTP sequence is stopped and EFI_ABORTED will be returned. + The format of the data returned from a TFTP read directory operation is a null-terminated + filename followed by a null-terminated information string, of the form + "size year-month-day hour:minute:second" (i.e. %d %d-%d-%d %d:%d:%f - note that + the seconds field can be a decimal number), where the date and time are UTC. For + an MTFTP read directory command, there is additionally a null-terminated multicast + IP address preceding the filename of the form %d.%d.%d.%d for IP v4. The final + entry is itself null-terminated, so that the final information string is terminated + with two null octets. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + @param Operation The type of operation to perform. + @param BufferPtr A pointer to the data buffer. + @param Overwrite Only used on write file operations. TRUE if a file on a remote server can + be overwritten. + @param BufferSize For get-file-size operations, *BufferSize returns the size of the + requested file. + @param BlockSize The requested block size to be used during a TFTP transfer. + @param ServerIp The TFTP / MTFTP server IP address. + @param Filename A Null-terminated ASCII string that specifies a directory name or a file + name. + @param Info The pointer to the MTFTP information. + @param DontUseBuffer Set to FALSE for normal TFTP and MTFTP read file operation. + + @retval EFI_SUCCESS The TFTP/MTFTP operation was completed. + @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. + @retval EFI_BUFFER_TOO_SMALL The buffer is not large enough to complete the read operation. + @retval EFI_ABORTED The callback function aborted the TFTP/MTFTP operation. + @retval EFI_TIMEOUT The TFTP/MTFTP operation timed out. + @retval EFI_ICMP_ERROR An ICMP error packet was received during the MTFTP session. + @retval EFI_TFTP_ERROR A TFTP error packet was received during the MTFTP session. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_MTFTP)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation, + IN OUT VOID *BufferPtr OPTIONAL, + IN BOOLEAN Overwrite, + IN OUT UINT64 *BufferSize, + IN UINTN *BlockSize OPTIONAL, + IN EFI_IP_ADDRESS *ServerIp, + IN UINT8 *Filename OPTIONAL, + IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL, + IN BOOLEAN DontUseBuffer + ); + +/** + Writes a UDP packet to the network interface. + + This function writes a UDP packet specified by the (optional HeaderPtr and) + BufferPtr parameters to the network interface. The UDP header is automatically + built by this routine. It uses the parameters OpFlags, DestIp, DestPort, GatewayIp, + SrcIp, and SrcPort to build this header. If the packet is successfully built and + transmitted through the network interface, then EFI_SUCCESS will be returned. + If a timeout occurs during the transmission of the packet, then EFI_TIMEOUT will + be returned. If an ICMP error occurs during the transmission of the packet, then + the IcmpErrorReceived field is set to TRUE, the IcmpError field is filled in and + EFI_ICMP_ERROR will be returned. If the Callback Protocol does not return + EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then EFI_ABORTED will be returned. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + @param OpFlags The UDP operation flags. + @param DestIp The destination IP address. + @param DestPort The destination UDP port number. + @param GatewayIp The gateway IP address. + @param SrcIp The source IP address. + @param SrcPort The source UDP port number. + @param HeaderSize An optional field which may be set to the length of a header at + HeaderPtr to be prefixed to the data at BufferPtr. + @param HeaderPtr If HeaderSize is not NULL, a pointer to a header to be prefixed to the + data at BufferPtr. + @param BufferSize A pointer to the size of the data at BufferPtr. + @param BufferPtr A pointer to the data to be written. + + @retval EFI_SUCCESS The UDP Write operation was completed. + @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_BAD_BUFFER_SIZE The buffer is too long to be transmitted. + @retval EFI_ABORTED The callback function aborted the UDP Write operation. + @retval EFI_TIMEOUT The UDP Write operation timed out. + @retval EFI_ICMP_ERROR An ICMP error packet was received during the UDP write session. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_UDP_WRITE)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN UINT16 OpFlags, + IN EFI_IP_ADDRESS *DestIp, + IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort, + IN EFI_IP_ADDRESS *GatewayIp OPTIONAL, + IN EFI_IP_ADDRESS *SrcIp OPTIONAL, + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, + IN UINTN *HeaderSize OPTIONAL, + IN VOID *HeaderPtr OPTIONAL, + IN UINTN *BufferSize, + IN VOID *BufferPtr + ); + +/** + Reads a UDP packet from the network interface. + + This function reads a UDP packet from a network interface. The data contents + are returned in (the optional HeaderPtr and) BufferPtr, and the size of the + buffer received is returned in BufferSize. If the input BufferSize is smaller + than the UDP packet received (less optional HeaderSize), it will be set to the + required size, and EFI_BUFFER_TOO_SMALL will be returned. In this case, the + contents of BufferPtr are undefined, and the packet is lost. If a UDP packet is + successfully received, then EFI_SUCCESS will be returned, and the information + from the UDP header will be returned in DestIp, DestPort, SrcIp, and SrcPort if + they are not NULL. + Depending on the values of OpFlags and the DestIp, DestPort, SrcIp, and SrcPort + input values, different types of UDP packet receive filtering will be performed. + The following tables summarize these receive filter operations. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + @param OpFlags The UDP operation flags. + @param DestIp The destination IP address. + @param DestPort The destination UDP port number. + @param SrcIp The source IP address. + @param SrcPort The source UDP port number. + @param HeaderSize An optional field which may be set to the length of a header at + HeaderPtr to be prefixed to the data at BufferPtr. + @param HeaderPtr If HeaderSize is not NULL, a pointer to a header to be prefixed to the + data at BufferPtr. + @param BufferSize A pointer to the size of the data at BufferPtr. + @param BufferPtr A pointer to the data to be read. + + @retval EFI_SUCCESS The UDP Read operation was completed. + @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. + @retval EFI_BUFFER_TOO_SMALL The packet is larger than Buffer can hold. + @retval EFI_ABORTED The callback function aborted the UDP Read operation. + @retval EFI_TIMEOUT The UDP Read operation timed out. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_UDP_READ)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN UINT16 OpFlags, + IN OUT EFI_IP_ADDRESS *DestIp OPTIONAL, + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort OPTIONAL, + IN OUT EFI_IP_ADDRESS *SrcIp OPTIONAL, + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, + IN UINTN *HeaderSize OPTIONAL, + IN VOID *HeaderPtr OPTIONAL, + IN OUT UINTN *BufferSize, + IN VOID *BufferPtr + ); + +/** + Updates the IP receive filters of a network device and enables software filtering. + + The NewFilter field is used to modify the network device's current IP receive + filter settings and to enable a software filter. This function updates the IpFilter + field of the EFI_PXE_BASE_CODE_MODE structure with the contents of NewIpFilter. + The software filter is used when the USE_FILTER in OpFlags is set to UdpRead(). + The current hardware filter remains in effect no matter what the settings of OpFlags + are, so that the meaning of ANY_DEST_IP set in OpFlags to UdpRead() is from those + packets whose reception is enabled in hardware - physical NIC address (unicast), + broadcast address, logical address or addresses (multicast), or all (promiscuous). + UdpRead() does not modify the IP filter settings. + Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP receive + filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP. + If an application or driver wishes to preserve the IP receive filter settings, + it will have to preserve the IP receive filter settings before these calls, and + use SetIpFilter() to restore them after the calls. If incompatible filtering is + requested (for example, PROMISCUOUS with anything else), or if the device does not + support a requested filter setting and it cannot be accommodated in software + (for example, PROMISCUOUS not supported), EFI_INVALID_PARAMETER will be returned. + The IPlist field is used to enable IPs other than the StationIP. They may be + multicast or unicast. If IPcnt is set as well as EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP, + then both the StationIP and the IPs from the IPlist will be used. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + @param NewFilter The pointer to the new set of IP receive filters. + + @retval EFI_SUCCESS The IP receive filter settings were updated. + @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_IP_FILTER)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN EFI_PXE_BASE_CODE_IP_FILTER *NewFilter + ); + +/** + Uses the ARP protocol to resolve a MAC address. + + This function uses the ARP protocol to resolve a MAC address. The UsingIpv6 field + of the EFI_PXE_BASE_CODE_MODE structure is used to determine if IPv4 or IPv6 + addresses are being used. The IP address specified by IpAddr is used to resolve + a MAC address. If the ARP protocol succeeds in resolving the specified address, + then the ArpCacheEntries and ArpCache fields of the EFI_PXE_BASE_CODE_MODE structure + are updated, and EFI_SUCCESS is returned. If MacAddr is not NULL, the resolved + MAC address is placed there as well. + If the PXE Base Code protocol is in the stopped state, then EFI_NOT_STARTED is + returned. If the ARP protocol encounters a timeout condition while attempting + to resolve an address, then EFI_TIMEOUT is returned. If the Callback Protocol + does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then EFI_ABORTED is + returned. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + @param IpAddr The pointer to the IP address that is used to resolve a MAC address. + @param MacAddr If not NULL, a pointer to the MAC address that was resolved with the + ARP protocol. + + @retval EFI_SUCCESS The IP or MAC address was resolved. + @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_DEVICE_ERROR The network device encountered an error during this operation. + @retval EFI_ABORTED The callback function aborted the ARP Protocol. + @retval EFI_TIMEOUT The ARP Protocol encountered a timeout condition. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_ARP)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN EFI_IP_ADDRESS *IpAddr, + IN EFI_MAC_ADDRESS *MacAddr OPTIONAL + ); + +/** + Updates the parameters that affect the operation of the PXE Base Code Protocol. + + This function sets parameters that affect the operation of the PXE Base Code Protocol. + The parameter specified by NewAutoArp is used to control the generation of ARP + protocol packets. If NewAutoArp is TRUE, then ARP Protocol packets will be generated + as required by the PXE Base Code Protocol. If NewAutoArp is FALSE, then no ARP + Protocol packets will be generated. In this case, the only mappings that are + available are those stored in the ArpCache of the EFI_PXE_BASE_CODE_MODE structure. + If there are not enough mappings in the ArpCache to perform a PXE Base Code Protocol + service, then the service will fail. This function updates the AutoArp field of + the EFI_PXE_BASE_CODE_MODE structure to NewAutoArp. + The SetParameters() call must be invoked after a Callback Protocol is installed + to enable the use of callbacks. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + @param NewAutoArp If not NULL, a pointer to a value that specifies whether to replace the + current value of AutoARP. + @param NewSendGUID If not NULL, a pointer to a value that specifies whether to replace the + current value of SendGUID. + @param NewTTL If not NULL, a pointer to be used in place of the current value of TTL, + the "time to live" field of the IP header. + @param NewToS If not NULL, a pointer to be used in place of the current value of ToS, + the "type of service" field of the IP header. + @param NewMakeCallback If not NULL, a pointer to a value that specifies whether to replace the + current value of the MakeCallback field of the Mode structure. + + @retval EFI_SUCCESS The new parameters values were updated. + @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_PARAMETERS)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN BOOLEAN *NewAutoArp OPTIONAL, + IN BOOLEAN *NewSendGUID OPTIONAL, + IN UINT8 *NewTTL OPTIONAL, + IN UINT8 *NewToS OPTIONAL, + IN BOOLEAN *NewMakeCallback OPTIONAL + ); + +/** + Updates the station IP address and/or subnet mask values of a network device. + + This function updates the station IP address and/or subnet mask values of a network + device. + The NewStationIp field is used to modify the network device's current IP address. + If NewStationIP is NULL, then the current IP address will not be modified. Otherwise, + this function updates the StationIp field of the EFI_PXE_BASE_CODE_MODE structure + with NewStationIp. + The NewSubnetMask field is used to modify the network device's current subnet + mask. If NewSubnetMask is NULL, then the current subnet mask will not be modified. + Otherwise, this function updates the SubnetMask field of the EFI_PXE_BASE_CODE_MODE + structure with NewSubnetMask. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + @param NewStationIp The pointer to the new IP address to be used by the network device. + @param NewSubnetMask The pointer to the new subnet mask to be used by the network device. + + @retval EFI_SUCCESS The new station IP address and/or subnet mask were updated. + @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_STATION_IP)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN EFI_IP_ADDRESS *NewStationIp OPTIONAL, + IN EFI_IP_ADDRESS *NewSubnetMask OPTIONAL + ); + +/** + Updates the contents of the cached DHCP and Discover packets. + + The pointers to the new packets are used to update the contents of the cached + packets in the EFI_PXE_BASE_CODE_MODE structure. + + @param This The pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance. + @param NewDhcpDiscoverValid The pointer to a value that will replace the current + DhcpDiscoverValid field. + @param NewDhcpAckReceived The pointer to a value that will replace the current + DhcpAckReceived field. + @param NewProxyOfferReceived The pointer to a value that will replace the current + ProxyOfferReceived field. + @param NewPxeDiscoverValid The pointer to a value that will replace the current + ProxyOfferReceived field. + @param NewPxeReplyReceived The pointer to a value that will replace the current + PxeReplyReceived field. + @param NewPxeBisReplyReceived The pointer to a value that will replace the current + PxeBisReplyReceived field. + @param NewDhcpDiscover The pointer to the new cached DHCP Discover packet contents. + @param NewDhcpAck The pointer to the new cached DHCP Ack packet contents. + @param NewProxyOffer The pointer to the new cached Proxy Offer packet contents. + @param NewPxeDiscover The pointer to the new cached PXE Discover packet contents. + @param NewPxeReply The pointer to the new cached PXE Reply packet contents. + @param NewPxeBisReply The pointer to the new cached PXE BIS Reply packet contents. + + @retval EFI_SUCCESS The cached packet contents were updated. + @retval EFI_NOT_STARTED The PXE Base Code Protocol is in the stopped state. + @retval EFI_INVALID_PARAMETER This is NULL or not point to a valid EFI_PXE_BASE_CODE_PROTOCOL structure. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_PACKETS)( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + BOOLEAN *NewDhcpDiscoverValid OPTIONAL, + BOOLEAN *NewDhcpAckReceived OPTIONAL, + BOOLEAN *NewProxyOfferReceived OPTIONAL, + BOOLEAN *NewPxeDiscoverValid OPTIONAL, + BOOLEAN *NewPxeReplyReceived OPTIONAL, + BOOLEAN *NewPxeBisReplyReceived OPTIONAL, + IN EFI_PXE_BASE_CODE_PACKET *NewDhcpDiscover OPTIONAL, + IN EFI_PXE_BASE_CODE_PACKET *NewDhcpAck OPTIONAL, + IN EFI_PXE_BASE_CODE_PACKET *NewProxyOffer OPTIONAL, + IN EFI_PXE_BASE_CODE_PACKET *NewPxeDiscover OPTIONAL, + IN EFI_PXE_BASE_CODE_PACKET *NewPxeReply OPTIONAL, + IN EFI_PXE_BASE_CODE_PACKET *NewPxeBisReply OPTIONAL + ); + +// +// PXE Base Code Protocol structure +// +#define EFI_PXE_BASE_CODE_PROTOCOL_REVISION 0x00010000 + +// +// Revision defined in EFI1.1 +// +#define EFI_PXE_BASE_CODE_INTERFACE_REVISION EFI_PXE_BASE_CODE_PROTOCOL_REVISION + +/// +/// The EFI_PXE_BASE_CODE_PROTOCOL is used to control PXE-compatible devices. +/// An EFI_PXE_BASE_CODE_PROTOCOL will be layered on top of an +/// EFI_MANAGED_NETWORK_PROTOCOL protocol in order to perform packet level transactions. +/// The EFI_PXE_BASE_CODE_PROTOCOL handle also supports the +/// EFI_LOAD_FILE_PROTOCOL protocol. This provides a clean way to obtain control from the +/// boot manager if the boot path is from the remote device. +/// +struct _EFI_PXE_BASE_CODE_PROTOCOL { + /// + /// The revision of the EFI_PXE_BASE_CODE_PROTOCOL. All future revisions must + /// be backwards compatible. If a future version is not backwards compatible + /// it is not the same GUID. + /// + UINT64 Revision; + EFI_PXE_BASE_CODE_START Start; + EFI_PXE_BASE_CODE_STOP Stop; + EFI_PXE_BASE_CODE_DHCP Dhcp; + EFI_PXE_BASE_CODE_DISCOVER Discover; + EFI_PXE_BASE_CODE_MTFTP Mtftp; + EFI_PXE_BASE_CODE_UDP_WRITE UdpWrite; + EFI_PXE_BASE_CODE_UDP_READ UdpRead; + EFI_PXE_BASE_CODE_SET_IP_FILTER SetIpFilter; + EFI_PXE_BASE_CODE_ARP Arp; + EFI_PXE_BASE_CODE_SET_PARAMETERS SetParameters; + EFI_PXE_BASE_CODE_SET_STATION_IP SetStationIp; + EFI_PXE_BASE_CODE_SET_PACKETS SetPackets; + /// + /// The pointer to the EFI_PXE_BASE_CODE_MODE data for this device. + /// + EFI_PXE_BASE_CODE_MODE *Mode; +}; + +extern EFI_GUID gEfiPxeBaseCodeProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/PxeBaseCodeCallBack.h b/sys/contrib/edk2/Include/Protocol/PxeBaseCodeCallBack.h new file mode 100644 index 000000000000..0402a212dfab --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/PxeBaseCodeCallBack.h @@ -0,0 +1,123 @@ +/** @file + It is invoked when the PXE Base Code Protocol is about to transmit, has received, + or is waiting to receive a packet. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in EFI Specification 1.10 + +**/ + +#ifndef _PXE_BASE_CODE_CALLBACK_H_ +#define _PXE_BASE_CODE_CALLBACK_H_ + +/// +/// Call Back Definitions. +/// +#define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID \ + { \ + 0x245dca21, 0xfb7b, 0x11d3, {0x8f, 0x01, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +/// +/// UEFI Revision Number Definition. +/// +#define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_REVISION 0x00010000 + +/// +/// EFI 1.1 Revision Number defintion. +/// +#define EFI_PXE_BASE_CODE_CALLBACK_INTERFACE_REVISION \ + EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_REVISION + +/// +/// UEFI Protocol name. +/// +typedef struct _EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL; + +/// +/// EFI1.1 Protocol name. +/// +typedef EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL EFI_PXE_BASE_CODE_CALLBACK; + +/// +/// Event type list for PXE Base Code Protocol function. +/// +typedef enum { + EFI_PXE_BASE_CODE_FUNCTION_FIRST, + EFI_PXE_BASE_CODE_FUNCTION_DHCP, + EFI_PXE_BASE_CODE_FUNCTION_DISCOVER, + EFI_PXE_BASE_CODE_FUNCTION_MTFTP, + EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE, + EFI_PXE_BASE_CODE_FUNCTION_UDP_READ, + EFI_PXE_BASE_CODE_FUNCTION_ARP, + EFI_PXE_BASE_CODE_FUNCTION_IGMP, + EFI_PXE_BASE_CODE_PXE_FUNCTION_LAST +} EFI_PXE_BASE_CODE_FUNCTION; + +/// +/// Callback status type. +/// +typedef enum { + EFI_PXE_BASE_CODE_CALLBACK_STATUS_FIRST, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_LAST +} EFI_PXE_BASE_CODE_CALLBACK_STATUS; + +/** + Callback function that is invoked when the PXE Base Code Protocol is about to transmit, has + received, or is waiting to receive a packet. + + This function is invoked when the PXE Base Code Protocol is about to transmit, has received, + or is waiting to receive a packet. Parameters Function and Received specify the type of event. + Parameters PacketLen and Packet specify the packet that generated the event. If these fields + are zero and NULL respectively, then this is a status update callback. If the operation specified + by Function is to continue, then CALLBACK_STATUS_CONTINUE should be returned. If the operation + specified by Function should be aborted, then CALLBACK_STATUS_ABORT should be returned. Due to + the polling nature of UEFI device drivers, a callback function should not execute for more than 5 ms. + The SetParameters() function must be called after a Callback Protocol is installed to enable the + use of callbacks. + + @param This The pointer to the EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL instance. + @param Function The PXE Base Code Protocol function that is waiting for an event. + @param Received TRUE if the callback is being invoked due to a receive event. FALSE if + the callback is being invoked due to a transmit event. + @param PacketLen The length, in bytes, of Packet. This field will have a value of zero if + this is a wait for receive event. + @param Packet If Received is TRUE, a pointer to the packet that was just received; + otherwise a pointer to the packet that is about to be transmitted. + + @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE if Function specifies a continue operation + @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT if Function specifies an abort operation + +**/ +typedef +EFI_PXE_BASE_CODE_CALLBACK_STATUS +(EFIAPI *EFI_PXE_CALLBACK)( + IN EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *This, + IN EFI_PXE_BASE_CODE_FUNCTION Function, + IN BOOLEAN Received, + IN UINT32 PacketLen, + IN EFI_PXE_BASE_CODE_PACKET *Packet OPTIONAL + ); + +/// +/// Protocol that is invoked when the PXE Base Code Protocol is about +/// to transmit, has received, or is waiting to receive a packet. +/// +struct _EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL { + /// + /// The revision of the EFI_PXE_BASE_CODE_PROTOCOL. All future revisions must + /// be backwards compatible. If a future version is not backwards compatible + /// it is not the same GUID. + /// + UINT64 Revision; + EFI_PXE_CALLBACK Callback; +}; + +extern EFI_GUID gEfiPxeBaseCodeCallbackProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Reset.h b/sys/contrib/edk2/Include/Protocol/Reset.h new file mode 100644 index 000000000000..9f1ec1d83325 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Reset.h @@ -0,0 +1,25 @@ +/** @file + Reset Architectural Protocol as defined in PI Specification VOLUME 2 DXE + + Used to provide ResetSystem runtime services + + The ResetSystem () UEFI 2.0 service is added to the EFI system table and the + EFI_RESET_ARCH_PROTOCOL_GUID protocol is registered with a NULL pointer. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_RESET_H__ +#define __ARCH_PROTOCOL_RESET_H__ + +/// +/// Global ID for the Reset Architectural Protocol +/// +#define EFI_RESET_ARCH_PROTOCOL_GUID \ + { 0x27CFAC88, 0x46CC, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } } + +extern EFI_GUID gEfiResetArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/RiscVBootProtocol.h b/sys/contrib/edk2/Include/Protocol/RiscVBootProtocol.h new file mode 100644 index 000000000000..ed223b852d34 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/RiscVBootProtocol.h @@ -0,0 +1,34 @@ +/** @file
+ RISC-V Boot Protocol mandatory for RISC-V UEFI platforms.
+
+ @par Revision Reference:
+ The protocol specification can be found at
+ https://github.com/riscv-non-isa/riscv-uefi
+
+ Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RISCV_BOOT_PROTOCOL_H_
+#define RISCV_BOOT_PROTOCOL_H_
+
+typedef struct _RISCV_EFI_BOOT_PROTOCOL RISCV_EFI_BOOT_PROTOCOL;
+
+#define RISCV_EFI_BOOT_PROTOCOL_REVISION 0x00010000
+#define RISCV_EFI_BOOT_PROTOCOL_LATEST_VERSION \
+ RISCV_EFI_BOOT_PROTOCOL_REVISION
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_BOOT_HARTID)(
+ IN RISCV_EFI_BOOT_PROTOCOL *This,
+ OUT UINTN *BootHartId
+ );
+
+typedef struct _RISCV_EFI_BOOT_PROTOCOL {
+ UINT64 Revision;
+ EFI_GET_BOOT_HARTID GetBootHartId;
+} RISCV_EFI_BOOT_PROTOCOL;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Protocol/Rng.h b/sys/contrib/edk2/Include/Protocol/Rng.h new file mode 100644 index 000000000000..5c3e1daa1e2e --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Rng.h @@ -0,0 +1,28 @@ +/** @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 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EFI_RNG_PROTOCOL_H_ +#define EFI_RNG_PROTOCOL_H_ + +#include <Guid/Rng.h> + +/// +/// 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 EFI_RNG_INTERFACE EFI_RNG_PROTOCOL; + +extern EFI_GUID gEfiRngProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Runtime.h b/sys/contrib/edk2/Include/Protocol/Runtime.h new file mode 100644 index 000000000000..ae2f89e476b1 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Runtime.h @@ -0,0 +1,122 @@ +/** @file + Runtime Architectural Protocol as defined in PI Specification VOLUME 2 DXE + + Allows the runtime functionality of the DXE Foundation to be contained + in a separate driver. It also provides hooks for the DXE Foundation to + export information that is needed at runtime. As such, this protocol allows + services to the DXE Foundation to manage runtime drivers and events. + This protocol also implies that the runtime services required to transition + to virtual mode, SetVirtualAddressMap() and ConvertPointer(), have been + registered into the UEFI Runtime Table in the UEFI System Table. This protocol + must be produced by a runtime DXE driver and may only be consumed by the DXE Foundation. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_RUNTIME_H__ +#define __ARCH_PROTOCOL_RUNTIME_H__ + +/// +/// Global ID for the Runtime Architectural Protocol +/// +#define EFI_RUNTIME_ARCH_PROTOCOL_GUID \ + { 0xb7dfb4e1, 0x52f, 0x449f, {0x87, 0xbe, 0x98, 0x18, 0xfc, 0x91, 0xb7, 0x33 } } + +typedef struct _EFI_RUNTIME_ARCH_PROTOCOL EFI_RUNTIME_ARCH_PROTOCOL; + +/// +/// LIST_ENTRY from BaseType +/// +typedef LIST_ENTRY EFI_LIST_ENTRY; + +typedef struct _EFI_RUNTIME_IMAGE_ENTRY EFI_RUNTIME_IMAGE_ENTRY; + +/// +/// EFI_RUNTIME_IMAGE_ENTRY +/// +struct _EFI_RUNTIME_IMAGE_ENTRY { + /// + /// Start of image that has been loaded in memory. It is a pointer + /// to either the DOS header or PE header of the image. + /// + VOID *ImageBase; + /// + /// Size in bytes of the image represented by ImageBase. + /// + UINT64 ImageSize; + /// + /// Information about the fix-ups that were performed on ImageBase when it was + /// loaded into memory. + /// + VOID *RelocationData; + /// + /// The ImageHandle passed into ImageBase when it was loaded. + /// + EFI_HANDLE Handle; + /// + /// Entry for this node in the EFI_RUNTIME_ARCHITECTURE_PROTOCOL.ImageHead list. + /// + EFI_LIST_ENTRY Link; +}; + +typedef struct _EFI_RUNTIME_EVENT_ENTRY EFI_RUNTIME_EVENT_ENTRY; + +/// +/// EFI_RUNTIME_EVENT_ENTRY +/// +struct _EFI_RUNTIME_EVENT_ENTRY { + /// + /// The same as Type passed into CreateEvent(). + /// + UINT32 Type; + /// + /// The same as NotifyTpl passed into CreateEvent(). + /// + EFI_TPL NotifyTpl; + /// + /// The same as NotifyFunction passed into CreateEvent(). + /// + EFI_EVENT_NOTIFY NotifyFunction; + /// + /// The same as NotifyContext passed into CreateEvent(). + /// + VOID *NotifyContext; + /// + /// The EFI_EVENT returned by CreateEvent(). Event must be in runtime memory. + /// + EFI_EVENT *Event; + /// + /// Entry for this node in the + /// EFI_RUNTIME_ARCHITECTURE_PROTOCOL.EventHead list. + /// + EFI_LIST_ENTRY Link; +}; + +/// +/// Allows the runtime functionality of the DXE Foundation to be contained in a +/// separate driver. It also provides hooks for the DXE Foundation to export +/// information that is needed at runtime. As such, this protocol allows the DXE +/// Foundation to manage runtime drivers and events. This protocol also implies +/// that the runtime services required to transition to virtual mode, +/// SetVirtualAddressMap() and ConvertPointer(), have been registered into the +/// EFI Runtime Table in the EFI System Partition. This protocol must be produced +/// by a runtime DXE driver and may only be consumed by the DXE Foundation. +/// +struct _EFI_RUNTIME_ARCH_PROTOCOL { + EFI_LIST_ENTRY ImageHead; ///< A list of type EFI_RUNTIME_IMAGE_ENTRY. + EFI_LIST_ENTRY EventHead; ///< A list of type EFI_RUNTIME_EVENT_ENTRY. + UINTN MemoryDescriptorSize; ///< Size of a memory descriptor that is returned by GetMemoryMap(). + UINT32 MemoryDesciptorVersion; ///< Version of a memory descriptor that is returned by GetMemoryMap(). + UINTN MemoryMapSize; ///< Size of the memory map in bytes contained in MemoryMapPhysical and MemoryMapVirtual. + EFI_MEMORY_DESCRIPTOR *MemoryMapPhysical; ///< Pointer to a runtime buffer that contains a copy of + ///< the memory map returned via GetMemoryMap(). + EFI_MEMORY_DESCRIPTOR *MemoryMapVirtual; ///< Pointer to MemoryMapPhysical that is updated to virtual mode after SetVirtualAddressMap(). + BOOLEAN VirtualMode; ///< Boolean that is TRUE if SetVirtualAddressMap() has been called. + BOOLEAN AtRuntime; ///< Boolean that is TRUE if ExitBootServices () has been called. +}; + +extern EFI_GUID gEfiRuntimeArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/ScsiIo.h b/sys/contrib/edk2/Include/Protocol/ScsiIo.h new file mode 100644 index 000000000000..8b1547ccade9 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/ScsiIo.h @@ -0,0 +1,309 @@ +/** @file + EFI_SCSI_IO_PROTOCOL as defined in UEFI 2.0. + This protocol is used by code, typically drivers, running in the EFI boot + services environment to access SCSI devices. In particular, functions for + managing devices on SCSI buses are defined here. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_SCSI_IO_PROTOCOL_H__ +#define __EFI_SCSI_IO_PROTOCOL_H__ + +#define EFI_SCSI_IO_PROTOCOL_GUID \ + { \ + 0x932f47e6, 0x2362, 0x4002, {0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \ + } + +/// +/// Forward reference for pure ANSI compatability +/// +typedef struct _EFI_SCSI_IO_PROTOCOL EFI_SCSI_IO_PROTOCOL; + +// +// SCSI Device type information, defined in the SCSI Primary Commands standard (e.g., SPC-4) +// +#define EFI_SCSI_IO_TYPE_DISK 0x00 ///< Disk device +#define EFI_SCSI_IO_TYPE_TAPE 0x01 ///< Tape device +#define EFI_SCSI_IO_TYPE_PRINTER 0x02 ///< Printer +#define EFI_SCSI_IO_TYPE_PROCESSOR 0x03 ///< Processor +#define EFI_SCSI_IO_TYPE_WORM 0x04 ///< Write-once read-multiple +#define EFI_SCSI_IO_TYPE_CDROM 0x05 ///< CD or DVD device +#define EFI_SCSI_IO_TYPE_SCANNER 0x06 ///< Scanner device +#define EFI_SCSI_IO_TYPE_OPTICAL 0x07 ///< Optical memory device +#define EFI_SCSI_IO_TYPE_MEDIUMCHANGER 0x08 ///< Medium Changer device +#define EFI_SCSI_IO_TYPE_COMMUNICATION 0x09 ///< Communications device +#define MFI_SCSI_IO_TYPE_A 0x0A ///< Obsolete +#define MFI_SCSI_IO_TYPE_B 0x0B ///< Obsolete +#define MFI_SCSI_IO_TYPE_RAID 0x0C ///< Storage array controller device (e.g., RAID) +#define MFI_SCSI_IO_TYPE_SES 0x0D ///< Enclosure services device +#define MFI_SCSI_IO_TYPE_RBC 0x0E ///< Simplified direct-access device (e.g., magnetic disk) +#define MFI_SCSI_IO_TYPE_OCRW 0x0F ///< Optical card reader/writer device +#define MFI_SCSI_IO_TYPE_BRIDGE 0x10 ///< Bridge Controller Commands +#define MFI_SCSI_IO_TYPE_OSD 0x11 ///< Object-based Storage Device +#define EFI_SCSI_IO_TYPE_RESERVED_LOW 0x12 ///< Reserved (low) +#define EFI_SCSI_IO_TYPE_RESERVED_HIGH 0x1E ///< Reserved (high) +#define EFI_SCSI_IO_TYPE_UNKNOWN 0x1F ///< Unknown no device type + +// +// SCSI Data Direction definition +// +#define EFI_SCSI_IO_DATA_DIRECTION_READ 0 +#define EFI_SCSI_IO_DATA_DIRECTION_WRITE 1 +#define EFI_SCSI_IO_DATA_DIRECTION_BIDIRECTIONAL 2 + +// +// SCSI Host Adapter Status definition +// +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK 0x00 +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND 0x09 ///< timeout when processing the command +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_TIMEOUT 0x0b ///< timeout when waiting for the command processing +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_MESSAGE_REJECT 0x0d ///< a message reject was received when processing command +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_RESET 0x0e ///< a bus reset was detected +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_PARITY_ERROR 0x0f +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED 0x10 ///< the adapter failed in issuing request sense command +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT 0x11 ///< selection timeout +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN 0x12 ///< data overrun or data underrun +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_BUS_FREE 0x13 ///< Unexepected bus free +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_PHASE_ERROR 0x14 ///< Target bus phase sequence failure +#define EFI_SCSI_IO_STATUS_HOST_ADAPTER_OTHER 0x7f + +// +// SCSI Target Status definition +// +#define EFI_SCSI_IO_STATUS_TARGET_GOOD 0x00 +#define EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION 0x02 ///< check condition +#define EFI_SCSI_IO_STATUS_TARGET_CONDITION_MET 0x04 ///< condition met +#define EFI_SCSI_IO_STATUS_TARGET_BUSY 0x08 ///< busy +#define EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE 0x10 ///< intermediate +#define EFI_SCSI_IO_STATUS_TARGET_INTERMEDIATE_CONDITION_MET 0x14 ///< intermediate-condition met +#define EFI_SCSI_IO_STATUS_TARGET_RESERVATION_CONFLICT 0x18 ///< reservation conflict +#define EFI_SCSI_IO_STATUS_TARGET_COMMOND_TERMINATED 0x22 ///< command terminated +#define EFI_SCSI_IO_STATUS_TARGET_QUEUE_FULL 0x28 ///< queue full + +typedef struct { + /// + /// The timeout, in 100 ns units, to use for the execution of this SCSI + /// Request Packet. A Timeout value of 0 means that this function + /// will wait indefinitely for the SCSI Request Packet to execute. If + /// Timeout is greater than zero, then this function will return + /// EFI_TIMEOUT if the time required to execute the SCSI Request + /// Packet is greater than Timeout. + /// + UINT64 Timeout; + /// + /// A pointer to the data buffer to transfer between the SCSI + /// controller and the SCSI device for SCSI READ command + /// + VOID *InDataBuffer; + /// + /// A pointer to the data buffer to transfer between the SCSI + /// controller and the SCSI device for SCSI WRITE command. + /// + VOID *OutDataBuffer; + /// + /// A pointer to the sense data that was generated by the execution of + /// the SCSI Request Packet. + /// + VOID *SenseData; + /// + /// A pointer to buffer that contains the Command Data Block to + /// send to the SCSI device. + /// + VOID *Cdb; + /// + /// On Input, the size, in bytes, of InDataBuffer. On output, the + /// number of bytes transferred between the SCSI controller and the SCSI device. + /// + UINT32 InTransferLength; + /// + /// On Input, the size, in bytes of OutDataBuffer. On Output, the + /// Number of bytes transferred between SCSI Controller and the SCSI device. + /// + UINT32 OutTransferLength; + /// + /// The length, in bytes, of the buffer Cdb. The standard values are + /// 6, 10, 12, and 16, but other values are possible if a variable length CDB is used. + /// + UINT8 CdbLength; + /// + /// The direction of the data transfer. 0 for reads, 1 for writes. A + /// value of 2 is Reserved for Bi-Directional SCSI commands. + /// + UINT8 DataDirection; + /// + /// The status of the SCSI Host Controller that produces the SCSI + /// bus where the SCSI device attached when the SCSI Request + /// Packet was executed on the SCSI Controller. + /// + UINT8 HostAdapterStatus; + /// + /// The status returned by the SCSI device when the SCSI Request + /// Packet was executed. + /// + UINT8 TargetStatus; + /// + /// On input, the length in bytes of the SenseData buffer. On + /// output, the number of bytes written to the SenseData buffer. + /// + UINT8 SenseDataLength; +} EFI_SCSI_IO_SCSI_REQUEST_PACKET; + +/** + Retrieves the device type information of the SCSI Controller. + + @param This Protocol instance pointer. + @param DeviceType A pointer to the device type information + retrieved from the SCSI Controller. + + @retval EFI_SUCCESS Retrieved the device type information successfully. + @retval EFI_INVALID_PARAMETER The DeviceType is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SCSI_IO_PROTOCOL_GET_DEVICE_TYPE)( + IN EFI_SCSI_IO_PROTOCOL *This, + OUT UINT8 *DeviceType + ); + +/** + Retrieves the device location in the SCSI channel. + + @param This Protocol instance pointer. + @param Target A pointer to the Target ID of a SCSI device + on the SCSI channel. + @param Lun A pointer to the LUN of the SCSI device on + the SCSI channel. + + @retval EFI_SUCCESS Retrieves the device location successfully. + @retval EFI_INVALID_PARAMETER The Target or Lun is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SCSI_IO_PROTOCOL_GET_DEVICE_LOCATION)( + IN EFI_SCSI_IO_PROTOCOL *This, + IN OUT UINT8 **Target, + OUT UINT64 *Lun + ); + +/** + Resets the SCSI Bus that the SCSI Controller is attached to. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The SCSI bus is reset successfully. + @retval EFI_DEVICE_ERROR Errors encountered when resetting the SCSI bus. + @retval EFI_UNSUPPORTED The bus reset operation is not supported by the + SCSI Host Controller. + @retval EFI_TIMEOUT A timeout occurred while attempting to reset + the SCSI bus. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SCSI_IO_PROTOCOL_RESET_BUS)( + IN EFI_SCSI_IO_PROTOCOL *This + ); + +/** + Resets the SCSI Controller that the device handle specifies. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS Reset the SCSI controller successfully. + @retval EFI_DEVICE_ERROR Errors were encountered when resetting the + SCSI Controller. + @retval EFI_UNSUPPORTED The SCSI bus does not support a device + reset operation. + @retval EFI_TIMEOUT A timeout occurred while attempting to + reset the SCSI Controller. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SCSI_IO_PROTOCOL_RESET_DEVICE)( + IN EFI_SCSI_IO_PROTOCOL *This + ); + +/** + Sends a SCSI Request Packet to the SCSI Controller for execution. + + @param This Protocol instance pointer. + @param Packet The SCSI request packet to send to the SCSI + Controller specified by the device handle. + @param Event If the SCSI bus to which the SCSI device is attached + does not support non-blocking I/O, then Event is + ignored, and blocking I/O is performed. + If Event is NULL, then blocking I/O is performed. + If Event is not NULL and non-blocking I/O is + supported, then non-blocking I/O is performed, + and Event will be signaled when the SCSI Request + Packet completes. + + @retval EFI_SUCCESS The SCSI Request Packet was sent by the host + successfully, and TransferLength bytes were + transferred to/from DataBuffer. See + HostAdapterStatus, TargetStatus, + SenseDataLength, and SenseData in that order + for additional status information. + @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, + but the entire DataBuffer could not be transferred. + The actual number of bytes transferred is returned + in TransferLength. See HostAdapterStatus, + TargetStatus, SenseDataLength, and SenseData in + that order for additional status information. + @retval EFI_NOT_READY The SCSI Request Packet could not be sent because + there are too many SCSI Command Packets already + queued.The caller may retry again later. + @retval EFI_DEVICE_ERROR A device error occurred while attempting to send + the SCSI Request Packet. See HostAdapterStatus, + TargetStatus, SenseDataLength, and SenseData in + that order for additional status information. + @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid. + The SCSI Request Packet was not sent, so no + additional status information is available. + @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet + is not supported by the SCSI initiator(i.e., SCSI + Host Controller). The SCSI Request Packet was not + sent, so no additional status information is + available. + @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI + Request Packet to execute. See HostAdapterStatus, + TargetStatus, SenseDataLength, and SenseData in + that order for additional status information. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SCSI_IO_PROTOCOL_EXEC_SCSI_COMMAND)( + IN EFI_SCSI_IO_PROTOCOL *This, + IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet, + IN EFI_EVENT Event OPTIONAL + ); + +/// +/// Provides services to manage and communicate with SCSI devices. +/// +struct _EFI_SCSI_IO_PROTOCOL { + EFI_SCSI_IO_PROTOCOL_GET_DEVICE_TYPE GetDeviceType; + EFI_SCSI_IO_PROTOCOL_GET_DEVICE_LOCATION GetDeviceLocation; + EFI_SCSI_IO_PROTOCOL_RESET_BUS ResetBus; + EFI_SCSI_IO_PROTOCOL_RESET_DEVICE ResetDevice; + EFI_SCSI_IO_PROTOCOL_EXEC_SCSI_COMMAND ExecuteScsiCommand; + + /// + /// Supplies the alignment requirement for any buffer used in a data transfer. + /// IoAlign values of 0 and 1 mean that the buffer can be placed anywhere in memory. + /// Otherwise, IoAlign must be a power of 2, and the requirement is that the + /// start address of a buffer must be evenly divisible by IoAlign with no remainder. + /// + UINT32 IoAlign; +}; + +extern EFI_GUID gEfiScsiIoProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/ScsiPassThru.h b/sys/contrib/edk2/Include/Protocol/ScsiPassThru.h new file mode 100644 index 000000000000..7cad5326e55c --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/ScsiPassThru.h @@ -0,0 +1,377 @@ +/** @file + SCSI Pass Through protocol as defined in EFI 1.1. + This protocol allows information about a SCSI channel to be collected, + and allows SCSI Request Packets to be sent to any SCSI devices on a SCSI + channel even if those devices are not boot devices. This protocol is attached + to the device handle of each SCSI channel in a system that the protocol + supports, and can be used for diagnostics. It may also be used to build + a Block I/O driver for SCSI hard drives and SCSI CD-ROM or DVD drives to + allow those devices to become boot devices. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SCSI_PASS_THROUGH_H__ +#define __SCSI_PASS_THROUGH_H__ + +#define EFI_SCSI_PASS_THRU_PROTOCOL_GUID \ + { \ + 0xa59e8fcf, 0xbda0, 0x43bb, {0x90, 0xb1, 0xd3, 0x73, 0x2e, 0xca, 0xa8, 0x77 } \ + } + +/// +/// Forward reference for pure ANSI compatability +/// +typedef struct _EFI_SCSI_PASS_THRU_PROTOCOL EFI_SCSI_PASS_THRU_PROTOCOL; + +#define EFI_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL 0x0001 +#define EFI_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL 0x0002 +#define EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO 0x0004 + +// +// SCSI Host Adapter Status definition +// +#define EFI_SCSI_STATUS_HOST_ADAPTER_OK 0x00 +#define EFI_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND 0x09 // timeout when processing the command +#define EFI_SCSI_STATUS_HOST_ADAPTER_TIMEOUT 0x0b // timeout when waiting for the command processing +#define EFI_SCSI_STATUS_HOST_ADAPTER_MESSAGE_REJECT 0x0d // a message reject was received when processing command +#define EFI_SCSI_STATUS_HOST_ADAPTER_BUS_RESET 0x0e // a bus reset was detected +#define EFI_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR 0x0f +#define EFI_SCSI_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED 0x10 // the adapter failed in issuing request sense command +#define EFI_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT 0x11 // selection timeout +#define EFI_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN 0x12 // data overrun or data underrun +#define EFI_SCSI_STATUS_HOST_ADAPTER_BUS_FREE 0x13 // Unexepected bus free +#define EFI_SCSI_STATUS_HOST_ADAPTER_PHASE_ERROR 0x14 // Target bus phase sequence failure +#define EFI_SCSI_STATUS_HOST_ADAPTER_OTHER 0x7f + +// +// SCSI Target Status definition +// +#define EFI_SCSI_STATUS_TARGET_GOOD 0x00 +#define EFI_SCSI_STATUS_TARGET_CHECK_CONDITION 0x02 // check condition +#define EFI_SCSI_STATUS_TARGET_CONDITION_MET 0x04 // condition met +#define EFI_SCSI_STATUS_TARGET_BUSY 0x08 // busy +#define EFI_SCSI_STATUS_TARGET_INTERMEDIATE 0x10 // intermediate +#define EFI_SCSI_STATUS_TARGET_INTERMEDIATE_CONDITION_MET 0x14 // intermediate-condition met +#define EFI_SCSI_STATUS_TARGET_RESERVATION_CONFLICT 0x18 // reservation conflict +#define EFI_SCSI_STATUS_TARGET_COMMOND_TERMINATED 0x22 // command terminated +#define EFI_SCSI_STATUS_TARGET_QUEUE_FULL 0x28 // queue full + +typedef struct { + /// + /// The timeout, in 100 ns units, to use for the execution of this SCSI + /// Request Packet. A Timeout value of 0 means that this function + /// will wait indefinitely for the SCSI Request Packet to execute. If + /// Timeout is greater than zero, then this function will return + /// EFI_TIMEOUT if the time required to execute the SCSI Request + /// Packet is greater than Timeout. + /// + UINT64 Timeout; + /// + /// A pointer to the data buffer to transfer between the SCSI + /// controller and the SCSI device. Must be aligned to the boundary + /// specified in the IoAlign field of the + /// EFI_SCSI_PASS_THRU_MODE structure. + /// + VOID *DataBuffer; + /// + /// A pointer to the sense data that was generated by the execution of + /// the SCSI Request Packet. + /// + VOID *SenseData; + /// + /// A pointer to buffer that contains the Command Data Block to + /// send to the SCSI device. + /// + VOID *Cdb; + /// + /// On Input, the size, in bytes, of InDataBuffer. On output, the + /// number of bytes transferred between the SCSI controller and the SCSI device. + /// + UINT32 TransferLength; + /// + /// The length, in bytes, of the buffer Cdb. The standard values are + /// 6, 10, 12, and 16, but other values are possible if a variable length CDB is used. + /// + UINT8 CdbLength; + /// + /// The direction of the data transfer. 0 for reads, 1 for writes. A + /// value of 2 is Reserved for Bi-Directional SCSI commands. + /// + UINT8 DataDirection; + /// + /// The status of the SCSI Host Controller that produces the SCSI + /// bus where the SCSI device attached when the SCSI Request + /// Packet was executed on the SCSI Controller. + /// + UINT8 HostAdapterStatus; + /// + /// The status returned by the SCSI device when the SCSI Request + /// Packet was executed. + /// + UINT8 TargetStatus; + /// + /// On input, the length in bytes of the SenseData buffer. On + /// output, the number of bytes written to the SenseData buffer. + /// + UINT8 SenseDataLength; +} EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET; + +typedef struct { + /// + /// A Null-terminated Unicode string that represents the printable name of the SCSI controller. + /// + CHAR16 *ControllerName; + /// + /// A Null-terminated Unicode string that represents the printable name of the SCSI channel. + /// + CHAR16 *ChannelName; + /// + /// The Target ID of the host adapter on the SCSI channel. + /// + UINT32 AdapterId; + /// + /// Additional information on the attributes of the SCSI channel. + /// + UINT32 Attributes; + /// + /// Supplies the alignment requirement for any buffer used in a data transfer. + /// + UINT32 IoAlign; +} EFI_SCSI_PASS_THRU_MODE; + +/** + Sends a SCSI Request Packet to a SCSI device that is attached to + the SCSI channel. This function supports both blocking I/O and + non-blocking I/O. The blocking I/O functionality is required, + and the non-blocking I/O functionality is optional. + + @param This Protocol instance pointer. + @param Target The Target ID of the SCSI device to + send the SCSI Request Packet. + @param Lun The LUN of the SCSI device to send the + SCSI Request Packet. + @param Packet A pointer to the SCSI Request Packet to send + to the SCSI device specified by Target and Lun. + @param Event If non-blocking I/O is not supported then Event + is ignored, and blocking I/O is performed. + If Event is NULL, then blocking I/O is performed. + If Event is not NULL and non blocking I/O is + supported, then non-blocking I/O is performed, + and Event will be signaled when the SCSI Request + Packet completes + + @retval EFI_SUCCESS The SCSI Request Packet was sent by the host, and + TransferLength bytes were transferred to/from + DataBuffer. See HostAdapterStatus, TargetStatus, + SenseDataLength, and SenseData in that order + for additional status information. + @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed, but the + entire DataBuffer could not be transferred. + The actual number of bytes transferred is returned + in TransferLength. See HostAdapterStatus, + TargetStatus, SenseDataLength, and SenseData in + that order for additional status information. + @retval EFI_NOT_READY The SCSI Request Packet could not be sent because + there are too many SCSI Request Packets already + queued. The caller may retry again later. + @retval EFI_DEVICE_ERROR A device error occurred while attempting to send + the SCSI Request Packet. See HostAdapterStatus, + TargetStatus, SenseDataLength, and SenseData in + that order for additional status information. + @retval EFI_INVALID_PARAMETER Target, Lun, or the contents of ScsiRequestPacket + are invalid. The SCSI Request Packet was not sent, + so no additional status information is available. + @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet + is not supported by the host adapter. The SCSI + Request Packet was not sent, so no additional + status information is available. + @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI + Request Packet to execute. See HostAdapterStatus, + TargetStatus, SenseDataLength, and SenseData in + that order for additional status information. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SCSI_PASS_THRU_PASSTHRU)( + IN EFI_SCSI_PASS_THRU_PROTOCOL *This, + IN UINT32 Target, + IN UINT64 Lun, + IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, + IN EFI_EVENT Event OPTIONAL + ); + +/** + Used to retrieve the list of legal Target IDs for SCSI devices + on a SCSI channel. + + @param This Protocol instance pointer. + @param Target On input, a pointer to the Target ID of a + SCSI device present on the SCSI channel. + On output, a pointer to the Target ID of + the next SCSI device present on a SCSI channel. + An input value of 0xFFFFFFFF retrieves the + Target ID of the first SCSI device present on + a SCSI channel. + @param Lun On input, a pointer to the LUN of a SCSI device + present on the SCSI channel. On output, a pointer + to the LUN of the next SCSI device present on a + SCSI channel. + + @retval EFI_SUCCESS The Target ID of the next SCSI device on the SCSI + channel was returned in Target and Lun. + @retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI channel. + @retval EFI_INVALID_PARAMETER Target is not 0xFFFFFFFF, and Target and Lun were + not returned on a previous call to GetNextDevice(). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SCSI_PASS_THRU_GET_NEXT_DEVICE)( + IN EFI_SCSI_PASS_THRU_PROTOCOL *This, + IN OUT UINT32 *Target, + IN OUT UINT64 *Lun + ); + +/** + Used to allocate and build a device path node for a SCSI device + on a SCSI channel. + + @param This Protocol instance pointer. + @param Target The Target ID of the SCSI device for which + a device path node is to be allocated and built. + @param Lun The LUN of the SCSI device for which a device + path node is to be allocated and built. + @param DevicePath A pointer to a single device path node that + describes the SCSI device specified by + Target and Lun. This function is responsible + for allocating the buffer DevicePath with the boot + service AllocatePool(). It is the caller's + responsibility to free DevicePath when the caller + is finished with DevicePath. + + @retval EFI_SUCCESS The device path node that describes the SCSI device + specified by Target and Lun was allocated and + returned in DevicePath. + @retval EFI_NOT_FOUND The SCSI devices specified by Target and Lun does + not exist on the SCSI channel. + @retval EFI_INVALID_PARAMETER DevicePath is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate + DevicePath. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SCSI_PASS_THRU_BUILD_DEVICE_PATH)( + IN EFI_SCSI_PASS_THRU_PROTOCOL *This, + IN UINT32 Target, + IN UINT64 Lun, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath + ); + +/** + Used to translate a device path node to a Target ID and LUN. + + @param This Protocol instance pointer. + @param DevicePath A pointer to the device path node that + describes a SCSI device on the SCSI channel. + @param Target A pointer to the Target ID of a SCSI device + on the SCSI channel. + @param Lun A pointer to the LUN of a SCSI device on + the SCSI channel. + + @retval EFI_SUCCESS DevicePath was successfully translated to a + Target ID and LUN, and they were returned + in Target and Lun. + @retval EFI_INVALID_PARAMETER DevicePath is NULL. + @retval EFI_INVALID_PARAMETER Target is NULL. + @retval EFI_INVALID_PARAMETER Lun is NULL. + @retval EFI_UNSUPPORTED This driver does not support the device path + node type in DevicePath. + @retval EFI_NOT_FOUND A valid translation from DevicePath to a + Target ID and LUN does not exist. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SCSI_PASS_THRU_GET_TARGET_LUN)( + IN EFI_SCSI_PASS_THRU_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT UINT32 *Target, + OUT UINT64 *Lun + ); + +/** + Resets a SCSI channel.This operation resets all the + SCSI devices connected to the SCSI channel. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The SCSI channel was reset. + @retval EFI_UNSUPPORTED The SCSI channel does not support + a channel reset operation. + @retval EFI_DEVICE_ERROR A device error occurred while + attempting to reset the SCSI channel. + @retval EFI_TIMEOUT A timeout occurred while attempting + to reset the SCSI channel. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SCSI_PASS_THRU_RESET_CHANNEL)( + IN EFI_SCSI_PASS_THRU_PROTOCOL *This + ); + +/** + Resets a SCSI device that is connected to a SCSI channel. + + @param This Protocol instance pointer. + @param Target The Target ID of the SCSI device to reset. + @param Lun The LUN of the SCSI device to reset. + + @retval EFI_SUCCESS The SCSI device specified by Target and + Lun was reset. + @retval EFI_UNSUPPORTED The SCSI channel does not support a target + reset operation. + @retval EFI_INVALID_PARAMETER Target or Lun are invalid. + @retval EFI_DEVICE_ERROR A device error occurred while attempting + to reset the SCSI device specified by Target + and Lun. + @retval EFI_TIMEOUT A timeout occurred while attempting to reset + the SCSI device specified by Target and Lun. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SCSI_PASS_THRU_RESET_TARGET)( + IN EFI_SCSI_PASS_THRU_PROTOCOL *This, + IN UINT32 Target, + IN UINT64 Lun + ); + +/// +/// The EFI_SCSI_PASS_THRU_PROTOCOL provides information about a SCSI channel and +/// the ability to send SCSI Request Packets to any SCSI device attached to that SCSI channel. The +/// information includes the Target ID of the host controller on the SCSI channel, the attributes of +/// the SCSI channel, the printable name for the SCSI controller, and the printable name of the +/// SCSI channel. +/// +struct _EFI_SCSI_PASS_THRU_PROTOCOL { + /// + /// A pointer to the EFI_SCSI_PASS_THRU_MODE data for this SCSI channel. + /// + EFI_SCSI_PASS_THRU_MODE *Mode; + EFI_SCSI_PASS_THRU_PASSTHRU PassThru; + EFI_SCSI_PASS_THRU_GET_NEXT_DEVICE GetNextDevice; + EFI_SCSI_PASS_THRU_BUILD_DEVICE_PATH BuildDevicePath; + EFI_SCSI_PASS_THRU_GET_TARGET_LUN GetTargetLun; + EFI_SCSI_PASS_THRU_RESET_CHANNEL ResetChannel; + EFI_SCSI_PASS_THRU_RESET_TARGET ResetTarget; +}; + +extern EFI_GUID gEfiScsiPassThruProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/ScsiPassThruExt.h b/sys/contrib/edk2/Include/Protocol/ScsiPassThruExt.h new file mode 100644 index 000000000000..75f8ae6dacf0 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/ScsiPassThruExt.h @@ -0,0 +1,388 @@ +/** @file + EFI_EXT_SCSI_PASS_THRU_PROTOCOL as defined in UEFI 2.0. + This protocol provides services that allow SCSI Pass Thru commands + to be sent to SCSI devices attached to a SCSI channel. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EXT_SCSI_PASS_THROUGH_PROTOCOL_H__ +#define __EXT_SCSI_PASS_THROUGH_PROTOCOL_H__ + +#define EFI_EXT_SCSI_PASS_THRU_PROTOCOL_GUID \ + { \ + 0x143b7632, 0xb81b, 0x4cb7, {0xab, 0xd3, 0xb6, 0x25, 0xa5, 0xb9, 0xbf, 0xfe } \ + } + +typedef struct _EFI_EXT_SCSI_PASS_THRU_PROTOCOL EFI_EXT_SCSI_PASS_THRU_PROTOCOL; + +#define TARGET_MAX_BYTES 0x10 + +#define EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL 0x0001 +#define EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL 0x0002 +#define EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO 0x0004 + +// +// DataDirection +// +#define EFI_EXT_SCSI_DATA_DIRECTION_READ 0 +#define EFI_EXT_SCSI_DATA_DIRECTION_WRITE 1 +#define EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL 2 +// +// HostAdapterStatus +// +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK 0x00 +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND 0x09 +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT 0x0b +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_MESSAGE_REJECT 0x0d +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_RESET 0x0e +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR 0x0f +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED 0x10 +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT 0x11 +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN 0x12 +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_FREE 0x13 +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PHASE_ERROR 0x14 +#define EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER 0x7f +// +// TargetStatus +// +#define EFI_EXT_SCSI_STATUS_TARGET_GOOD 0x00 +#define EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION 0x02 +#define EFI_EXT_SCSI_STATUS_TARGET_CONDITION_MET 0x04 +#define EFI_EXT_SCSI_STATUS_TARGET_BUSY 0x08 +#define EFI_EXT_SCSI_STATUS_TARGET_INTERMEDIATE 0x10 +#define EFI_EXT_SCSI_STATUS_TARGET_INTERMEDIATE_CONDITION_MET 0x14 +#define EFI_EXT_SCSI_STATUS_TARGET_RESERVATION_CONFLICT 0x18 +#define EFI_EXT_SCSI_STATUS_TARGET_TASK_SET_FULL 0x28 +#define EFI_EXT_SCSI_STATUS_TARGET_ACA_ACTIVE 0x30 +#define EFI_EXT_SCSI_STATUS_TARGET_TASK_ABORTED 0x40 + +typedef struct { + /// + /// The Target ID of the host adapter on the SCSI channel. + /// + UINT32 AdapterId; + /// + /// Additional information on the attributes of the SCSI channel. + /// + UINT32 Attributes; + /// + /// Supplies the alignment requirement for any buffer used in a data transfer. + /// + UINT32 IoAlign; +} EFI_EXT_SCSI_PASS_THRU_MODE; + +typedef struct { + /// + /// The timeout, in 100 ns units, to use for the execution of this SCSI + /// Request Packet. A Timeout value of 0 means that this function + /// will wait indefinitely for the SCSI Request Packet to execute. If + /// Timeout is greater than zero, then this function will return + /// EFI_TIMEOUT if the time required to execute the SCSI + /// Request Packet is greater than Timeout. + /// + UINT64 Timeout; + /// + /// A pointer to the data buffer to transfer between the SCSI + /// controller and the SCSI device for read and bidirectional commands. + /// + VOID *InDataBuffer; + /// + /// A pointer to the data buffer to transfer between the SCSI + /// controller and the SCSI device for write or bidirectional commands. + /// + VOID *OutDataBuffer; + /// + /// A pointer to the sense data that was generated by the execution of + /// the SCSI Request Packet. + /// + VOID *SenseData; + /// + /// A pointer to buffer that contains the Command Data Block to + /// send to the SCSI device specified by Target and Lun. + /// + VOID *Cdb; + /// + /// On Input, the size, in bytes, of InDataBuffer. On output, the + /// number of bytes transferred between the SCSI controller and the SCSI device. + /// + UINT32 InTransferLength; + /// + /// On Input, the size, in bytes of OutDataBuffer. On Output, the + /// Number of bytes transferred between SCSI Controller and the SCSI device. + /// + UINT32 OutTransferLength; + /// + /// The length, in bytes, of the buffer Cdb. The standard values are 6, + /// 10, 12, and 16, but other values are possible if a variable length CDB is used. + /// + UINT8 CdbLength; + /// + /// The direction of the data transfer. 0 for reads, 1 for writes. A + /// value of 2 is Reserved for Bi-Directional SCSI commands. + /// + UINT8 DataDirection; + /// + /// The status of the host adapter specified by This when the SCSI + /// Request Packet was executed on the target device. + /// + UINT8 HostAdapterStatus; + /// + /// The status returned by the device specified by Target and Lun + /// when the SCSI Request Packet was executed. + /// + UINT8 TargetStatus; + /// + /// On input, the length in bytes of the SenseData buffer. On + /// output, the number of bytes written to the SenseData buffer. + /// + UINT8 SenseDataLength; +} EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET; + +/** + Sends a SCSI Request Packet to a SCSI device that is attached to the SCSI channel. This function + supports both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the + nonblocking I/O functionality is optional. + + @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. + @param Target The Target is an array of size TARGET_MAX_BYTES and it represents + the id of the SCSI device to send the SCSI Request Packet. Each + transport driver may choose to utilize a subset of this size to suit the needs + of transport target representation. For example, a Fibre Channel driver + may use only 8 bytes (WWN) to represent an FC target. + @param Lun The LUN of the SCSI device to send the SCSI Request Packet. + @param Packet A pointer to the SCSI Request Packet to send to the SCSI device + specified by Target and Lun. + @param Event If nonblocking I/O is not supported then Event is ignored, and blocking + I/O is performed. If Event is NULL, then blocking I/O is performed. If + Event is not NULL and non blocking I/O is supported, then + nonblocking I/O is performed, and Event will be signaled when the + SCSI Request Packet completes. + + @retval EFI_SUCCESS The SCSI Request Packet was sent by the host. For bi-directional + commands, InTransferLength bytes were transferred from + InDataBuffer. For write and bi-directional commands, + OutTransferLength bytes were transferred by + OutDataBuffer. + @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was not executed. The number of bytes that + could be transferred is returned in InTransferLength. For write + and bi-directional commands, OutTransferLength bytes were + transferred by OutDataBuffer. + @retval EFI_NOT_READY The SCSI Request Packet could not be sent because there are too many + SCSI Request Packets already queued. The caller may retry again later. + @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the SCSI Request + Packet. + @retval EFI_INVALID_PARAMETER Target, Lun, or the contents of ScsiRequestPacket are invalid. + @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet is not supported + by the host adapter. This includes the case of Bi-directional SCSI + commands not supported by the implementation. The SCSI Request + Packet was not sent, so no additional status information is available. + @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI Request Packet to execute. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_EXT_SCSI_PASS_THRU_PASSTHRU)( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN UINT8 *Target, + IN UINT64 Lun, + IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, + IN EFI_EVENT Event OPTIONAL + ); + +/** + Used to retrieve the list of legal Target IDs and LUNs for SCSI devices on a SCSI channel. These + can either be the list SCSI devices that are actually present on the SCSI channel, or the list of legal + Target Ids and LUNs for the SCSI channel. Regardless, the caller of this function must probe the + Target ID and LUN returned to see if a SCSI device is actually present at that location on the SCSI + channel. + + @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. + @param Target On input, a pointer to the Target ID (an array of size + TARGET_MAX_BYTES) of a SCSI device present on the SCSI channel. + On output, a pointer to the Target ID (an array of + TARGET_MAX_BYTES) of the next SCSI device present on a SCSI + channel. An input value of 0xF(all bytes in the array are 0xF) in the + Target array retrieves the Target ID of the first SCSI device present on a + SCSI channel. + @param Lun On input, a pointer to the LUN of a SCSI device present on the SCSI + channel. On output, a pointer to the LUN of the next SCSI device present + on a SCSI channel. + + @retval EFI_SUCCESS The Target ID and LUN of the next SCSI device on the SCSI + channel was returned in Target and Lun. + @retval EFI_INVALID_PARAMETER Target array is not all 0xF, and Target and Lun were + not returned on a previous call to GetNextTargetLun(). + @retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI channel. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET_LUN)( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN OUT UINT8 **Target, + IN OUT UINT64 *Lun + ); + +/** + Used to allocate and build a device path node for a SCSI device on a SCSI channel. + + @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. + @param Target The Target is an array of size TARGET_MAX_BYTES and it specifies the + Target ID of the SCSI device for which a device path node is to be + allocated and built. Transport drivers may chose to utilize a subset of + this size to suit the representation of targets. For example, a Fibre + Channel driver may use only 8 bytes (WWN) in the array to represent a + FC target. + @param Lun The LUN of the SCSI device for which a device path node is to be + allocated and built. + @param DevicePath A pointer to a single device path node that describes the SCSI device + specified by Target and Lun. This function is responsible for + allocating the buffer DevicePath with the boot service + AllocatePool(). It is the caller's responsibility to free + DevicePath when the caller is finished with DevicePath. + + @retval EFI_SUCCESS The device path node that describes the SCSI device specified by + Target and Lun was allocated and returned in + DevicePath. + @retval EFI_INVALID_PARAMETER DevicePath is NULL. + @retval EFI_NOT_FOUND The SCSI devices specified by Target and Lun does not exist + on the SCSI channel. + @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate DevicePath. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_EXT_SCSI_PASS_THRU_BUILD_DEVICE_PATH)( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN UINT8 *Target, + IN UINT64 Lun, + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath + ); + +/** + Used to translate a device path node to a Target ID and LUN. + + @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. + @param DevicePath A pointer to a single device path node that describes the SCSI device + on the SCSI channel. + @param Target A pointer to the Target Array which represents the ID of a SCSI device + on the SCSI channel. + @param Lun A pointer to the LUN of a SCSI device on the SCSI channel. + + @retval EFI_SUCCESS DevicePath was successfully translated to a Target ID and + LUN, and they were returned in Target and Lun. + @retval EFI_INVALID_PARAMETER DevicePath or Target or Lun is NULL. + @retval EFI_NOT_FOUND A valid translation from DevicePath to a Target ID and LUN + does not exist. + @retval EFI_UNSUPPORTED This driver does not support the device path node type in + DevicePath. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_EXT_SCSI_PASS_THRU_GET_TARGET_LUN)( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT UINT8 **Target, + OUT UINT64 *Lun + ); + +/** + Resets a SCSI channel. This operation resets all the SCSI devices connected to the SCSI channel. + + @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. + + @retval EFI_SUCCESS The SCSI channel was reset. + @retval EFI_DEVICE_ERROR A device error occurred while attempting to reset the SCSI channel. + @retval EFI_TIMEOUT A timeout occurred while attempting to reset the SCSI channel. + @retval EFI_UNSUPPORTED The SCSI channel does not support a channel reset operation. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_EXT_SCSI_PASS_THRU_RESET_CHANNEL)( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This + ); + +/** + Resets a SCSI logical unit that is connected to a SCSI channel. + + @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. + @param Target The Target is an array of size TARGET_MAX_BYTE and it represents the + target port ID of the SCSI device containing the SCSI logical unit to + reset. Transport drivers may chose to utilize a subset of this array to suit + the representation of their targets. + @param Lun The LUN of the SCSI device to reset. + + @retval EFI_SUCCESS The SCSI device specified by Target and Lun was reset. + @retval EFI_INVALID_PARAMETER Target or Lun is NULL. + @retval EFI_TIMEOUT A timeout occurred while attempting to reset the SCSI device + specified by Target and Lun. + @retval EFI_UNSUPPORTED The SCSI channel does not support a target reset operation. + @retval EFI_DEVICE_ERROR A device error occurred while attempting to reset the SCSI device + specified by Target and Lun. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_EXT_SCSI_PASS_THRU_RESET_TARGET_LUN)( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN UINT8 *Target, + IN UINT64 Lun + ); + +/** + Used to retrieve the list of legal Target IDs for SCSI devices on a SCSI channel. These can either + be the list SCSI devices that are actually present on the SCSI channel, or the list of legal Target IDs + for the SCSI channel. Regardless, the caller of this function must probe the Target ID returned to + see if a SCSI device is actually present at that location on the SCSI channel. + + @param This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance. + @param Target (TARGET_MAX_BYTES) of a SCSI device present on the SCSI channel. + On output, a pointer to the Target ID (an array of + TARGET_MAX_BYTES) of the next SCSI device present on a SCSI + channel. An input value of 0xF(all bytes in the array are 0xF) in the + Target array retrieves the Target ID of the first SCSI device present on a + SCSI channel. + + @retval EFI_SUCCESS The Target ID of the next SCSI device on the SCSI + channel was returned in Target. + @retval EFI_INVALID_PARAMETER Target or Lun is NULL. + @retval EFI_TIMEOUT Target array is not all 0xF, and Target was not + returned on a previous call to GetNextTarget(). + @retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI channel. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET)( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN OUT UINT8 **Target + ); + +/// +/// The EFI_EXT_SCSI_PASS_THRU_PROTOCOL provides information about a SCSI channel +/// and the ability to send SCI Request Packets to any SCSI device attached to +/// that SCSI channel. The information includes the Target ID of the host controller +/// on the SCSI channel and the attributes of the SCSI channel. +/// +struct _EFI_EXT_SCSI_PASS_THRU_PROTOCOL { + /// + /// A pointer to the EFI_EXT_SCSI_PASS_THRU_MODE data for this SCSI channel. + /// + EFI_EXT_SCSI_PASS_THRU_MODE *Mode; + EFI_EXT_SCSI_PASS_THRU_PASSTHRU PassThru; + EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET_LUN GetNextTargetLun; + EFI_EXT_SCSI_PASS_THRU_BUILD_DEVICE_PATH BuildDevicePath; + EFI_EXT_SCSI_PASS_THRU_GET_TARGET_LUN GetTargetLun; + EFI_EXT_SCSI_PASS_THRU_RESET_CHANNEL ResetChannel; + EFI_EXT_SCSI_PASS_THRU_RESET_TARGET_LUN ResetTargetLun; + EFI_EXT_SCSI_PASS_THRU_GET_NEXT_TARGET GetNextTarget; +}; + +extern EFI_GUID gEfiExtScsiPassThruProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Security.h b/sys/contrib/edk2/Include/Protocol/Security.h new file mode 100644 index 000000000000..2c48dd2a71ea --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Security.h @@ -0,0 +1,97 @@ +/** @file + Security Architectural Protocol as defined in PI Specification VOLUME 2 DXE + + Used to provide Security services. Specifically, dependening upon the + authentication state of a discovered driver in a Firmware Volume, the + portable DXE Core Dispatcher will call into the Security Architectural + Protocol (SAP) with the authentication state of the driver. + + This call-out allows for OEM-specific policy decisions to be made, such + as event logging for attested boots, locking flash in response to discovering + an unsigned driver or failed signature check, or other exception response. + + The SAP can also change system behavior by having the DXE core put a driver + in the Schedule-On-Request (SOR) state. This will allow for later disposition + of the driver by platform agent, such as Platform BDS. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_SECURITY_H__ +#define __ARCH_PROTOCOL_SECURITY_H__ + +/// +/// Global ID for the Security Code Architectural Protocol +/// +#define EFI_SECURITY_ARCH_PROTOCOL_GUID \ + { 0xA46423E3, 0x4617, 0x49f1, {0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 } } + +typedef struct _EFI_SECURITY_ARCH_PROTOCOL EFI_SECURITY_ARCH_PROTOCOL; + +/** + The EFI_SECURITY_ARCH_PROTOCOL (SAP) is used to abstract platform-specific + policy from the DXE core response to an attempt to use a file that returns a + given status for the authentication check from the section extraction protocol. + + The possible responses in a given SAP implementation may include locking + flash upon failure to authenticate, attestation logging for all signed drivers, + and other exception operations. The File parameter allows for possible logging + within the SAP of the driver. + + If File is NULL, then EFI_INVALID_PARAMETER is returned. + + If the file specified by File with an authentication status specified by + AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned. + + If the file specified by File with an authentication status specified by + AuthenticationStatus is not safe for the DXE Core to use under any circumstances, + then EFI_ACCESS_DENIED is returned. + + If the file specified by File with an authentication status specified by + AuthenticationStatus is not safe for the DXE Core to use right now, but it + might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is + returned. + + @param This The EFI_SECURITY_ARCH_PROTOCOL instance. + @param AuthenticationStatus + This is the authentication type returned from the Section + Extraction protocol. See the Section Extraction Protocol + Specification for details on this type. + @param File This is a pointer to the device path of the file that is + being dispatched. This will optionally be used for logging. + + @retval EFI_SUCCESS The file specified by File did authenticate, and the + platform policy dictates that the DXE Core may use File. + @retval EFI_INVALID_PARAMETER Driver is NULL. + @retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and + the platform policy dictates that File should be placed + in the untrusted state. A file may be promoted from + the untrusted to the trusted state at a future time + with a call to the Trust() DXE Service. + @retval EFI_ACCESS_DENIED The file specified by File did not authenticate, and + the platform policy dictates that File should not be + used for any purpose. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SECURITY_FILE_AUTHENTICATION_STATE)( + IN CONST EFI_SECURITY_ARCH_PROTOCOL *This, + IN UINT32 AuthenticationStatus, + IN CONST EFI_DEVICE_PATH_PROTOCOL *File + ); + +/// +/// The EFI_SECURITY_ARCH_PROTOCOL is used to abstract platform-specific policy +/// from the DXE core. This includes locking flash upon failure to authenticate, +/// attestation logging, and other exception operations. +/// +struct _EFI_SECURITY_ARCH_PROTOCOL { + EFI_SECURITY_FILE_AUTHENTICATION_STATE FileAuthenticationState; +}; + +extern EFI_GUID gEfiSecurityArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Security2.h b/sys/contrib/edk2/Include/Protocol/Security2.h new file mode 100644 index 000000000000..9938afe02720 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Security2.h @@ -0,0 +1,101 @@ +/** @file + Security2 Architectural Protocol as defined in PI Specification1.2.1 VOLUME 2 DXE + + Abstracts security-specific functions from the DXE Foundation of UEFI Image Verification, + Trusted Computing Group (TCG) measured boot, and User Identity policy for image loading and + consoles. This protocol must be produced by a boot service or runtime DXE driver. + + This protocol is optional and must be published prior to the EFI_SECURITY_ARCH_PROTOCOL. + As a result, the same driver must publish both of these interfaces. + + When both Security and Security2 Architectural Protocols are published, LoadImage must use + them in accordance with the following rules: + The Security2 protocol must be used on every image being loaded. + The Security protocol must be used after the Securiy2 protocol and only on images that + have been read using Firmware Volume protocol. + + When only Security architectural protocol is published, LoadImage must use it on every image + being loaded. + + Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_SECURITY2_H__ +#define __ARCH_PROTOCOL_SECURITY2_H__ + +/// +/// Global ID for the Security2 Code Architectural Protocol +/// +#define EFI_SECURITY2_ARCH_PROTOCOL_GUID \ + { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } } + +typedef struct _EFI_SECURITY2_ARCH_PROTOCOL EFI_SECURITY2_ARCH_PROTOCOL; + +/** + The DXE Foundation uses this service to measure and/or verify a UEFI image. + + This service abstracts the invocation of Trusted Computing Group (TCG) measured boot, UEFI + Secure boot, and UEFI User Identity infrastructure. For the former two, the DXE Foundation + invokes the FileAuthentication() with a DevicePath and corresponding image in + FileBuffer memory. The TCG measurement code will record the FileBuffer contents into the + appropriate PCR. The image verification logic will confirm the integrity and provenance of the + image in FileBuffer of length FileSize . The origin of the image will be DevicePath in + these cases. + If the FileBuffer is NULL, the interface will determine if the DevicePath can be connected + in order to support the User Identification policy. + + @param This The EFI_SECURITY2_ARCH_PROTOCOL instance. + @param File A pointer to the device path of the file that is + being dispatched. This will optionally be used for logging. + @param FileBuffer A pointer to the buffer with the UEFI file image. + @param FileSize The size of the file. + @param BootPolicy A boot policy that was used to call LoadImage() UEFI service. If + FileAuthentication() is invoked not from the LoadImage(), + BootPolicy must be set to FALSE. + + @retval EFI_SUCCESS The file specified by DevicePath and non-NULL + FileBuffer did authenticate, and the platform policy dictates + that the DXE Foundation may use the file. + @retval EFI_SUCCESS The device path specified by NULL device path DevicePath + and non-NULL FileBuffer did authenticate, and the platform + policy dictates that the DXE Foundation may execute the image in + FileBuffer. + @retval EFI_SUCCESS FileBuffer is NULL and current user has permission to start + UEFI device drivers on the device path specified by DevicePath. + @retval EFI_SECURITY_VIOLATION The file specified by DevicePath and FileBuffer did not + authenticate, and the platform policy dictates that the file should be + placed in the untrusted state. The image has been added to the file + execution table. + @retval EFI_ACCESS_DENIED The file specified by File and FileBuffer did not + authenticate, and the platform policy dictates that the DXE + Foundation may not use File. + @retval EFI_SECURITY_VIOLATION FileBuffer is NULL and the user has no + permission to start UEFI device drivers on the device path specified + by DevicePath. + @retval EFI_SECURITY_VIOLATION FileBuffer is not NULL and the user has no permission to load + drivers from the device path specified by DevicePath. The + image has been added into the list of the deferred images. +**/ +typedef EFI_STATUS (EFIAPI *EFI_SECURITY2_FILE_AUTHENTICATION)( + IN CONST EFI_SECURITY2_ARCH_PROTOCOL *This, + IN CONST EFI_DEVICE_PATH_PROTOCOL *File OPTIONAL, + IN VOID *FileBuffer, + IN UINTN FileSize, + IN BOOLEAN BootPolicy + ); + +/// +/// The EFI_SECURITY2_ARCH_PROTOCOL is used to abstract platform-specific policy from the +/// DXE Foundation. This includes measuring the PE/COFF image prior to invoking, comparing the +/// image against a policy (whether a white-list/black-list of public image verification keys +/// or registered hashes). +/// +struct _EFI_SECURITY2_ARCH_PROTOCOL { + EFI_SECURITY2_FILE_AUTHENTICATION FileAuthentication; +}; + +extern EFI_GUID gEfiSecurity2ArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/SerialIo.h b/sys/contrib/edk2/Include/Protocol/SerialIo.h new file mode 100644 index 000000000000..ccaf602dc9a9 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/SerialIo.h @@ -0,0 +1,309 @@ +/** @file + Serial IO protocol as defined in the UEFI 2.0 specification. + + Abstraction of a basic serial device. Targeted at 16550 UART, but + could be much more generic. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SERIAL_IO_PROTOCOL_H__ +#define __SERIAL_IO_PROTOCOL_H__ + +#define EFI_SERIAL_IO_PROTOCOL_GUID \ + { \ + 0xBB25CF6F, 0xF1D4, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD } \ + } + +#define EFI_SERIAL_TERMINAL_DEVICE_TYPE_GUID \ + { \ + 0X6AD9A60F, 0X5815, 0X4C7C, { 0X8A, 0X10, 0X50, 0X53, 0XD2, 0XBF, 0X7A, 0X1B } \ + } + +/// +/// Protocol GUID defined in EFI1.1. +/// +#define SERIAL_IO_PROTOCOL EFI_SERIAL_IO_PROTOCOL_GUID + +typedef struct _EFI_SERIAL_IO_PROTOCOL EFI_SERIAL_IO_PROTOCOL; + +/// +/// Backward-compatible with EFI1.1. +/// +typedef EFI_SERIAL_IO_PROTOCOL SERIAL_IO_INTERFACE; + +/// +/// Parity type that is computed or checked as each character is transmitted or received. If the +/// device does not support parity, the value is the default parity value. +/// +typedef enum { + DefaultParity, + NoParity, + EvenParity, + OddParity, + MarkParity, + SpaceParity +} EFI_PARITY_TYPE; + +/// +/// Stop bits type +/// +typedef enum { + DefaultStopBits, + OneStopBit, + OneFiveStopBits, + TwoStopBits +} EFI_STOP_BITS_TYPE; + +// +// define for Control bits, grouped by read only, write only, and read write +// +// +// Read Only +// +#define EFI_SERIAL_CLEAR_TO_SEND 0x00000010 +#define EFI_SERIAL_DATA_SET_READY 0x00000020 +#define EFI_SERIAL_RING_INDICATE 0x00000040 +#define EFI_SERIAL_CARRIER_DETECT 0x00000080 +#define EFI_SERIAL_INPUT_BUFFER_EMPTY 0x00000100 +#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY 0x00000200 + +// +// Write Only +// +#define EFI_SERIAL_REQUEST_TO_SEND 0x00000002 +#define EFI_SERIAL_DATA_TERMINAL_READY 0x00000001 + +// +// Read Write +// +#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE 0x00001000 +#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE 0x00002000 +#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x00004000 + +// +// Serial IO Member Functions +// + +/** + Reset the serial device. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The serial device could not be reset. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_RESET)( + IN EFI_SERIAL_IO_PROTOCOL *This + ); + +/** + Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, + data bits, and stop bits on a serial device. + + @param This Protocol instance pointer. + @param BaudRate The requested baud rate. A BaudRate value of 0 will use the + device's default interface speed. + @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the + serial interface. A ReceiveFifoDepth value of 0 will use + the device's default FIFO depth. + @param Timeout The requested time out for a single character in microseconds. + This timeout applies to both the transmit and receive side of the + interface. A Timeout value of 0 will use the device's default time + out value. + @param Parity The type of parity to use on this serial device. A Parity value of + DefaultParity will use the device's default parity value. + @param DataBits The number of data bits to use on the serial device. A DataBits + vaule of 0 will use the device's default data bit setting. + @param StopBits The number of stop bits to use on this serial device. A StopBits + value of DefaultStopBits will use the device's default number of + stop bits. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_INVALID_PARAMETER One or more attributes has an unsupported value. + @retval EFI_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_SET_ATTRIBUTES)( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN UINT64 BaudRate, + IN UINT32 ReceiveFifoDepth, + IN UINT32 Timeout, + IN EFI_PARITY_TYPE Parity, + IN UINT8 DataBits, + IN EFI_STOP_BITS_TYPE StopBits + ); + +/** + Set the control bits on a serial device + + @param This Protocol instance pointer. + @param Control Set the bits of Control that are settable. + + @retval EFI_SUCCESS The new control bits were set on the serial device. + @retval EFI_UNSUPPORTED The serial device does not support this operation. + @retval EFI_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_SET_CONTROL_BITS)( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN UINT32 Control + ); + +/** + Retrieves the status of thecontrol bits on a serial device + + @param This Protocol instance pointer. + @param Control A pointer to return the current Control signals from the serial device. + + @retval EFI_SUCCESS The control bits were read from the serial device. + @retval EFI_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_GET_CONTROL_BITS)( + IN EFI_SERIAL_IO_PROTOCOL *This, + OUT UINT32 *Control + ); + +/** + Writes data to a serial device. + + @param This Protocol instance pointer. + @param BufferSize On input, the size of the Buffer. On output, the amount of + data actually written. + @param Buffer The buffer of data to write + + @retval EFI_SUCCESS The data was written. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_TIMEOUT The data write was stopped due to a timeout. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_WRITE)( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +/** + Writes data to a serial device. + + @param This Protocol instance pointer. + @param BufferSize On input, the size of the Buffer. On output, the amount of + data returned in Buffer. + @param Buffer The buffer to return the data into. + + @retval EFI_SUCCESS The data was read. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_TIMEOUT The data write was stopped due to a timeout. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_READ)( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +/** + @par Data Structure Description: + The data values in SERIAL_IO_MODE are read-only and are updated by the code + that produces the SERIAL_IO_PROTOCOL member functions. + + @param ControlMask + A mask for the Control bits that the device supports. The device + must always support the Input Buffer Empty control bit. + + @param TimeOut + If applicable, the number of microseconds to wait before timing out + a Read or Write operation. + + @param BaudRate + If applicable, the current baud rate setting of the device; otherwise, + baud rate has the value of zero to indicate that device runs at the + device's designed speed. + + @param ReceiveFifoDepth + The number of characters the device will buffer on input + + @param DataBits + The number of characters the device will buffer on input + + @param Parity + If applicable, this is the EFI_PARITY_TYPE that is computed or + checked as each character is transmitted or reveived. If the device + does not support parity the value is the default parity value. + + @param StopBits + If applicable, the EFI_STOP_BITS_TYPE number of stop bits per + character. If the device does not support stop bits the value is + the default stop bit values. + +**/ +typedef struct { + UINT32 ControlMask; + + // + // current Attributes + // + UINT32 Timeout; + UINT64 BaudRate; + UINT32 ReceiveFifoDepth; + UINT32 DataBits; + UINT32 Parity; + UINT32 StopBits; +} EFI_SERIAL_IO_MODE; + +#define EFI_SERIAL_IO_PROTOCOL_REVISION 0x00010000 +#define EFI_SERIAL_IO_PROTOCOL_REVISION1p1 0x00010001 +#define SERIAL_IO_INTERFACE_REVISION EFI_SERIAL_IO_PROTOCOL_REVISION + +/// +/// The Serial I/O protocol is used to communicate with UART-style serial devices. +/// These can be standard UART serial ports in PC-AT systems, serial ports attached +/// to a USB interface, or potentially any character-based I/O device. +/// +struct _EFI_SERIAL_IO_PROTOCOL { + /// + /// The revision to which the EFI_SERIAL_IO_PROTOCOL adheres. All future revisions + /// must be backwards compatible. If a future version is not backwards compatible, + /// it is not the same GUID. + /// + UINT32 Revision; + EFI_SERIAL_RESET Reset; + EFI_SERIAL_SET_ATTRIBUTES SetAttributes; + EFI_SERIAL_SET_CONTROL_BITS SetControl; + EFI_SERIAL_GET_CONTROL_BITS GetControl; + EFI_SERIAL_WRITE Write; + EFI_SERIAL_READ Read; + /// + /// Pointer to SERIAL_IO_MODE data. + /// + EFI_SERIAL_IO_MODE *Mode; + /// + /// Pointer to a GUID identifying the device connected to the serial port. + /// This field is NULL when the protocol is installed by the serial port + /// driver and may be populated by a platform driver for a serial port + /// with a known device attached. The field will remain NULL if there is + /// no platform serial device identification information available. + /// + CONST EFI_GUID *DeviceTypeGuid; // Revision 1.1 +}; + +extern EFI_GUID gEfiSerialIoProtocolGuid; +extern EFI_GUID gEfiSerialTerminalDeviceTypeGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/ServiceBinding.h b/sys/contrib/edk2/Include/Protocol/ServiceBinding.h new file mode 100644 index 000000000000..b9a0d1be739f --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/ServiceBinding.h @@ -0,0 +1,88 @@ +/** @file + UEFI Service Binding Protocol is defined in UEFI specification. + + The file defines the generic Service Binding Protocol functions. + It provides services that are required to create and destroy child + handles that support a given set of protocols. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_SERVICE_BINDING_H__ +#define __EFI_SERVICE_BINDING_H__ + +/// +/// Forward reference for pure ANSI compatability +/// +typedef struct _EFI_SERVICE_BINDING_PROTOCOL EFI_SERVICE_BINDING_PROTOCOL; + +/** + Creates a child handle and installs a protocol. + + The CreateChild() function installs a protocol on ChildHandle. + If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle. + If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle. + + @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param ChildHandle Pointer to the handle of the child to create. If it is NULL, + then a new handle is created. If it is a pointer to an existing UEFI handle, + then the protocol is added to the existing UEFI handle. + + @retval EFI_SUCCES The protocol was added to ChildHandle. + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create + the child + @retval other The child handle was not created + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SERVICE_BINDING_CREATE_CHILD)( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN OUT EFI_HANDLE *ChildHandle + ); + +/** + Destroys a child handle with a protocol installed on it. + + The DestroyChild() function does the opposite of CreateChild(). It removes a protocol + that was installed by CreateChild() from ChildHandle. If the removed protocol is the + last protocol on ChildHandle, then ChildHandle is destroyed. + + @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param ChildHandle Handle of the child to destroy + + @retval EFI_SUCCES The protocol was removed from ChildHandle. + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed. + @retval EFI_INVALID_PARAMETER Child handle is NULL. + @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle + because its services are being used. + @retval other The child handle was not destroyed + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SERVICE_BINDING_DESTROY_CHILD)( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE ChildHandle + ); + +/// +/// The EFI_SERVICE_BINDING_PROTOCOL provides member functions to create and destroy +/// child handles. A driver is responsible for adding protocols to the child handle +/// in CreateChild() and removing protocols in DestroyChild(). It is also required +/// that the CreateChild() function opens the parent protocol BY_CHILD_CONTROLLER +/// to establish the parent-child relationship, and closes the protocol in DestroyChild(). +/// The pseudo code for CreateChild() and DestroyChild() is provided to specify the +/// required behavior, not to specify the required implementation. Each consumer of +/// a software protocol is responsible for calling CreateChild() when it requires the +/// protocol and calling DestroyChild() when it is finished with that protocol. +/// +struct _EFI_SERVICE_BINDING_PROTOCOL { + EFI_SERVICE_BINDING_CREATE_CHILD CreateChild; + EFI_SERVICE_BINDING_DESTROY_CHILD DestroyChild; +}; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/SimpleFileSystem.h b/sys/contrib/edk2/Include/Protocol/SimpleFileSystem.h new file mode 100644 index 000000000000..7d54f28f7036 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/SimpleFileSystem.h @@ -0,0 +1,553 @@ +/** @file + SimpleFileSystem protocol as defined in the UEFI 2.0 specification. + + The SimpleFileSystem protocol is the programmatic access to the FAT (12,16,32) + file system specified in UEFI 2.0. It can also be used to abstract a file + system other than FAT. + + UEFI 2.0 can boot from any valid EFI image contained in a SimpleFileSystem. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SIMPLE_FILE_SYSTEM_H__ +#define __SIMPLE_FILE_SYSTEM_H__ + +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + { \ + 0x964e5b22, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +typedef struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL EFI_SIMPLE_FILE_SYSTEM_PROTOCOL; + +typedef struct _EFI_FILE_PROTOCOL EFI_FILE_PROTOCOL; +typedef struct _EFI_FILE_PROTOCOL *EFI_FILE_HANDLE; + +/// +/// Protocol GUID name defined in EFI1.1. +/// +#define SIMPLE_FILE_SYSTEM_PROTOCOL EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID + +/// +/// Protocol name defined in EFI1.1. +/// +typedef EFI_SIMPLE_FILE_SYSTEM_PROTOCOL EFI_FILE_IO_INTERFACE; +typedef EFI_FILE_PROTOCOL EFI_FILE; + +/** + Open the root directory on a volume. + + @param This A pointer to the volume to open the root directory. + @param Root A pointer to the location to return the opened file handle for the + root directory. + + @retval EFI_SUCCESS The device was opened. + @retval EFI_UNSUPPORTED This volume does not support the requested file system type. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no + longer supported. Any existing file handles for this volume are + no longer valid. To access the files on the new medium, the + volume must be reopened with OpenVolume(). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME)( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ); + +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION 0x00010000 + +/// +/// Revision defined in EFI1.1 +/// +#define EFI_FILE_IO_INTERFACE_REVISION EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION + +struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL { + /// + /// The version of the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. The version + /// specified by this specification is 0x00010000. All future revisions + /// must be backwards compatible. + /// + UINT64 Revision; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume; +}; + +/** + Opens a new file relative to the source file's location. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to the source location. This would typically be an open + handle to a directory. + @param NewHandle A pointer to the location to return the opened handle for the new + file. + @param FileName The Null-terminated string of the name of the file to be opened. + The file name may contain the following path modifiers: "\", ".", + and "..". + @param OpenMode The mode to open the file. The only valid combinations that the + file may be opened with are: Read, Read/Write, or Create/Read/Write. + @param Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the + attribute bits for the newly created file. + + @retval EFI_SUCCESS The file was opened. + @retval EFI_NOT_FOUND The specified file could not be found on the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no + longer supported. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write + when the media is write-protected. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_OPEN)( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +// +// Open modes +// +#define EFI_FILE_MODE_READ 0x0000000000000001ULL +#define EFI_FILE_MODE_WRITE 0x0000000000000002ULL +#define EFI_FILE_MODE_CREATE 0x8000000000000000ULL + +// +// File attributes +// +#define EFI_FILE_READ_ONLY 0x0000000000000001ULL +#define EFI_FILE_HIDDEN 0x0000000000000002ULL +#define EFI_FILE_SYSTEM 0x0000000000000004ULL +#define EFI_FILE_RESERVED 0x0000000000000008ULL +#define EFI_FILE_DIRECTORY 0x0000000000000010ULL +#define EFI_FILE_ARCHIVE 0x0000000000000020ULL +#define EFI_FILE_VALID_ATTR 0x0000000000000037ULL + +/** + Closes a specified file handle. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to close. + + @retval EFI_SUCCESS The file was closed. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_CLOSE)( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Close and delete the file handle. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the + handle to the file to delete. + + @retval EFI_SUCCESS The file was closed and deleted, and the handle was closed. + @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_DELETE)( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Reads data from a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to read data from. + @param BufferSize On input, the size of the Buffer. On output, the amount of data + returned in Buffer. In both cases, the size is measured in bytes. + @param Buffer The buffer into which the data is read. + + @retval EFI_SUCCESS Data was read. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file. + @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory + entry. BufferSize has been updated with the size + needed to complete the request. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_READ)( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +/** + Writes data to a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to write data to. + @param BufferSize On input, the size of the Buffer. On output, the amount of data + actually written. In both cases, the size is measured in bytes. + @param Buffer The buffer of data to write. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Writes to open directory files are not supported. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The file or medium is write-protected. + @retval EFI_ACCESS_DENIED The file was opened read only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_WRITE)( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +/** + Sets a file's current position. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the + file handle to set the requested position on. + @param Position The byte position from the start of the file to set. + + @retval EFI_SUCCESS The position was set. + @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open + directories. + @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_SET_POSITION)( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ); + +/** + Returns a file's current position. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to get the current position on. + @param Position The address to return the file's current position value. + + @retval EFI_SUCCESS The position was returned. + @retval EFI_UNSUPPORTED The request is not valid on open directories. + @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_GET_POSITION)( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ); + +/** + Returns information about a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle the requested information is for. + @param InformationType The type identifier for the information being requested. + @param BufferSize On input, the size of Buffer. On output, the amount of data + returned in Buffer. In both cases, the size is measured in bytes. + @param Buffer A pointer to the data buffer to return. The buffer's type is + indicated by InformationType. + + @retval EFI_SUCCESS The information was returned. + @retval EFI_UNSUPPORTED The InformationType is not known. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. + BufferSize has been updated with the size needed to complete + the request. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_GET_INFO)( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +/** + Sets information about a file. + + @param File A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle the information is for. + @param InformationType The type identifier for the information being set. + @param BufferSize The size, in bytes, of Buffer. + @param Buffer A pointer to the data buffer to write. The buffer's type is + indicated by InformationType. + + @retval EFI_SUCCESS The information was set. + @retval EFI_UNSUPPORTED The InformationType is not known. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_INFO_ID and the media is + read-only. + @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID + and the media is read only. + @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID + and the media is read-only. + @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a + file that is already present. + @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY + Attribute. + @retval EFI_ACCESS_DENIED An attempt is being made to change the size of a directory. + @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the file was opened + read-only and an attempt is being made to modify a field + other than Attribute. + @retval EFI_VOLUME_FULL The volume is full. + @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type indicated + by InformationType. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_SET_INFO)( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +/** + Flushes all modified data associated with a file to a device. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to flush. + + @retval EFI_SUCCESS The data was flushed. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The file or medium is write-protected. + @retval EFI_ACCESS_DENIED The file was opened read-only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_FLUSH)( + IN EFI_FILE_PROTOCOL *This + ); + +typedef struct { + // + // If Event is NULL, then blocking I/O is performed. + // If Event is not NULL and non-blocking I/O is supported, then non-blocking I/O is performed, + // and Event will be signaled when the read request is completed. + // The caller must be prepared to handle the case where the callback associated with Event + // occurs before the original asynchronous I/O request call returns. + // + EFI_EVENT Event; + + // + // Defines whether or not the signaled event encountered an error. + // + EFI_STATUS Status; + + // + // For OpenEx(): Not Used, ignored. + // For ReadEx(): On input, the size of the Buffer. On output, the amount of data returned in Buffer. + // In both cases, the size is measured in bytes. + // For WriteEx(): On input, the size of the Buffer. On output, the amount of data actually written. + // In both cases, the size is measured in bytes. + // For FlushEx(): Not used, ignored. + // + UINTN BufferSize; + + // + // For OpenEx(): Not Used, ignored. + // For ReadEx(): The buffer into which the data is read. + // For WriteEx(): The buffer of data to write. + // For FlushEx(): Not Used, ignored. + // + VOID *Buffer; +} EFI_FILE_IO_TOKEN; + +/** + Opens a new file relative to the source directory's location. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to the source location. + @param NewHandle A pointer to the location to return the opened handle for the new + file. + @param FileName The Null-terminated string of the name of the file to be opened. + The file name may contain the following path modifiers: "\", ".", + and "..". + @param OpenMode The mode to open the file. The only valid combinations that the + file may be opened with are: Read, Read/Write, or Create/Read/Write. + @param Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the + attribute bits for the newly created file. + @param Token A pointer to the token associated with the transaction. + + @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully. + If Event is not NULL (asynchronous I/O): The request was successfully + queued for processing. + @retval EFI_NOT_FOUND The specified file could not be found on the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no + longer supported. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write + when the media is write-protected. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_OPEN_EX)( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes, + IN OUT EFI_FILE_IO_TOKEN *Token + ); + +/** + Reads data from a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to read data from. + @param Token A pointer to the token associated with the transaction. + + @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully. + If Event is not NULL (asynchronous I/O): The request was successfully + queued for processing. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file. + @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_OUT_OF_RESOURCES Unable to queue the request due to lack of resources. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_READ_EX)( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ); + +/** + Writes data to a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to write data to. + @param Token A pointer to the token associated with the transaction. + + @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully. + If Event is not NULL (asynchronous I/O): The request was successfully + queued for processing. + @retval EFI_UNSUPPORTED Writes to open directory files are not supported. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The file or medium is write-protected. + @retval EFI_ACCESS_DENIED The file was opened read only. + @retval EFI_VOLUME_FULL The volume is full. + @retval EFI_OUT_OF_RESOURCES Unable to queue the request due to lack of resources. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_WRITE_EX)( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ); + +/** + Flushes all modified data associated with a file to a device. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to flush. + @param Token A pointer to the token associated with the transaction. + + @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully. + If Event is not NULL (asynchronous I/O): The request was successfully + queued for processing. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The file or medium is write-protected. + @retval EFI_ACCESS_DENIED The file was opened read-only. + @retval EFI_VOLUME_FULL The volume is full. + @retval EFI_OUT_OF_RESOURCES Unable to queue the request due to lack of resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_FLUSH_EX)( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ); + +#define EFI_FILE_PROTOCOL_REVISION 0x00010000 +#define EFI_FILE_PROTOCOL_REVISION2 0x00020000 +#define EFI_FILE_PROTOCOL_LATEST_REVISION EFI_FILE_PROTOCOL_REVISION2 + +// +// Revision defined in EFI1.1. +// +#define EFI_FILE_REVISION EFI_FILE_PROTOCOL_REVISION + +/// +/// The EFI_FILE_PROTOCOL provides file IO access to supported file systems. +/// An EFI_FILE_PROTOCOL provides access to a file's or directory's contents, +/// and is also a reference to a location in the directory tree of the file system +/// in which the file resides. With any given file handle, other files may be opened +/// relative to this file's location, yielding new file handles. +/// +struct _EFI_FILE_PROTOCOL { + /// + /// The version of the EFI_FILE_PROTOCOL interface. The version specified + /// by this specification is EFI_FILE_PROTOCOL_LATEST_REVISION. + /// Future versions are required to be backward compatible to version 1.0. + /// + UINT64 Revision; + EFI_FILE_OPEN Open; + EFI_FILE_CLOSE Close; + EFI_FILE_DELETE Delete; + EFI_FILE_READ Read; + EFI_FILE_WRITE Write; + EFI_FILE_GET_POSITION GetPosition; + EFI_FILE_SET_POSITION SetPosition; + EFI_FILE_GET_INFO GetInfo; + EFI_FILE_SET_INFO SetInfo; + EFI_FILE_FLUSH Flush; + EFI_FILE_OPEN_EX OpenEx; + EFI_FILE_READ_EX ReadEx; + EFI_FILE_WRITE_EX WriteEx; + EFI_FILE_FLUSH_EX FlushEx; +}; + +extern EFI_GUID gEfiSimpleFileSystemProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/SimpleNetwork.h b/sys/contrib/edk2/Include/Protocol/SimpleNetwork.h new file mode 100644 index 000000000000..9b2e7990344d --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/SimpleNetwork.h @@ -0,0 +1,675 @@ +/** @file + The EFI_SIMPLE_NETWORK_PROTOCOL provides services to initialize a network interface, + transmit packets, receive packets, and close a network interface. + + Basic network device abstraction. + + Rx - Received + Tx - Transmit + MCast - MultiCast + ... + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in EFI Specification 1.10. + +**/ + +#ifndef __SIMPLE_NETWORK_H__ +#define __SIMPLE_NETWORK_H__ + +#define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \ + { \ + 0xA19832B9, 0xAC25, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } \ + } + +typedef struct _EFI_SIMPLE_NETWORK_PROTOCOL EFI_SIMPLE_NETWORK_PROTOCOL; + +/// +/// Protocol defined in EFI1.1. +/// +typedef EFI_SIMPLE_NETWORK_PROTOCOL EFI_SIMPLE_NETWORK; + +/// +/// Simple Network Protocol data structures. +/// +typedef struct { + /// + /// Total number of frames received. Includes frames with errors and + /// dropped frames. + /// + UINT64 RxTotalFrames; + + /// + /// Number of valid frames received and copied into receive buffers. + /// + UINT64 RxGoodFrames; + + /// + /// Number of frames below the minimum length for the media. + /// This would be <64 for ethernet. + /// + UINT64 RxUndersizeFrames; + + /// + /// Number of frames longer than the maxminum length for the + /// media. This would be >1500 for ethernet. + /// + UINT64 RxOversizeFrames; + + /// + /// Valid frames that were dropped because receive buffers were full. + /// + UINT64 RxDroppedFrames; + + /// + /// Number of valid unicast frames received and not dropped. + /// + UINT64 RxUnicastFrames; + + /// + /// Number of valid broadcast frames received and not dropped. + /// + UINT64 RxBroadcastFrames; + + /// + /// Number of valid mutlicast frames received and not dropped. + /// + UINT64 RxMulticastFrames; + + /// + /// Number of frames w/ CRC or alignment errors. + /// + UINT64 RxCrcErrorFrames; + + /// + /// Total number of bytes received. Includes frames with errors + /// and dropped frames. + // + UINT64 RxTotalBytes; + + /// + /// Transmit statistics. + /// + UINT64 TxTotalFrames; + UINT64 TxGoodFrames; + UINT64 TxUndersizeFrames; + UINT64 TxOversizeFrames; + UINT64 TxDroppedFrames; + UINT64 TxUnicastFrames; + UINT64 TxBroadcastFrames; + UINT64 TxMulticastFrames; + UINT64 TxCrcErrorFrames; + UINT64 TxTotalBytes; + + /// + /// Number of collisions detection on this subnet. + /// + UINT64 Collisions; + + /// + /// Number of frames destined for unsupported protocol. + /// + UINT64 UnsupportedProtocol; + + /// + /// Number of valid frames received that were duplicated. + /// + UINT64 RxDuplicatedFrames; + + /// + /// Number of encrypted frames received that failed to decrypt. + /// + UINT64 RxDecryptErrorFrames; + + /// + /// Number of frames that failed to transmit after exceeding the retry limit. + /// + UINT64 TxErrorFrames; + + /// + /// Number of frames transmitted successfully after more than one attempt. + /// + UINT64 TxRetryFrames; +} EFI_NETWORK_STATISTICS; + +/// +/// The state of the network interface. +/// When an EFI_SIMPLE_NETWORK_PROTOCOL driver initializes a +/// network interface, the network interface is left in the EfiSimpleNetworkStopped state. +/// +typedef enum { + EfiSimpleNetworkStopped, + EfiSimpleNetworkStarted, + EfiSimpleNetworkInitialized, + EfiSimpleNetworkMaxState +} EFI_SIMPLE_NETWORK_STATE; + +#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01 +#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02 +#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04 +#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08 +#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10 + +#define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT 0x01 +#define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT 0x02 +#define EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT 0x04 +#define EFI_SIMPLE_NETWORK_SOFTWARE_INTERRUPT 0x08 + +#define MAX_MCAST_FILTER_CNT 16 +typedef struct { + /// + /// Reports the current state of the network interface. + /// + UINT32 State; + /// + /// The size, in bytes, of the network interface's HW address. + /// + UINT32 HwAddressSize; + /// + /// The size, in bytes, of the network interface's media header. + /// + UINT32 MediaHeaderSize; + /// + /// The maximum size, in bytes, of the packets supported by the network interface. + /// + UINT32 MaxPacketSize; + /// + /// The size, in bytes, of the NVRAM device attached to the network interface. + /// + UINT32 NvRamSize; + /// + /// The size that must be used for all NVRAM reads and writes. The + /// start address for NVRAM read and write operations and the total + /// length of those operations, must be a multiple of this value. The + /// legal values for this field are 0, 1, 2, 4, and 8. + /// + UINT32 NvRamAccessSize; + /// + /// The multicast receive filter settings supported by the network interface. + /// + UINT32 ReceiveFilterMask; + /// + /// The current multicast receive filter settings. + /// + UINT32 ReceiveFilterSetting; + /// + /// The maximum number of multicast address receive filters supported by the driver. + /// + UINT32 MaxMCastFilterCount; + /// + /// The current number of multicast address receive filters. + /// + UINT32 MCastFilterCount; + /// + /// Array containing the addresses of the current multicast address receive filters. + /// + EFI_MAC_ADDRESS MCastFilter[MAX_MCAST_FILTER_CNT]; + /// + /// The current HW MAC address for the network interface. + /// + EFI_MAC_ADDRESS CurrentAddress; + /// + /// The current HW MAC address for broadcast packets. + /// + EFI_MAC_ADDRESS BroadcastAddress; + /// + /// The permanent HW MAC address for the network interface. + /// + EFI_MAC_ADDRESS PermanentAddress; + /// + /// The interface type of the network interface. + /// + UINT8 IfType; + /// + /// TRUE if the HW MAC address can be changed. + /// + BOOLEAN MacAddressChangeable; + /// + /// TRUE if the network interface can transmit more than one packet at a time. + /// + BOOLEAN MultipleTxSupported; + /// + /// TRUE if the presence of media can be determined; otherwise FALSE. + /// + BOOLEAN MediaPresentSupported; + /// + /// TRUE if media are connected to the network interface; otherwise FALSE. + /// + BOOLEAN MediaPresent; +} EFI_SIMPLE_NETWORK_MODE; + +// +// Protocol Member Functions +// + +/** + Changes the state of a network interface from "stopped" to "started". + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The network interface was started. + @retval EFI_ALREADY_STARTED The network interface is already in the started state. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_START)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This + ); + +/** + Changes the state of a network interface from "started" to "stopped". + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The network interface was stopped. + @retval EFI_ALREADY_STARTED The network interface is already in the stopped state. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STOP)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This + ); + +/** + Resets a network adapter and allocates the transmit and receive buffers + required by the network interface; optionally, also requests allocation + of additional transmit and receive buffers. + + @param This The protocol instance pointer. + @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space + that the driver should allocate for the network interface. + Some network interfaces will not be able to use the extra + buffer, and the caller will not know if it is actually + being used. + @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space + that the driver should allocate for the network interface. + Some network interfaces will not be able to use the extra + buffer, and the caller will not know if it is actually + being used. + + @retval EFI_SUCCESS The network interface was initialized. + @retval EFI_NOT_STARTED The network interface has not been started. + @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and + receive buffers. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_INITIALIZE)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN UINTN ExtraRxBufferSize OPTIONAL, + IN UINTN ExtraTxBufferSize OPTIONAL + ); + +/** + Resets a network adapter and re-initializes it with the parameters that were + provided in the previous call to Initialize(). + + @param This The protocol instance pointer. + @param ExtendedVerification Indicates that the driver may perform a more + exhaustive verification operation of the device + during reset. + + @retval EFI_SUCCESS The network interface was reset. + @retval EFI_NOT_STARTED The network interface has not been started. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RESET)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +/** + Resets a network adapter and leaves it in a state that is safe for + another driver to initialize. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The network interface was shutdown. + @retval EFI_NOT_STARTED The network interface has not been started. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_SHUTDOWN)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This + ); + +/** + Manages the multicast receive filters of a network interface. + + @param This The protocol instance pointer. + @param Enable A bit mask of receive filters to enable on the network interface. + @param Disable A bit mask of receive filters to disable on the network interface. + @param ResetMCastFilter Set to TRUE to reset the contents of the multicast receive + filters on the network interface to their default values. + @param McastFilterCnt Number of multicast HW MAC addresses in the new + MCastFilter list. This value must be less than or equal to + the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This + field is optional if ResetMCastFilter is TRUE. + @param MCastFilter A pointer to a list of new multicast receive filter HW MAC + addresses. This list will replace any existing multicast + HW MAC address list. This field is optional if + ResetMCastFilter is TRUE. + + @retval EFI_SUCCESS The multicast receive filter list was updated. + @retval EFI_NOT_STARTED The network interface has not been started. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN UINT32 Enable, + IN UINT32 Disable, + IN BOOLEAN ResetMCastFilter, + IN UINTN MCastFilterCnt OPTIONAL, + IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL + ); + +/** + Modifies or resets the current station address, if supported. + + @param This The protocol instance pointer. + @param Reset Flag used to reset the station address to the network interfaces + permanent address. + @param New The new station address to be used for the network interface. + + @retval EFI_SUCCESS The network interfaces station address was updated. + @retval EFI_NOT_STARTED The network interface has not been started. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STATION_ADDRESS)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN BOOLEAN Reset, + IN EFI_MAC_ADDRESS *New OPTIONAL + ); + +/** + Resets or collects the statistics on a network interface. + + @param This Protocol instance pointer. + @param Reset Set to TRUE to reset the statistics for the network interface. + @param StatisticsSize On input the size, in bytes, of StatisticsTable. On + output the size, in bytes, of the resulting table of + statistics. + @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that + contains the statistics. + + @retval EFI_SUCCESS The statistics were collected from the network interface. + @retval EFI_NOT_STARTED The network interface has not been started. + @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer + size needed to hold the statistics is returned in + StatisticsSize. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STATISTICS)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN BOOLEAN Reset, + IN OUT UINTN *StatisticsSize OPTIONAL, + OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL + ); + +/** + Converts a multicast IP address to a multicast HW MAC address. + + @param This The protocol instance pointer. + @param IPv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set + to FALSE if the multicast IP address is IPv4 [RFC 791]. + @param IP The multicast IP address that is to be converted to a multicast + HW MAC address. + @param MAC The multicast HW MAC address that is to be generated from IP. + + @retval EFI_SUCCESS The multicast IP address was mapped to the multicast + HW MAC address. + @retval EFI_NOT_STARTED The network interface has not been started. + @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer + size needed to hold the statistics is returned in + StatisticsSize. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN BOOLEAN IPv6, + IN EFI_IP_ADDRESS *IP, + OUT EFI_MAC_ADDRESS *MAC + ); + +/** + Performs read and write operations on the NVRAM device attached to a + network interface. + + @param This The protocol instance pointer. + @param ReadWrite TRUE for read operations, FALSE for write operations. + @param Offset Byte offset in the NVRAM device at which to start the read or + write operation. This must be a multiple of NvRamAccessSize and + less than NvRamSize. + @param BufferSize The number of bytes to read or write from the NVRAM device. + This must also be a multiple of NvramAccessSize. + @param Buffer A pointer to the data buffer. + + @retval EFI_SUCCESS The NVRAM access was performed. + @retval EFI_NOT_STARTED The network interface has not been started. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_NVDATA)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN BOOLEAN ReadWrite, + IN UINTN Offset, + IN UINTN BufferSize, + IN OUT VOID *Buffer + ); + +/** + Reads the current interrupt status and recycled transmit buffer status from + a network interface. + + @param This The protocol instance pointer. + @param InterruptStatus A pointer to the bit mask of the currently active interrupts + If this is NULL, the interrupt status will not be read from + the device. If this is not NULL, the interrupt status will + be read from the device. When the interrupt status is read, + it will also be cleared. Clearing the transmit interrupt + does not empty the recycled transmit buffer array. + @param TxBuf Recycled transmit buffer address. The network interface will + not transmit if its internal recycled transmit buffer array + is full. Reading the transmit buffer does not clear the + transmit interrupt. If this is NULL, then the transmit buffer + status will not be read. If there are no transmit buffers to + recycle and TxBuf is not NULL, * TxBuf will be set to NULL. + + @retval EFI_SUCCESS The status of the network interface was retrieved. + @retval EFI_NOT_STARTED The network interface has not been started. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_GET_STATUS)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, + OUT UINT32 *InterruptStatus OPTIONAL, + OUT VOID **TxBuf OPTIONAL + ); + +/** + Places a packet in the transmit queue of a network interface. + + @param This The protocol instance pointer. + @param HeaderSize The size, in bytes, of the media header to be filled in by + the Transmit() function. If HeaderSize is non-zero, then it + must be equal to This->Mode->MediaHeaderSize and the DestAddr + and Protocol parameters must not be NULL. + @param BufferSize The size, in bytes, of the entire packet (media header and + data) to be transmitted through the network interface. + @param Buffer A pointer to the packet (media header followed by data) to be + transmitted. This parameter cannot be NULL. If HeaderSize is zero, + then the media header in Buffer must already be filled in by the + caller. If HeaderSize is non-zero, then the media header will be + filled in by the Transmit() function. + @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter + is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then + This->Mode->CurrentAddress is used for the source HW MAC address. + @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this + parameter is ignored. + @param Protocol The type of header to build. If HeaderSize is zero, then this + parameter is ignored. See RFC 1700, section "Ether Types", for + examples. + + @retval EFI_SUCCESS The packet was placed on the transmit queue. + @retval EFI_NOT_STARTED The network interface has not been started. + @retval EFI_NOT_READY The network interface is too busy to accept this transmit request. + @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_TRANSMIT)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN UINTN HeaderSize, + IN UINTN BufferSize, + IN VOID *Buffer, + IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL, + IN EFI_MAC_ADDRESS *DestAddr OPTIONAL, + IN UINT16 *Protocol OPTIONAL + ); + +/** + Receives a packet from a network interface. + + @param This The protocol instance pointer. + @param HeaderSize The size, in bytes, of the media header received on the network + interface. If this parameter is NULL, then the media header size + will not be returned. + @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in + bytes, of the packet that was received on the network interface. + @param Buffer A pointer to the data buffer to receive both the media header and + the data. + @param SrcAddr The source HW MAC address. If this parameter is NULL, the + HW MAC source address will not be extracted from the media + header. + @param DestAddr The destination HW MAC address. If this parameter is NULL, + the HW MAC destination address will not be extracted from the + media header. + @param Protocol The media header type. If this parameter is NULL, then the + protocol will not be extracted from the media header. See + RFC 1700 section "Ether Types" for examples. + + @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has + been updated to the number of bytes received. + @retval EFI_NOT_STARTED The network interface has not been started. + @retval EFI_NOT_READY The network interface is too busy to accept this transmit + request. + @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small. + @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value. + @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. + @retval EFI_UNSUPPORTED This function is not supported by the network interface. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE)( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, + OUT UINTN *HeaderSize OPTIONAL, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer, + OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL, + OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL, + OUT UINT16 *Protocol OPTIONAL + ); + +#define EFI_SIMPLE_NETWORK_PROTOCOL_REVISION 0x00010000 + +// +// Revision defined in EFI1.1 +// +#define EFI_SIMPLE_NETWORK_INTERFACE_REVISION EFI_SIMPLE_NETWORK_PROTOCOL_REVISION + +/// +/// The EFI_SIMPLE_NETWORK_PROTOCOL protocol is used to initialize access +/// to a network adapter. Once the network adapter initializes, +/// the EFI_SIMPLE_NETWORK_PROTOCOL protocol provides services that +/// allow packets to be transmitted and received. +/// +struct _EFI_SIMPLE_NETWORK_PROTOCOL { + /// + /// Revision of the EFI_SIMPLE_NETWORK_PROTOCOL. All future revisions must + /// be backwards compatible. If a future version is not backwards compatible + /// it is not the same GUID. + /// + UINT64 Revision; + EFI_SIMPLE_NETWORK_START Start; + EFI_SIMPLE_NETWORK_STOP Stop; + EFI_SIMPLE_NETWORK_INITIALIZE Initialize; + EFI_SIMPLE_NETWORK_RESET Reset; + EFI_SIMPLE_NETWORK_SHUTDOWN Shutdown; + EFI_SIMPLE_NETWORK_RECEIVE_FILTERS ReceiveFilters; + EFI_SIMPLE_NETWORK_STATION_ADDRESS StationAddress; + EFI_SIMPLE_NETWORK_STATISTICS Statistics; + EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC MCastIpToMac; + EFI_SIMPLE_NETWORK_NVDATA NvData; + EFI_SIMPLE_NETWORK_GET_STATUS GetStatus; + EFI_SIMPLE_NETWORK_TRANSMIT Transmit; + EFI_SIMPLE_NETWORK_RECEIVE Receive; + /// + /// Event used with WaitForEvent() to wait for a packet to be received. + /// + EFI_EVENT WaitForPacket; + /// + /// Pointer to the EFI_SIMPLE_NETWORK_MODE data for the device. + /// + EFI_SIMPLE_NETWORK_MODE *Mode; +}; + +extern EFI_GUID gEfiSimpleNetworkProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/SimplePointer.h b/sys/contrib/edk2/Include/Protocol/SimplePointer.h new file mode 100644 index 000000000000..8c38439be013 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/SimplePointer.h @@ -0,0 +1,137 @@ +/** @file + Simple Pointer protocol from the UEFI 2.0 specification. + + Abstraction of a very simple pointer device like a mouse or trackball. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SIMPLE_POINTER_H__ +#define __SIMPLE_POINTER_H__ + +#define EFI_SIMPLE_POINTER_PROTOCOL_GUID \ + { \ + 0x31878c87, 0xb75, 0x11d5, {0x9a, 0x4f, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +typedef struct _EFI_SIMPLE_POINTER_PROTOCOL EFI_SIMPLE_POINTER_PROTOCOL; + +// +// Data structures +// +typedef struct { + /// + /// The signed distance in counts that the pointer device has been moved along the x-axis. + /// + INT32 RelativeMovementX; + /// + /// The signed distance in counts that the pointer device has been moved along the y-axis. + /// + INT32 RelativeMovementY; + /// + /// The signed distance in counts that the pointer device has been moved along the z-axis. + /// + INT32 RelativeMovementZ; + /// + /// If TRUE, then the left button of the pointer device is being + /// pressed. If FALSE, then the left button of the pointer device is not being pressed. + /// + BOOLEAN LeftButton; + /// + /// If TRUE, then the right button of the pointer device is being + /// pressed. If FALSE, then the right button of the pointer device is not being pressed. + /// + BOOLEAN RightButton; +} EFI_SIMPLE_POINTER_STATE; + +typedef struct { + /// + /// The resolution of the pointer device on the x-axis in counts/mm. + /// If 0, then the pointer device does not support an x-axis. + /// + UINT64 ResolutionX; + /// + /// The resolution of the pointer device on the y-axis in counts/mm. + /// If 0, then the pointer device does not support an x-axis. + /// + UINT64 ResolutionY; + /// + /// The resolution of the pointer device on the z-axis in counts/mm. + /// If 0, then the pointer device does not support an x-axis. + /// + UINT64 ResolutionZ; + /// + /// TRUE if a left button is present on the pointer device. Otherwise FALSE. + /// + BOOLEAN LeftButton; + /// + /// TRUE if a right button is present on the pointer device. Otherwise FALSE. + /// + BOOLEAN RightButton; +} EFI_SIMPLE_POINTER_MODE; + +/** + Resets the pointer device hardware. + + @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL + instance. + @param ExtendedVerification Indicates that the driver may perform a more exhaustive + verification operation of the device during reset. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_POINTER_RESET)( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +/** + Retrieves the current state of a pointer device. + + @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL + instance. + @param State A pointer to the state information on the pointer device. + + @retval EFI_SUCCESS The state of the pointer device was returned in State. + @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to + GetState(). + @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's + current state. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_POINTER_GET_STATE)( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + OUT EFI_SIMPLE_POINTER_STATE *State + ); + +/// +/// The EFI_SIMPLE_POINTER_PROTOCOL provides a set of services for a pointer +/// device that can use used as an input device from an application written +/// to this specification. The services include the ability to reset the +/// pointer device, retrieve get the state of the pointer device, and +/// retrieve the capabilities of the pointer device. +/// +struct _EFI_SIMPLE_POINTER_PROTOCOL { + EFI_SIMPLE_POINTER_RESET Reset; + EFI_SIMPLE_POINTER_GET_STATE GetState; + /// + /// Event to use with WaitForEvent() to wait for input from the pointer device. + /// + EFI_EVENT WaitForInput; + /// + /// Pointer to EFI_SIMPLE_POINTER_MODE data. + /// + EFI_SIMPLE_POINTER_MODE *Mode; +}; + +extern EFI_GUID gEfiSimplePointerProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/StatusCode.h b/sys/contrib/edk2/Include/Protocol/StatusCode.h new file mode 100644 index 000000000000..baf0c886379e --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/StatusCode.h @@ -0,0 +1,53 @@ +/** @file + Status code Runtime Protocol as defined in PI Specification 1.4a VOLUME 2 DXE + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __STATUS_CODE_RUNTIME_PROTOCOL_H__ +#define __STATUS_CODE_RUNTIME_PROTOCOL_H__ + +#define EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID \ +{ 0xd2b2b828, 0x826, 0x48a7, { 0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0 } } + +/** + Provides an interface that a software module can call to report a status code. + + @param Type Indicates the type of status code being reported. + @param Value Describes the current status of a hardware or software entity. + This included information about the class and subclass that is used to + classify the entity as well as an operation. + @param Instance The enumeration of a hardware or software entity within + the system. Valid instance numbers start with 1. + @param CallerId This optional parameter may be used to identify the caller. + This parameter allows the status code driver to apply different rules to + different callers. + @param Data This optional parameter may be used to pass additional data. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_DEVICE_ERROR The function should not be completed due to a device error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_REPORT_STATUS_CODE)( + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID *CallerId OPTIONAL, + IN EFI_STATUS_CODE_DATA *Data OPTIONAL + ); + +/// +/// Provides the service required to report a status code to the platform firmware. +/// This protocol must be produced by a runtime DXE driver. +/// +typedef struct _EFI_STATUS_CODE_PROTOCOL { + EFI_REPORT_STATUS_CODE ReportStatusCode; +} EFI_STATUS_CODE_PROTOCOL; + +extern EFI_GUID gEfiStatusCodeRuntimeProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Tcg2Protocol.h b/sys/contrib/edk2/Include/Protocol/Tcg2Protocol.h new file mode 100644 index 000000000000..f1326a5ef022 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Tcg2Protocol.h @@ -0,0 +1,335 @@ +/** @file
+ TPM2 Protocol as defined in TCG PC Client Platform EFI Protocol Specification Family "2.0".
+ See http://trustedcomputinggroup.org for the latest specification
+
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __TCG2_PROTOCOL_H__
+#define __TCG2_PROTOCOL_H__
+
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <IndustryStandard/Tpm20.h>
+
+#define EFI_TCG2_PROTOCOL_GUID \
+ {0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f }}
+
+typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
+
+typedef struct tdEFI_TCG2_VERSION {
+ UINT8 Major;
+ UINT8 Minor;
+} EFI_TCG2_VERSION;
+
+typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP;
+typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT;
+typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP;
+
+#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x00000001
+#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x00000002
+
+typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
+ //
+ // Allocated size of the structure
+ //
+ UINT8 Size;
+ //
+ // Version of the EFI_TCG2_BOOT_SERVICE_CAPABILITY structure itself.
+ // For this version of the protocol, the Major version shall be set to 1
+ // and the Minor version shall be set to 1.
+ //
+ EFI_TCG2_VERSION StructureVersion;
+ //
+ // Version of the EFI TCG2 protocol.
+ // For this version of the protocol, the Major version shall be set to 1
+ // and the Minor version shall be set to 1.
+ //
+ EFI_TCG2_VERSION ProtocolVersion;
+ //
+ // Supported hash algorithms (this bitmap is determined by the supported PCR
+ // banks in the TPM and the hashing algorithms supported by the firmware)
+ //
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
+ //
+ // Bitmap of supported event log formats
+ //
+ EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
+ //
+ // False = TPM not present
+ //
+ BOOLEAN TPMPresentFlag;
+ //
+ // Max size (in bytes) of a command that can be sent to the TPM
+ //
+ UINT16 MaxCommandSize;
+ //
+ // Max size (in bytes) of a response that can be provided by the TPM
+ //
+ UINT16 MaxResponseSize;
+ //
+ // 4-byte Vendor ID
+ // (see TCG Vendor ID registry, Section "TPM Capabilities Vendor ID")
+ //
+ UINT32 ManufacturerID;
+ //
+ // Maximum number of PCR banks (hashing algorithms) supported.
+ // No granularity is provided to support a specific set of algorithms.
+ // Minimum value is 1.
+ //
+ UINT32 NumberOfPCRBanks;
+ //
+ // A bitmap of currently active PCR banks (hashing algorithms).
+ // This is a subset of the supported hashing algorithms reported in HashAlgorithmBitMap.
+ // NumberOfPcrBanks defines the number of bits that are set.
+ //
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
+} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
+
+#define EFI_TCG2_BOOT_HASH_ALG_SHA1 0x00000001
+#define EFI_TCG2_BOOT_HASH_ALG_SHA256 0x00000002
+#define EFI_TCG2_BOOT_HASH_ALG_SHA384 0x00000004
+#define EFI_TCG2_BOOT_HASH_ALG_SHA512 0x00000008
+#define EFI_TCG2_BOOT_HASH_ALG_SM3_256 0x00000010
+
+//
+// This bit is shall be set when an event shall be extended but not logged.
+//
+#define EFI_TCG2_EXTEND_ONLY 0x0000000000000001
+//
+// This bit shall be set when the intent is to measure a PE/COFF image.
+//
+#define PE_COFF_IMAGE 0x0000000000000010
+
+#define MAX_PCR_INDEX 23
+
+#pragma pack(1)
+
+#define EFI_TCG2_EVENT_HEADER_VERSION 1
+
+typedef struct {
+ //
+ // Size of the event header itself (sizeof(EFI_TCG2_EVENT_HEADER)).
+ //
+ UINT32 HeaderSize;
+ //
+ // Header version. For this version of this specification, the value shall be 1.
+ //
+ UINT16 HeaderVersion;
+ //
+ // Index of the PCR that shall be extended (0 - 23).
+ //
+ TCG_PCRINDEX PCRIndex;
+ //
+ // Type of the event that shall be extended (and optionally logged).
+ //
+ TCG_EVENTTYPE EventType;
+} EFI_TCG2_EVENT_HEADER;
+
+typedef struct tdEFI_TCG2_EVENT {
+ //
+ // Total size of the event including the Size component, the header and the Event data.
+ //
+ UINT32 Size;
+ EFI_TCG2_EVENT_HEADER Header;
+ UINT8 Event[1];
+} EFI_TCG2_EVENT;
+
+#pragma pack()
+
+/**
+ The EFI_TCG2_PROTOCOL GetCapability function call provides protocol
+ capability information and state information.
+
+ @param[in] This Indicates the calling context
+ @param[in, out] ProtocolCapability The caller allocates memory for a EFI_TCG2_BOOT_SERVICE_CAPABILITY
+ structure and sets the size field to the size of the structure allocated.
+ The callee fills in the fields with the EFI protocol capability information
+ and the current EFI TCG2 state information up to the number of fields which
+ fit within the size of the structure passed in.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+ The ProtocolCapability variable will not be populated.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+ The ProtocolCapability variable will not be populated.
+ @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
+ It will be partially populated (required Size field will be set).
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCG2_GET_CAPABILITY)(
+ IN EFI_TCG2_PROTOCOL *This,
+ IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability
+ );
+
+/**
+ The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to
+ retrieve the address of a given event log and its last entry.
+
+ @param[in] This Indicates the calling context
+ @param[in] EventLogFormat The type of the event log for which the information is requested.
+ @param[out] EventLogLocation A pointer to the memory address of the event log.
+ @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
+ address of the start of the last entry in the event log in memory.
+ @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
+ have exceeded the area allocated for events, this value is set to TRUE.
+ Otherwise, the value will be FALSE and the Event Log will be complete.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
+ (e.g. asking for an event log whose format is not supported).
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCG2_GET_EVENT_LOG)(
+ IN EFI_TCG2_PROTOCOL *This,
+ IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry,
+ OUT BOOLEAN *EventLogTruncated
+ );
+
+/**
+ The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with
+ an opportunity to extend and optionally log events without requiring
+ knowledge of actual TPM commands.
+ The extend operation will occur even if this function cannot create an event
+ log entry (e.g. due to the event log being full).
+
+ @param[in] This Indicates the calling context
+ @param[in] Flags Bitmap providing additional information.
+ @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
+ @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
+ @param[in] EfiTcgEvent Pointer to data buffer containing information about the event.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+ @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+ @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCG2_HASH_LOG_EXTEND_EVENT)(
+ IN EFI_TCG2_PROTOCOL *This,
+ IN UINT64 Flags,
+ IN EFI_PHYSICAL_ADDRESS DataToHash,
+ IN UINT64 DataToHashLen,
+ IN EFI_TCG2_EVENT *EfiTcgEvent
+ );
+
+/**
+ This service enables the sending of commands to the TPM.
+
+ @param[in] This Indicates the calling context
+ @param[in] InputParameterBlockSize Size of the TPM input parameter block.
+ @param[in] InputParameterBlock Pointer to the TPM input parameter block.
+ @param[in] OutputParameterBlockSize Size of the TPM output parameter block.
+ @param[in] OutputParameterBlock Pointer to the TPM output parameter block.
+
+ @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
+ @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+ @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCG2_SUBMIT_COMMAND)(
+ IN EFI_TCG2_PROTOCOL *This,
+ IN UINT32 InputParameterBlockSize,
+ IN UINT8 *InputParameterBlock,
+ IN UINT32 OutputParameterBlockSize,
+ IN UINT8 *OutputParameterBlock
+ );
+
+/**
+ This service returns the currently active PCR banks.
+
+ @param[in] This Indicates the calling context
+ @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks.
+
+ @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCG2_GET_ACTIVE_PCR_BANKS)(
+ IN EFI_TCG2_PROTOCOL *This,
+ OUT UINT32 *ActivePcrBanks
+ );
+
+/**
+ This service sets the currently active PCR banks.
+
+ @param[in] This Indicates the calling context
+ @param[in] ActivePcrBanks Bitmap of the requested active PCR banks. At least one bit SHALL be set.
+
+ @retval EFI_SUCCESS The bitmap in ActivePcrBank parameter is already active.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCG2_SET_ACTIVE_PCR_BANKS)(
+ IN EFI_TCG2_PROTOCOL *This,
+ IN UINT32 ActivePcrBanks
+ );
+
+/**
+ This service retrieves the result of a previous invocation of SetActivePcrBanks.
+
+ @param[in] This Indicates the calling context
+ @param[out] OperationPresent Non-zero value to indicate a SetActivePcrBank operation was invoked during the last boot.
+ @param[out] Response The response from the SetActivePcrBank request.
+
+ @retval EFI_SUCCESS The result value could be returned.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS)(
+ IN EFI_TCG2_PROTOCOL *This,
+ OUT UINT32 *OperationPresent,
+ OUT UINT32 *Response
+ );
+
+struct tdEFI_TCG2_PROTOCOL {
+ EFI_TCG2_GET_CAPABILITY GetCapability;
+ EFI_TCG2_GET_EVENT_LOG GetEventLog;
+ EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
+ EFI_TCG2_SUBMIT_COMMAND SubmitCommand;
+ EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks;
+ EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks;
+ EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks;
+};
+
+extern EFI_GUID gEfiTcg2ProtocolGuid;
+
+//
+// Log entries after Get Event Log service
+//
+
+#define EFI_TCG2_FINAL_EVENTS_TABLE_GUID \
+ {0x1e2ed096, 0x30e2, 0x4254, { 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25 }}
+
+extern EFI_GUID gEfiTcg2FinalEventsTableGuid;
+
+typedef struct tdEFI_TCG2_FINAL_EVENTS_TABLE {
+ //
+ // The version of this structure.
+ //
+ UINT64 Version;
+ //
+ // Number of events recorded after invocation of GetEventLog API
+ //
+ UINT64 NumberOfEvents;
+ //
+ // List of events of type TCG_PCR_EVENT2.
+ //
+ // TCG_PCR_EVENT2 Event[1];
+} EFI_TCG2_FINAL_EVENTS_TABLE;
+
+#define EFI_TCG2_FINAL_EVENTS_TABLE_VERSION 1
+
+#endif
diff --git a/sys/contrib/edk2/Include/Protocol/Tcp4.h b/sys/contrib/edk2/Include/Protocol/Tcp4.h new file mode 100644 index 000000000000..0cec4f5fdaa0 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Tcp4.h @@ -0,0 +1,567 @@ +/** @file + EFI TCPv4(Transmission Control Protocol version 4) Protocol Definition + The EFI TCPv4 Service Binding Protocol is used to locate EFI TCPv4 Protocol drivers to create + and destroy child of the driver to communicate with other host using TCP protocol. + The EFI TCPv4 Protocol provides services to send and receive data stream. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.0. + +**/ + +#ifndef __EFI_TCP4_PROTOCOL_H__ +#define __EFI_TCP4_PROTOCOL_H__ + +#include <Protocol/Ip4.h> + +#define EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0x00720665, 0x67EB, 0x4a99, {0xBA, 0xF7, 0xD3, 0xC3, 0x3A, 0x1C, 0x7C, 0xC9 } \ + } + +#define EFI_TCP4_PROTOCOL_GUID \ + { \ + 0x65530BC7, 0xA359, 0x410f, {0xB0, 0x10, 0x5A, 0xAD, 0xC7, 0xEC, 0x2B, 0x62 } \ + } + +typedef struct _EFI_TCP4_PROTOCOL EFI_TCP4_PROTOCOL; + +/// +/// EFI_TCP4_SERVICE_POINT is deprecated in the UEFI 2.4B and should not be used any more. +/// The definition in here is only present to provide backwards compatability. +/// +typedef struct { + EFI_HANDLE InstanceHandle; + EFI_IPv4_ADDRESS LocalAddress; + UINT16 LocalPort; + EFI_IPv4_ADDRESS RemoteAddress; + UINT16 RemotePort; +} EFI_TCP4_SERVICE_POINT; + +/// +/// EFI_TCP4_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more. +/// The definition in here is only present to provide backwards compatability. +/// +typedef struct { + EFI_HANDLE DriverHandle; + UINT32 ServiceCount; + EFI_TCP4_SERVICE_POINT Services[1]; +} EFI_TCP4_VARIABLE_DATA; + +typedef struct { + BOOLEAN UseDefaultAddress; + EFI_IPv4_ADDRESS StationAddress; + EFI_IPv4_ADDRESS SubnetMask; + UINT16 StationPort; + EFI_IPv4_ADDRESS RemoteAddress; + UINT16 RemotePort; + BOOLEAN ActiveFlag; +} EFI_TCP4_ACCESS_POINT; + +typedef struct { + UINT32 ReceiveBufferSize; + UINT32 SendBufferSize; + UINT32 MaxSynBackLog; + UINT32 ConnectionTimeout; + UINT32 DataRetries; + UINT32 FinTimeout; + UINT32 TimeWaitTimeout; + UINT32 KeepAliveProbes; + UINT32 KeepAliveTime; + UINT32 KeepAliveInterval; + BOOLEAN EnableNagle; + BOOLEAN EnableTimeStamp; + BOOLEAN EnableWindowScaling; + BOOLEAN EnableSelectiveAck; + BOOLEAN EnablePathMtuDiscovery; +} EFI_TCP4_OPTION; + +typedef struct { + // + // I/O parameters + // + UINT8 TypeOfService; + UINT8 TimeToLive; + + // + // Access Point + // + EFI_TCP4_ACCESS_POINT AccessPoint; + + // + // TCP Control Options + // + EFI_TCP4_OPTION *ControlOption; +} EFI_TCP4_CONFIG_DATA; + +/// +/// TCP4 connnection state +/// +typedef enum { + Tcp4StateClosed = 0, + Tcp4StateListen = 1, + Tcp4StateSynSent = 2, + Tcp4StateSynReceived = 3, + Tcp4StateEstablished = 4, + Tcp4StateFinWait1 = 5, + Tcp4StateFinWait2 = 6, + Tcp4StateClosing = 7, + Tcp4StateTimeWait = 8, + Tcp4StateCloseWait = 9, + Tcp4StateLastAck = 10 +} EFI_TCP4_CONNECTION_STATE; + +typedef struct { + EFI_EVENT Event; + EFI_STATUS Status; +} EFI_TCP4_COMPLETION_TOKEN; + +typedef struct { + /// + /// The Status in the CompletionToken will be set to one of + /// the following values if the active open succeeds or an unexpected + /// error happens: + /// EFI_SUCCESS: The active open succeeds and the instance's + /// state is Tcp4StateEstablished. + /// EFI_CONNECTION_RESET: The connect fails because the connection is reset + /// either by instance itself or the communication peer. + /// EFI_CONNECTION_REFUSED: The connect fails because this connection is initiated with + /// an active open and the connection is refused. + /// EFI_ABORTED: The active open is aborted. + /// EFI_TIMEOUT: The connection establishment timer expires and + /// no more specific information is available. + /// EFI_NETWORK_UNREACHABLE: The active open fails because + /// an ICMP network unreachable error is received. + /// EFI_HOST_UNREACHABLE: The active open fails because an + /// ICMP host unreachable error is received. + /// EFI_PROTOCOL_UNREACHABLE: The active open fails + /// because an ICMP protocol unreachable error is received. + /// EFI_PORT_UNREACHABLE: The connection establishment + /// timer times out and an ICMP port unreachable error is received. + /// EFI_ICMP_ERROR: The connection establishment timer timeout and some other ICMP + /// error is received. + /// EFI_DEVICE_ERROR: An unexpected system or network error occurred. + /// EFI_NO_MEDIA: There was a media error. + /// + EFI_TCP4_COMPLETION_TOKEN CompletionToken; +} EFI_TCP4_CONNECTION_TOKEN; + +typedef struct { + EFI_TCP4_COMPLETION_TOKEN CompletionToken; + EFI_HANDLE NewChildHandle; +} EFI_TCP4_LISTEN_TOKEN; + +typedef struct { + UINT32 FragmentLength; + VOID *FragmentBuffer; +} EFI_TCP4_FRAGMENT_DATA; + +typedef struct { + BOOLEAN UrgentFlag; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_TCP4_FRAGMENT_DATA FragmentTable[1]; +} EFI_TCP4_RECEIVE_DATA; + +typedef struct { + BOOLEAN Push; + BOOLEAN Urgent; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_TCP4_FRAGMENT_DATA FragmentTable[1]; +} EFI_TCP4_TRANSMIT_DATA; + +typedef struct { + /// + /// When transmission finishes or meets any unexpected error it will + /// be set to one of the following values: + /// EFI_SUCCESS: The receiving or transmission operation + /// completes successfully. + /// EFI_CONNECTION_FIN: The receiving operation fails because the communication peer + /// has closed the connection and there is no more data in the + /// receive buffer of the instance. + /// EFI_CONNECTION_RESET: The receiving or transmission operation fails + /// because this connection is reset either by instance + /// itself or the communication peer. + /// EFI_ABORTED: The receiving or transmission is aborted. + /// EFI_TIMEOUT: The transmission timer expires and no more + /// specific information is available. + /// EFI_NETWORK_UNREACHABLE: The transmission fails + /// because an ICMP network unreachable error is received. + /// EFI_HOST_UNREACHABLE: The transmission fails because an + /// ICMP host unreachable error is received. + /// EFI_PROTOCOL_UNREACHABLE: The transmission fails + /// because an ICMP protocol unreachable error is received. + /// EFI_PORT_UNREACHABLE: The transmission fails and an + /// ICMP port unreachable error is received. + /// EFI_ICMP_ERROR: The transmission fails and some other + /// ICMP error is received. + /// EFI_DEVICE_ERROR: An unexpected system or network error occurs. + /// EFI_NO_MEDIA: There was a media error. + /// + EFI_TCP4_COMPLETION_TOKEN CompletionToken; + union { + /// + /// When this token is used for receiving, RxData is a pointer to EFI_TCP4_RECEIVE_DATA. + /// + EFI_TCP4_RECEIVE_DATA *RxData; + /// + /// When this token is used for transmitting, TxData is a pointer to EFI_TCP4_TRANSMIT_DATA. + /// + EFI_TCP4_TRANSMIT_DATA *TxData; + } Packet; +} EFI_TCP4_IO_TOKEN; + +typedef struct { + EFI_TCP4_COMPLETION_TOKEN CompletionToken; + BOOLEAN AbortOnClose; +} EFI_TCP4_CLOSE_TOKEN; + +// +// Interface definition for TCP4 protocol +// + +/** + Get the current operational status. + + @param This The pointer to the EFI_TCP4_PROTOCOL instance. + @param Tcp4State The pointer to the buffer to receive the current TCP state. + @param Tcp4ConfigData The pointer to the buffer to receive the current TCP configuration. + @param Ip4ModeData The pointer to the buffer to receive the current IPv4 configuration + data used by the TCPv4 instance. + @param MnpConfigData The pointer to the buffer to receive the current MNP configuration + data used indirectly by the TCPv4 instance. + @param SnpModeData The pointer to the buffer to receive the current SNP configuration + data used indirectly by the TCPv4 instance. + + @retval EFI_SUCCESS The mode data was read. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_STARTED No configuration data is available because this instance hasn't + been started. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_GET_MODE_DATA)( + IN EFI_TCP4_PROTOCOL *This, + OUT EFI_TCP4_CONNECTION_STATE *Tcp4State OPTIONAL, + OUT EFI_TCP4_CONFIG_DATA *Tcp4ConfigData OPTIONAL, + OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL, + OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, + OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL + ); + +/** + Initialize or brutally reset the operational parameters for this EFI TCPv4 instance. + + @param This The pointer to the EFI_TCP4_PROTOCOL instance. + @param Tcp4ConfigData The pointer to the configure data to configure the instance. + + @retval EFI_SUCCESS The operational settings are set, changed, or reset + successfully. + @retval EFI_INVALID_PARAMETER Some parameter is invalid. + @retval EFI_NO_MAPPING When using a default address, configuration (through + DHCP, BOOTP, RARP, etc.) is not finished yet. + @retval EFI_ACCESS_DENIED Configuring TCP instance when it is configured without + calling Configure() with NULL to reset it. + @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. + @retval EFI_UNSUPPORTED One or more of the control options are not supported in + the implementation. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources when + executing Configure(). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_CONFIGURE)( + IN EFI_TCP4_PROTOCOL *This, + IN EFI_TCP4_CONFIG_DATA *TcpConfigData OPTIONAL + ); + +/** + Add or delete a route entry to the route table + + @param This The pointer to the EFI_TCP4_PROTOCOL instance. + @param DeleteRoute Set it to TRUE to delete this route from the routing table. Set it to + FALSE to add this route to the routing table. + DestinationAddress and SubnetMask are used as the + keywords to search route entry. + @param SubnetAddress The destination network. + @param SubnetMask The subnet mask of the destination network. + @param GatewayAddress The gateway address for this route. It must be on the same + subnet with the station address unless a direct route is specified. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_NOT_STARTED The EFI TCPv4 Protocol instance has not been configured. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, + RARP, etc.) is not finished yet. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - SubnetAddress is NULL. + - SubnetMask is NULL. + - GatewayAddress is NULL. + - *SubnetAddress is not NULL a valid subnet address. + - *SubnetMask is not a valid subnet mask. + - *GatewayAddress is not a valid unicast IP address or it + is not in the same subnet. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to add the entry to the + routing table. + @retval EFI_NOT_FOUND This route is not in the routing table. + @retval EFI_ACCESS_DENIED The route is already defined in the routing table. + @retval EFI_UNSUPPORTED The TCP driver does not support this operation. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_ROUTES)( + IN EFI_TCP4_PROTOCOL *This, + IN BOOLEAN DeleteRoute, + IN EFI_IPv4_ADDRESS *SubnetAddress, + IN EFI_IPv4_ADDRESS *SubnetMask, + IN EFI_IPv4_ADDRESS *GatewayAddress + ); + +/** + Initiate a nonblocking TCP connection request for an active TCP instance. + + @param This The pointer to the EFI_TCP4_PROTOCOL instance. + @param ConnectionToken The pointer to the connection token to return when the TCP three + way handshake finishes. + + @retval EFI_SUCCESS The connection request is successfully initiated and the state + of this TCPv4 instance has been changed to Tcp4StateSynSent. + @retval EFI_NOT_STARTED This EFI TCPv4 Protocol instance has not been configured. + @retval EFI_ACCESS_DENIED One or more of the following conditions are TRUE: + - This instance is not configured as an active one. + - This instance is not in Tcp4StateClosed state. + @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: + - This is NULL. + - ConnectionToken is NULL. + - ConnectionToken->CompletionToken.Event is NULL. + @retval EFI_OUT_OF_RESOURCES The driver can't allocate enough resource to initiate the activ eopen. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_CONNECT)( + IN EFI_TCP4_PROTOCOL *This, + IN EFI_TCP4_CONNECTION_TOKEN *ConnectionToken + ); + +/** + Listen on the passive instance to accept an incoming connection request. This is a nonblocking operation. + + @param This The pointer to the EFI_TCP4_PROTOCOL instance. + @param ListenToken The pointer to the listen token to return when operation finishes. + + @retval EFI_SUCCESS The listen token has been queued successfully. + @retval EFI_NOT_STARTED This EFI TCPv4 Protocol instance has not been configured. + @retval EFI_ACCESS_DENIED One or more of the following are TRUE: + - This instance is not a passive instance. + - This instance is not in Tcp4StateListen state. + - The same listen token has already existed in the listen + token queue of this TCP instance. + @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: + - This is NULL. + - ListenToken is NULL. + - ListentToken->CompletionToken.Event is NULL. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the operation. + @retval EFI_DEVICE_ERROR Any unexpected and not belonged to above category error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_ACCEPT)( + IN EFI_TCP4_PROTOCOL *This, + IN EFI_TCP4_LISTEN_TOKEN *ListenToken + ); + +/** + Queues outgoing data into the transmit queue. + + @param This The pointer to the EFI_TCP4_PROTOCOL instance. + @param Token The pointer to the completion token to queue to the transmit queue. + + @retval EFI_SUCCESS The data has been queued for transmission. + @retval EFI_NOT_STARTED This EFI TCPv4 Protocol instance has not been configured. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, + RARP, etc.) is not finished yet. + @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: + - This is NULL. + - Token is NULL. + - Token->CompletionToken.Event is NULL. + - Token->Packet.TxData is NULL L. + - Token->Packet.FragmentCount is zero. + - Token->Packet.DataLength is not equal to the sum of fragment lengths. + @retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE: + - A transmit completion token with the same Token->CompletionToken.Event + was already in the transmission queue. + - The current instance is in Tcp4StateClosed state. + - The current instance is a passive one and it is in + Tcp4StateListen state. + - User has called Close() to disconnect this connection. + @retval EFI_NOT_READY The completion token could not be queued because the + transmit queue is full. + @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data because of resource + shortage. + @retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or address. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_TRANSMIT)( + IN EFI_TCP4_PROTOCOL *This, + IN EFI_TCP4_IO_TOKEN *Token + ); + +/** + Places an asynchronous receive request into the receiving queue. + + @param This The pointer to the EFI_TCP4_PROTOCOL instance. + @param Token The pointer to a token that is associated with the receive data + descriptor. + + @retval EFI_SUCCESS The receive completion token was cached. + @retval EFI_NOT_STARTED This EFI TCPv4 Protocol instance has not been configured. + @retval EFI_NO_MAPPING When using a default address, configuration (DHCP, BOOTP, RARP, + etc.) is not finished yet. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - Token is NULL. + - Token->CompletionToken.Event is NULL. + - Token->Packet.RxData is NULL. + - Token->Packet.RxData->DataLength is 0. + - The Token->Packet.RxData->DataLength is not + the sum of all FragmentBuffer length in FragmentTable. + @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of + system resources (usually memory). + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE: + - A receive completion token with the same Token- + >CompletionToken.Event was already in the receive + queue. + - The current instance is in Tcp4StateClosed state. + - The current instance is a passive one and it is in + Tcp4StateListen state. + - User has called Close() to disconnect this connection. + @retval EFI_CONNECTION_FIN The communication peer has closed the connection and there is + no any buffered data in the receive buffer of this instance. + @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_RECEIVE)( + IN EFI_TCP4_PROTOCOL *This, + IN EFI_TCP4_IO_TOKEN *Token + ); + +/** + Disconnecting a TCP connection gracefully or reset a TCP connection. This function is a + nonblocking operation. + + @param This The pointer to the EFI_TCP4_PROTOCOL instance. + @param CloseToken The pointer to the close token to return when operation finishes. + + @retval EFI_SUCCESS The Close() is called successfully. + @retval EFI_NOT_STARTED This EFI TCPv4 Protocol instance has not been configured. + @retval EFI_ACCESS_DENIED One or more of the following are TRUE: + - Configure() has been called with + TcpConfigData set to NULL and this function has + not returned. + - Previous Close() call on this instance has not + finished. + @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: + - This is NULL. + - CloseToken is NULL. + - CloseToken->CompletionToken.Event is NULL. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the operation. + @retval EFI_DEVICE_ERROR Any unexpected and not belonged to above category error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_CLOSE)( + IN EFI_TCP4_PROTOCOL *This, + IN EFI_TCP4_CLOSE_TOKEN *CloseToken + ); + +/** + Abort an asynchronous connection, listen, transmission or receive request. + + @param This The pointer to the EFI_TCP4_PROTOCOL instance. + @param Token The pointer to a token that has been issued by + EFI_TCP4_PROTOCOL.Connect(), + EFI_TCP4_PROTOCOL.Accept(), + EFI_TCP4_PROTOCOL.Transmit() or + EFI_TCP4_PROTOCOL.Receive(). If NULL, all pending + tokens issued by above four functions will be aborted. Type + EFI_TCP4_COMPLETION_TOKEN is defined in + EFI_TCP4_PROTOCOL.Connect(). + + @retval EFI_SUCCESS The asynchronous I/O request is aborted and Token->Event + is signaled. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_STARTED This instance hasn't been configured. + @retval EFI_NO_MAPPING When using the default address, configuration + (DHCP, BOOTP,RARP, etc.) hasn't finished yet. + @retval EFI_NOT_FOUND The asynchronous I/O request isn't found in the + transmission or receive queue. It has either + completed or wasn't issued by Transmit() and Receive(). + @retval EFI_UNSUPPORTED The implementation does not support this function. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_CANCEL)( + IN EFI_TCP4_PROTOCOL *This, + IN EFI_TCP4_COMPLETION_TOKEN *Token OPTIONAL + ); + +/** + Poll to receive incoming data and transmit outgoing segments. + + @param This The pointer to the EFI_TCP4_PROTOCOL instance. + + @retval EFI_SUCCESS Incoming or outgoing data was processed. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_NOT_READY No incoming or outgoing data is processed. + @retval EFI_TIMEOUT Data was dropped out of the transmission or receive queue. + Consider increasing the polling rate. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_POLL)( + IN EFI_TCP4_PROTOCOL *This + ); + +/// +/// The EFI_TCP4_PROTOCOL defines the EFI TCPv4 Protocol child to be used by +/// any network drivers or applications to send or receive data stream. +/// It can either listen on a specified port as a service or actively connected +/// to remote peer as a client. Each instance has its own independent settings, +/// such as the routing table. +/// +struct _EFI_TCP4_PROTOCOL { + EFI_TCP4_GET_MODE_DATA GetModeData; + EFI_TCP4_CONFIGURE Configure; + EFI_TCP4_ROUTES Routes; + EFI_TCP4_CONNECT Connect; + EFI_TCP4_ACCEPT Accept; + EFI_TCP4_TRANSMIT Transmit; + EFI_TCP4_RECEIVE Receive; + EFI_TCP4_CLOSE Close; + EFI_TCP4_CANCEL Cancel; + EFI_TCP4_POLL Poll; +}; + +extern EFI_GUID gEfiTcp4ServiceBindingProtocolGuid; +extern EFI_GUID gEfiTcp4ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Tcp6.h b/sys/contrib/edk2/Include/Protocol/Tcp6.h new file mode 100644 index 000000000000..dd7f4bad4879 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Tcp6.h @@ -0,0 +1,856 @@ +/** @file + EFI TCPv6(Transmission Control Protocol version 6) Protocol Definition + The EFI TCPv6 Service Binding Protocol is used to locate EFI TCPv6 Protocol drivers to create + and destroy child of the driver to communicate with other host using TCP protocol. + The EFI TCPv6 Protocol provides services to send and receive data stream. + + Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.2 + +**/ + +#ifndef __EFI_TCP6_PROTOCOL_H__ +#define __EFI_TCP6_PROTOCOL_H__ + +#include <Protocol/ManagedNetwork.h> +#include <Protocol/Ip6.h> + +#define EFI_TCP6_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0xec20eb79, 0x6c1a, 0x4664, {0x9a, 0x0d, 0xd2, 0xe4, 0xcc, 0x16, 0xd6, 0x64 } \ + } + +#define EFI_TCP6_PROTOCOL_GUID \ + { \ + 0x46e44855, 0xbd60, 0x4ab7, {0xab, 0x0d, 0xa6, 0x79, 0xb9, 0x44, 0x7d, 0x77 } \ + } + +typedef struct _EFI_TCP6_PROTOCOL EFI_TCP6_PROTOCOL; + +/// +/// EFI_TCP6_SERVICE_POINT is deprecated in the UEFI 2.4B and should not be used any more. +/// The definition in here is only present to provide backwards compatability. +/// +typedef struct { + /// + /// The EFI TCPv6 Protocol instance handle that is using this + /// address/port pair. + /// + EFI_HANDLE InstanceHandle; + /// + /// The local IPv6 address to which this TCP instance is bound. Set + /// to 0::/128, if this TCP instance is configured to listen on all + /// available source addresses. + /// + EFI_IPv6_ADDRESS LocalAddress; + /// + /// The local port number in host byte order. + /// + UINT16 LocalPort; + /// + /// The remote IPv6 address. It may be 0::/128 if this TCP instance is + /// not connected to any remote host. + /// + EFI_IPv6_ADDRESS RemoteAddress; + /// + /// The remote port number in host byte order. It may be zero if this + /// TCP instance is not connected to any remote host. + /// + UINT16 RemotePort; +} EFI_TCP6_SERVICE_POINT; + +/// +/// EFI_TCP6_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more. +/// The definition in here is only present to provide backwards compatability. +/// +typedef struct { + EFI_HANDLE DriverHandle; ///< The handle of the driver that creates this entry. + UINT32 ServiceCount; ///< The number of address/port pairs following this data structure. + EFI_TCP6_SERVICE_POINT Services[1]; ///< List of address/port pairs that are currently in use. +} EFI_TCP6_VARIABLE_DATA; + +/// +/// EFI_TCP6_ACCESS_POINT +/// +typedef struct { + /// + /// The local IP address assigned to this TCP instance. The EFI + /// TCPv6 driver will only deliver incoming packets whose + /// destination addresses exactly match the IP address. Set to zero to + /// let the underlying IPv6 driver choose a source address. If not zero + /// it must be one of the configured IP addresses in the underlying + /// IPv6 driver. + /// + EFI_IPv6_ADDRESS StationAddress; + /// + /// The local port number to which this EFI TCPv6 Protocol instance + /// is bound. If the instance doesn't care the local port number, set + /// StationPort to zero to use an ephemeral port. + /// + UINT16 StationPort; + /// + /// The remote IP address to which this EFI TCPv6 Protocol instance + /// is connected. If ActiveFlag is FALSE (i.e. a passive TCPv6 + /// instance), the instance only accepts connections from the + /// RemoteAddress. If ActiveFlag is TRUE the instance will + /// connect to the RemoteAddress, i.e., outgoing segments will be + /// sent to this address and only segments from this address will be + /// delivered to the application. When ActiveFlag is FALSE, it + /// can be set to zero and means that incoming connection requests + /// from any address will be accepted. + /// + EFI_IPv6_ADDRESS RemoteAddress; + /// + /// The remote port to which this EFI TCPv6 Protocol instance + /// connects or from which connection request will be accepted by + /// this EFI TCPv6 Protocol instance. If ActiveFlag is FALSE it + /// can be zero and means that incoming connection request from + /// any port will be accepted. Its value can not be zero when + /// ActiveFlag is TRUE. + /// + UINT16 RemotePort; + /// + /// Set it to TRUE to initiate an active open. Set it to FALSE to + /// initiate a passive open to act as a server. + /// + BOOLEAN ActiveFlag; +} EFI_TCP6_ACCESS_POINT; + +/// +/// EFI_TCP6_OPTION +/// +typedef struct { + /// + /// The size of the TCP receive buffer. + /// + UINT32 ReceiveBufferSize; + /// + /// The size of the TCP send buffer. + /// + UINT32 SendBufferSize; + /// + /// The length of incoming connect request queue for a passive + /// instance. When set to zero, the value is implementation specific. + /// + UINT32 MaxSynBackLog; + /// + /// The maximum seconds a TCP instance will wait for before a TCP + /// connection established. When set to zero, the value is + /// implementation specific. + /// + UINT32 ConnectionTimeout; + /// + /// The number of times TCP will attempt to retransmit a packet on + /// an established connection. When set to zero, the value is + /// implementation specific. + /// + UINT32 DataRetries; + /// + /// How many seconds to wait in the FIN_WAIT_2 states for a final + /// FIN flag before the TCP instance is closed. This timeout is in + /// effective only if the application has called Close() to + /// disconnect the connection completely. It is also called + /// FIN_WAIT_2 timer in other implementations. When set to zero, + /// it should be disabled because the FIN_WAIT_2 timer itself is + /// against the standard. The default value is 60. + /// + UINT32 FinTimeout; + /// + /// How many seconds to wait in TIME_WAIT state before the TCP + /// instance is closed. The timer is disabled completely to provide a + /// method to close the TCP connection quickly if it is set to zero. It + /// is against the related RFC documents. + /// + UINT32 TimeWaitTimeout; + /// + /// The maximum number of TCP keep-alive probes to send before + /// giving up and resetting the connection if no response from the + /// other end. Set to zero to disable keep-alive probe. + /// + UINT32 KeepAliveProbes; + /// + /// The number of seconds a connection needs to be idle before TCP + /// sends out periodical keep-alive probes. When set to zero, the + /// value is implementation specific. It should be ignored if keep- + /// alive probe is disabled. + /// + UINT32 KeepAliveTime; + /// + /// The number of seconds between TCP keep-alive probes after the + /// periodical keep-alive probe if no response. When set to zero, the + /// value is implementation specific. It should be ignored if keep- + /// alive probe is disabled. + /// + UINT32 KeepAliveInterval; + /// + /// Set it to TRUE to enable the Nagle algorithm as defined in + /// RFC896. Set it to FALSE to disable it. + /// + BOOLEAN EnableNagle; + /// + /// Set it to TRUE to enable TCP timestamps option as defined in + /// RFC7323. Set to FALSE to disable it. + /// + BOOLEAN EnableTimeStamp; + /// + /// Set it to TRUE to enable TCP window scale option as defined in + /// RFC7323. Set it to FALSE to disable it. + /// + BOOLEAN EnableWindowScaling; + /// + /// Set it to TRUE to enable selective acknowledge mechanism + /// described in RFC 2018. Set it to FALSE to disable it. + /// Implementation that supports SACK can optionally support + /// DSAK as defined in RFC 2883. + /// + BOOLEAN EnableSelectiveAck; + /// + /// Set it to TRUE to enable path MTU discovery as defined in + /// RFC 1191. Set to FALSE to disable it. + /// + BOOLEAN EnablePathMtuDiscovery; +} EFI_TCP6_OPTION; + +/// +/// EFI_TCP6_CONFIG_DATA +/// +typedef struct { + /// + /// TrafficClass field in transmitted IPv6 packets. + /// + UINT8 TrafficClass; + /// + /// HopLimit field in transmitted IPv6 packets. + /// + UINT8 HopLimit; + /// + /// Used to specify TCP communication end settings for a TCP instance. + /// + EFI_TCP6_ACCESS_POINT AccessPoint; + /// + /// Used to configure the advance TCP option for a connection. If set + /// to NULL, implementation specific options for TCP connection will be used. + /// + EFI_TCP6_OPTION *ControlOption; +} EFI_TCP6_CONFIG_DATA; + +/// +/// EFI_TCP6_CONNECTION_STATE +/// +typedef enum { + Tcp6StateClosed = 0, + Tcp6StateListen = 1, + Tcp6StateSynSent = 2, + Tcp6StateSynReceived = 3, + Tcp6StateEstablished = 4, + Tcp6StateFinWait1 = 5, + Tcp6StateFinWait2 = 6, + Tcp6StateClosing = 7, + Tcp6StateTimeWait = 8, + Tcp6StateCloseWait = 9, + Tcp6StateLastAck = 10 +} EFI_TCP6_CONNECTION_STATE; + +/// +/// EFI_TCP6_COMPLETION_TOKEN +/// is used as a common header for various asynchronous tokens. +/// +typedef struct { + /// + /// The Event to signal after request is finished and Status field is + /// updated by the EFI TCPv6 Protocol driver. + /// + EFI_EVENT Event; + /// + /// The result of the completed operation. + /// + EFI_STATUS Status; +} EFI_TCP6_COMPLETION_TOKEN; + +/// +/// EFI_TCP6_CONNECTION_TOKEN +/// will be set if the active open succeeds or an unexpected +/// error happens. +/// +typedef struct { + /// + /// The Status in the CompletionToken will be set to one of + /// the following values if the active open succeeds or an unexpected + /// error happens: + /// EFI_SUCCESS: The active open succeeds and the instance's + /// state is Tcp6StateEstablished. + /// EFI_CONNECTION_RESET: The connect fails because the connection is reset + /// either by instance itself or the communication peer. + /// EFI_CONNECTION_REFUSED: The receiving or transmission operation fails because this + /// connection is refused. + /// EFI_ABORTED: The active open is aborted. + /// EFI_TIMEOUT: The connection establishment timer expires and + /// no more specific information is available. + /// EFI_NETWORK_UNREACHABLE: The active open fails because + /// an ICMP network unreachable error is received. + /// EFI_HOST_UNREACHABLE: The active open fails because an + /// ICMP host unreachable error is received. + /// EFI_PROTOCOL_UNREACHABLE: The active open fails + /// because an ICMP protocol unreachable error is received. + /// EFI_PORT_UNREACHABLE: The connection establishment + /// timer times out and an ICMP port unreachable error is received. + /// EFI_ICMP_ERROR: The connection establishment timer times + /// out and some other ICMP error is received. + /// EFI_DEVICE_ERROR: An unexpected system or network error occurred. + /// EFI_SECURITY_VIOLATION: The active open was failed because of IPSec policy check. + /// EFI_NO_MEDIA: There was a media error. + /// + EFI_TCP6_COMPLETION_TOKEN CompletionToken; +} EFI_TCP6_CONNECTION_TOKEN; + +/// +/// EFI_TCP6_LISTEN_TOKEN +/// returns when list operation finishes. +/// +typedef struct { + /// + /// The Status in CompletionToken will be set to the + /// following value if accept finishes: + /// EFI_SUCCESS: A remote peer has successfully established a + /// connection to this instance. A new TCP instance has also been + /// created for the connection. + /// EFI_CONNECTION_RESET: The accept fails because the connection is reset either + /// by instance itself or communication peer. + /// EFI_ABORTED: The accept request has been aborted. + /// EFI_SECURITY_VIOLATION: The accept operation was failed because of IPSec policy check. + /// + EFI_TCP6_COMPLETION_TOKEN CompletionToken; + EFI_HANDLE NewChildHandle; +} EFI_TCP6_LISTEN_TOKEN; + +/// +/// EFI_TCP6_FRAGMENT_DATA +/// allows multiple receive or transmit buffers to be specified. The +/// purpose of this structure is to provide scattered read and write. +/// +typedef struct { + UINT32 FragmentLength; ///< Length of data buffer in the fragment. + VOID *FragmentBuffer; ///< Pointer to the data buffer in the fragment. +} EFI_TCP6_FRAGMENT_DATA; + +/// +/// EFI_TCP6_RECEIVE_DATA +/// When TCPv6 driver wants to deliver received data to the application, +/// it will pick up the first queued receiving token, update its +/// Token->Packet.RxData then signal the Token->CompletionToken.Event. +/// +typedef struct { + /// + /// Whether the data is urgent. When this flag is set, the instance is in + /// urgent mode. + /// + BOOLEAN UrgentFlag; + /// + /// When calling Receive() function, it is the byte counts of all + /// Fragmentbuffer in FragmentTable allocated by user. + /// When the token is signaled by TCPv6 driver it is the length of + /// received data in the fragments. + /// + UINT32 DataLength; + /// + /// Number of fragments. + /// + UINT32 FragmentCount; + /// + /// An array of fragment descriptors. + /// + EFI_TCP6_FRAGMENT_DATA FragmentTable[1]; +} EFI_TCP6_RECEIVE_DATA; + +/// +/// EFI_TCP6_TRANSMIT_DATA +/// The EFI TCPv6 Protocol user must fill this data structure before sending a packet. +/// The packet may contain multiple buffers in non-continuous memory locations. +/// +typedef struct { + /// + /// Push If TRUE, data must be transmitted promptly, and the PUSH bit in + /// the last TCP segment created will be set. If FALSE, data + /// transmission may be delayed to combine with data from + /// subsequent Transmit()s for efficiency. + /// + BOOLEAN Push; + /// + /// The data in the fragment table are urgent and urgent point is in + /// effect if TRUE. Otherwise those data are NOT considered urgent. + /// + BOOLEAN Urgent; + /// + /// Length of the data in the fragments. + /// + UINT32 DataLength; + /// + /// Number of fragments. + /// + UINT32 FragmentCount; + /// + /// An array of fragment descriptors. + /// + EFI_TCP6_FRAGMENT_DATA FragmentTable[1]; +} EFI_TCP6_TRANSMIT_DATA; + +/// +/// EFI_TCP6_IO_TOKEN +/// returns When transmission finishes or meets any unexpected error. +/// +typedef struct { + /// + /// When transmission finishes or meets any unexpected error it will + /// be set to one of the following values: + /// EFI_SUCCESS: The receiving or transmission operation + /// completes successfully. + /// EFI_CONNECTION_FIN: The receiving operation fails because the communication peer + /// has closed the connection and there is no more data in the + /// receive buffer of the instance. + /// EFI_CONNECTION_RESET: The receiving or transmission operation fails + /// because this connection is reset either by instance + /// itself or the communication peer. + /// EFI_ABORTED: The receiving or transmission is aborted. + /// EFI_TIMEOUT: The transmission timer expires and no more + /// specific information is available. + /// EFI_NETWORK_UNREACHABLE: The transmission fails + /// because an ICMP network unreachable error is received. + /// EFI_HOST_UNREACHABLE: The transmission fails because an + /// ICMP host unreachable error is received. + /// EFI_PROTOCOL_UNREACHABLE: The transmission fails + /// because an ICMP protocol unreachable error is received. + /// EFI_PORT_UNREACHABLE: The transmission fails and an + /// ICMP port unreachable error is received. + /// EFI_ICMP_ERROR: The transmission fails and some other + /// ICMP error is received. + /// EFI_DEVICE_ERROR: An unexpected system or network error occurs. + /// EFI_SECURITY_VIOLATION: The receiving or transmission + /// operation was failed because of IPSec policy check + /// EFI_NO_MEDIA: There was a media error. + /// + EFI_TCP6_COMPLETION_TOKEN CompletionToken; + union { + /// + /// When this token is used for receiving, RxData is a pointer to + /// EFI_TCP6_RECEIVE_DATA. + /// + EFI_TCP6_RECEIVE_DATA *RxData; + /// + /// When this token is used for transmitting, TxData is a pointer to + /// EFI_TCP6_TRANSMIT_DATA. + /// + EFI_TCP6_TRANSMIT_DATA *TxData; + } Packet; +} EFI_TCP6_IO_TOKEN; + +/// +/// EFI_TCP6_CLOSE_TOKEN +/// returns when close operation finishes. +/// +typedef struct { + /// + /// When close finishes or meets any unexpected error it will be set + /// to one of the following values: + /// EFI_SUCCESS: The close operation completes successfully. + /// EFI_ABORTED: User called configure with NULL without close stopping. + /// EFI_SECURITY_VIOLATION: The close operation was failed because of IPSec policy check. + /// + EFI_TCP6_COMPLETION_TOKEN CompletionToken; + /// + /// Abort the TCP connection on close instead of the standard TCP + /// close process when it is set to TRUE. This option can be used to + /// satisfy a fast disconnect. + /// + BOOLEAN AbortOnClose; +} EFI_TCP6_CLOSE_TOKEN; + +/** + Get the current operational status. + + The GetModeData() function copies the current operational settings of this EFI TCPv6 + Protocol instance into user-supplied buffers. This function can also be used to retrieve + the operational setting of underlying drivers such as IPv6, MNP, or SNP. + + @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. + @param[out] Tcp6State The buffer in which the current TCP state is returned. + @param[out] Tcp6ConfigData The buffer in which the current TCP configuration is returned. + @param[out] Ip6ModeData The buffer in which the current IPv6 configuration data used by + the TCP instance is returned. + @param[out] MnpConfigData The buffer in which the current MNP configuration data used + indirectly by the TCP instance is returned. + @param[out] SnpModeData The buffer in which the current SNP mode data used indirectly by + the TCP instance is returned. + + @retval EFI_SUCCESS The mode data was read. + @retval EFI_NOT_STARTED No configuration data is available because this instance hasn't + been started. + @retval EFI_INVALID_PARAMETER This is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_GET_MODE_DATA)( + IN EFI_TCP6_PROTOCOL *This, + OUT EFI_TCP6_CONNECTION_STATE *Tcp6State OPTIONAL, + OUT EFI_TCP6_CONFIG_DATA *Tcp6ConfigData OPTIONAL, + OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL, + OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, + OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL + ); + +/** + Initialize or brutally reset the operational parameters for this EFI TCPv6 instance. + + The Configure() function does the following: + - Initialize this TCP instance, i.e., initialize the communication end settings and + specify active open or passive open for an instance. + - Reset this TCP instance brutally, i.e., cancel all pending asynchronous tokens, flush + transmission and receiving buffer directly without informing the communication peer. + + No other TCPv6 Protocol operation except Poll() can be executed by this instance until + it is configured properly. For an active TCP instance, after a proper configuration it + may call Connect() to initiates the three-way handshake. For a passive TCP instance, + its state will transit to Tcp6StateListen after configuration, and Accept() may be + called to listen the incoming TCP connection requests. If Tcp6ConfigData is set to NULL, + the instance is reset. Resetting process will be done brutally, the state machine will + be set to Tcp6StateClosed directly, the receive queue and transmit queue will be flushed, + and no traffic is allowed through this instance. + + @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. + @param[in] Tcp6ConfigData Pointer to the configure data to configure the instance. + If Tcp6ConfigData is set to NULL, the instance is reset. + + @retval EFI_SUCCESS The operational settings are set, changed, or reset + successfully. + @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source + address for this instance, but no source address was available for + use. + @retval EFI_INVALID_PARAMETER One or more of the following conditions are TRUE: + - This is NULL. + - Tcp6ConfigData->AccessPoint.StationAddress is neither zero nor + one of the configured IP addresses in the underlying IPv6 driver. + - Tcp6ConfigData->AccessPoint.RemoteAddress isn't a valid unicast + IPv6 address. + - Tcp6ConfigData->AccessPoint.RemoteAddress is zero or + Tcp6ConfigData->AccessPoint.RemotePort is zero when + Tcp6ConfigData->AccessPoint.ActiveFlag is TRUE. + - A same access point has been configured in other TCP + instance properly. + @retval EFI_ACCESS_DENIED Configuring TCP instance when it is configured without + calling Configure() with NULL to reset it. + @retval EFI_UNSUPPORTED One or more of the control options are not supported in + the implementation. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources when + executing Configure(). + @retval EFI_DEVICE_ERROR An unexpected network or system error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_CONFIGURE)( + IN EFI_TCP6_PROTOCOL *This, + IN EFI_TCP6_CONFIG_DATA *Tcp6ConfigData OPTIONAL + ); + +/** + Initiate a nonblocking TCP connection request for an active TCP instance. + + The Connect() function will initiate an active open to the remote peer configured + in current TCP instance if it is configured active. If the connection succeeds or + fails due to any error, the ConnectionToken->CompletionToken.Event will be signaled + and ConnectionToken->CompletionToken.Status will be updated accordingly. This + function can only be called for the TCP instance in Tcp6StateClosed state. The + instance will transfer into Tcp6StateSynSent if the function returns EFI_SUCCESS. + If TCP three-way handshake succeeds, its state will become Tcp6StateEstablished, + otherwise, the state will return to Tcp6StateClosed. + + @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. + @param[in] ConnectionToken Pointer to the connection token to return when the TCP three + way handshake finishes. + + @retval EFI_SUCCESS The connection request is successfully initiated and the state of + this TCP instance has been changed to Tcp6StateSynSent. + @retval EFI_NOT_STARTED This EFI TCPv6 Protocol instance has not been configured. + @retval EFI_ACCESS_DENIED One or more of the following conditions are TRUE: + - This instance is not configured as an active one. + - This instance is not in Tcp6StateClosed state. + @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: + - This is NULL. + - ConnectionToken is NULL. + - ConnectionToken->CompletionToken.Event is NULL. + @retval EFI_OUT_OF_RESOURCES The driver can't allocate enough resource to initiate the active open. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_CONNECT)( + IN EFI_TCP6_PROTOCOL *This, + IN EFI_TCP6_CONNECTION_TOKEN *ConnectionToken + ); + +/** + Listen on the passive instance to accept an incoming connection request. This is a + nonblocking operation. + + The Accept() function initiates an asynchronous accept request to wait for an incoming + connection on the passive TCP instance. If a remote peer successfully establishes a + connection with this instance, a new TCP instance will be created and its handle will + be returned in ListenToken->NewChildHandle. The newly created instance is configured + by inheriting the passive instance's configuration and is ready for use upon return. + The new instance is in the Tcp6StateEstablished state. + + The ListenToken->CompletionToken.Event will be signaled when a new connection is + accepted, user aborts the listen or connection is reset. + + This function only can be called when current TCP instance is in Tcp6StateListen state. + + @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. + @param[in] ListenToken Pointer to the listen token to return when operation finishes. + + + @retval EFI_SUCCESS The listen token has been queued successfully. + @retval EFI_NOT_STARTED This EFI TCPv6 Protocol instance has not been configured. + @retval EFI_ACCESS_DENIED One or more of the following are TRUE: + - This instance is not a passive instance. + - This instance is not in Tcp6StateListen state. + - The same listen token has already existed in the listen + token queue of this TCP instance. + @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: + - This is NULL. + - ListenToken is NULL. + - ListentToken->CompletionToken.Event is NULL. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the operation. + @retval EFI_DEVICE_ERROR Any unexpected and not belonged to above category error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_ACCEPT)( + IN EFI_TCP6_PROTOCOL *This, + IN EFI_TCP6_LISTEN_TOKEN *ListenToken + ); + +/** + Queues outgoing data into the transmit queue. + + The Transmit() function queues a sending request to this TCP instance along with the + user data. The status of the token is updated and the event in the token will be + signaled once the data is sent out or some error occurs. + + @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. + @param[in] Token Pointer to the completion token to queue to the transmit queue. + + @retval EFI_SUCCESS The data has been queued for transmission. + @retval EFI_NOT_STARTED This EFI TCPv6 Protocol instance has not been configured. + @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a + source address for this instance, but no source address was + available for use. + @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: + - This is NULL. + - Token is NULL. + - Token->CompletionToken.Event is NULL. + - Token->Packet.TxData is NULL. + - Token->Packet.FragmentCount is zero. + - Token->Packet.DataLength is not equal to the sum of fragment lengths. + @retval EFI_ACCESS_DENIED One or more of the following conditions are TRUE: + - A transmit completion token with the same Token-> + CompletionToken.Event was already in the + transmission queue. + - The current instance is in Tcp6StateClosed state. + - The current instance is a passive one and it is in + Tcp6StateListen state. + - User has called Close() to disconnect this connection. + @retval EFI_NOT_READY The completion token could not be queued because the + transmit queue is full. + @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data because of resource + shortage. + @retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or address. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_TRANSMIT)( + IN EFI_TCP6_PROTOCOL *This, + IN EFI_TCP6_IO_TOKEN *Token + ); + +/** + Places an asynchronous receive request into the receiving queue. + + The Receive() function places a completion token into the receive packet queue. This + function is always asynchronous. The caller must allocate the Token->CompletionToken.Event + and the FragmentBuffer used to receive data. The caller also must fill the DataLength which + represents the whole length of all FragmentBuffer. When the receive operation completes, the + EFI TCPv6 Protocol driver updates the Token->CompletionToken.Status and Token->Packet.RxData + fields and the Token->CompletionToken.Event is signaled. If got data the data and its length + will be copied into the FragmentTable, at the same time the full length of received data will + be recorded in the DataLength fields. Providing a proper notification function and context + for the event will enable the user to receive the notification and receiving status. That + notification function is guaranteed to not be re-entered. + + @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. + @param[in] Token Pointer to a token that is associated with the receive data + descriptor. + + @retval EFI_SUCCESS The receive completion token was cached. + @retval EFI_NOT_STARTED This EFI TCPv6 Protocol instance has not been configured. + @retval EFI_NO_MAPPING The underlying IPv6 driver was responsible for choosing a source + address for this instance, but no source address was available for use. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - This is NULL. + - Token is NULL. + - Token->CompletionToken.Event is NULL. + - Token->Packet.RxData is NULL. + - Token->Packet.RxData->DataLength is 0. + - The Token->Packet.RxData->DataLength is not the + sum of all FragmentBuffer length in FragmentTable. + @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of + system resources (usually memory). + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + The EFI TCPv6 Protocol instance has been reset to startup defaults. + @retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE: + - A receive completion token with the same Token->CompletionToken.Event + was already in the receive queue. + - The current instance is in Tcp6StateClosed state. + - The current instance is a passive one and it is in + Tcp6StateListen state. + - User has called Close() to disconnect this connection. + @retval EFI_CONNECTION_FIN The communication peer has closed the connection and there is no + any buffered data in the receive buffer of this instance + @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_RECEIVE)( + IN EFI_TCP6_PROTOCOL *This, + IN EFI_TCP6_IO_TOKEN *Token + ); + +/** + Disconnecting a TCP connection gracefully or reset a TCP connection. This function is a + nonblocking operation. + + Initiate an asynchronous close token to TCP driver. After Close() is called, any buffered + transmission data will be sent by TCP driver and the current instance will have a graceful close + working flow described as RFC 793 if AbortOnClose is set to FALSE, otherwise, a rest packet + will be sent by TCP driver to fast disconnect this connection. When the close operation completes + successfully the TCP instance is in Tcp6StateClosed state, all pending asynchronous + operations are signaled and any buffers used for TCP network traffic are flushed. + + @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. + @param[in] CloseToken Pointer to the close token to return when operation finishes. + + @retval EFI_SUCCESS The Close() is called successfully. + @retval EFI_NOT_STARTED This EFI TCPv6 Protocol instance has not been configured. + @retval EFI_ACCESS_DENIED One or more of the following are TRUE: + - CloseToken or CloseToken->CompletionToken.Event is already in use. + - Previous Close() call on this instance has not finished. + @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: + - This is NULL. + - CloseToken is NULL. + - CloseToken->CompletionToken.Event is NULL. + @retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the operation. + @retval EFI_DEVICE_ERROR Any unexpected and not belonged to above category error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_CLOSE)( + IN EFI_TCP6_PROTOCOL *This, + IN EFI_TCP6_CLOSE_TOKEN *CloseToken + ); + +/** + Abort an asynchronous connection, listen, transmission or receive request. + + The Cancel() function aborts a pending connection, listen, transmit or + receive request. + + If Token is not NULL and the token is in the connection, listen, transmission + or receive queue when it is being cancelled, its Token->Status will be set + to EFI_ABORTED and then Token->Event will be signaled. + + If the token is not in one of the queues, which usually means that the + asynchronous operation has completed, EFI_NOT_FOUND is returned. + + If Token is NULL all asynchronous token issued by Connect(), Accept(), + Transmit() and Receive() will be aborted. + + @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. + @param[in] Token Pointer to a token that has been issued by + EFI_TCP6_PROTOCOL.Connect(), + EFI_TCP6_PROTOCOL.Accept(), + EFI_TCP6_PROTOCOL.Transmit() or + EFI_TCP6_PROTOCOL.Receive(). If NULL, all pending + tokens issued by above four functions will be aborted. Type + EFI_TCP6_COMPLETION_TOKEN is defined in + EFI_TCP_PROTOCOL.Connect(). + + @retval EFI_SUCCESS The asynchronous I/O request is aborted and Token->Event + is signaled. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_NOT_STARTED This instance hasn't been configured. + @retval EFI_NOT_FOUND The asynchronous I/O request isn't found in the transmission or + receive queue. It has either completed or wasn't issued by + Transmit() and Receive(). + @retval EFI_UNSUPPORTED The implementation does not support this function. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_CANCEL)( + IN EFI_TCP6_PROTOCOL *This, + IN EFI_TCP6_COMPLETION_TOKEN *Token OPTIONAL + ); + +/** + Poll to receive incoming data and transmit outgoing segments. + + The Poll() function increases the rate that data is moved between the network + and application and can be called when the TCP instance is created successfully. + Its use is optional. + + @param[in] This Pointer to the EFI_TCP6_PROTOCOL instance. + + @retval EFI_SUCCESS Incoming or outgoing data was processed. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_NOT_READY No incoming or outgoing data is processed. + @retval EFI_TIMEOUT Data was dropped out of the transmission or receive queue. + Consider increasing the polling rate. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_POLL)( + IN EFI_TCP6_PROTOCOL *This + ); + +/// +/// EFI_TCP6_PROTOCOL +/// defines the EFI TCPv6 Protocol child to be used by any network drivers or +/// applications to send or receive data stream. It can either listen on a +/// specified port as a service or actively connect to remote peer as a client. +/// Each instance has its own independent settings. +/// +struct _EFI_TCP6_PROTOCOL { + EFI_TCP6_GET_MODE_DATA GetModeData; + EFI_TCP6_CONFIGURE Configure; + EFI_TCP6_CONNECT Connect; + EFI_TCP6_ACCEPT Accept; + EFI_TCP6_TRANSMIT Transmit; + EFI_TCP6_RECEIVE Receive; + EFI_TCP6_CLOSE Close; + EFI_TCP6_CANCEL Cancel; + EFI_TCP6_POLL Poll; +}; + +extern EFI_GUID gEfiTcp6ServiceBindingProtocolGuid; +extern EFI_GUID gEfiTcp6ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Timer.h b/sys/contrib/edk2/Include/Protocol/Timer.h new file mode 100644 index 000000000000..384368c9242f --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Timer.h @@ -0,0 +1,173 @@ +/** @file + Timer Architectural Protocol as defined in PI Specification VOLUME 2 DXE + + This code is used to provide the timer tick for the DXE core. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_TIMER_H__ +#define __ARCH_PROTOCOL_TIMER_H__ + +/// +/// Global ID for the Timer Architectural Protocol +/// +#define EFI_TIMER_ARCH_PROTOCOL_GUID \ + { 0x26baccb3, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +/// +/// Declare forward reference for the Timer Architectural Protocol +/// +typedef struct _EFI_TIMER_ARCH_PROTOCOL EFI_TIMER_ARCH_PROTOCOL; + +/** + This function of this type is called when a timer interrupt fires. This + function executes at TPL_HIGH_LEVEL. The DXE Core will register a function + of this type to be called for the timer interrupt, so it can know how much + time has passed. This information is used to signal timer based events. + + @param Time Time since the last timer interrupt in 100 ns units. This will + typically be TimerPeriod, but if a timer interrupt is missed, and the + EFI_TIMER_ARCH_PROTOCOL driver can detect missed interrupts, then Time + will contain the actual amount of time since the last interrupt. + + None. + +**/ +typedef +VOID +(EFIAPI *EFI_TIMER_NOTIFY)( + IN UINT64 Time + ); + +/** + This function registers the handler NotifyFunction so it is called every time + the timer interrupt fires. It also passes the amount of time since the last + handler call to the NotifyFunction. If NotifyFunction is NULL, then the + handler is unregistered. If the handler is registered, then EFI_SUCCESS is + returned. If the CPU does not support registering a timer interrupt handler, + then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler + when a handler is already registered, then EFI_ALREADY_STARTED is returned. + If an attempt is made to unregister a handler when a handler is not registered, + then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to + register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR + is returned. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param NotifyFunction The function to call when a timer interrupt fires. This + function executes at TPL_HIGH_LEVEL. The DXE Core will + register a handler for the timer interrupt, so it can know + how much time has passed. This information is used to + signal timer based events. NULL will unregister the handler. + + @retval EFI_SUCCESS The timer handler was registered. + @retval EFI_UNSUPPORTED The platform does not support timer interrupts. + @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already + registered. + @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not + previously registered. + @retval EFI_DEVICE_ERROR The timer handler could not be registered. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TIMER_REGISTER_HANDLER)( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction + ); + +/** + This function adjusts the period of timer interrupts to the value specified + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust the + interrupt controller so that a CPU interrupt is not generated when the timer + interrupt fires. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is + returned. If the timer is programmable, then the timer period + will be rounded up to the nearest timer period that is supported + by the timer hardware. If TimerPeriod is set to 0, then the + timer interrupts will be disabled. + + @retval EFI_SUCCESS The timer period was changed. + @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt. + @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TIMER_SET_TIMER_PERIOD)( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ); + +/** + This function retrieves the period of timer interrupts in 100 ns units, + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is + returned, then the timer is currently disabled. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If + 0 is returned, then the timer is currently disabled. + + @retval EFI_SUCCESS The timer period was returned in TimerPeriod. + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TIMER_GET_TIMER_PERIOD)( + IN EFI_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ); + +/** + This function generates a soft timer interrupt. If the platform does not support soft + timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned. + If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() + service, then a soft timer interrupt will be generated. If the timer interrupt is + enabled when this service is called, then the registered handler will be invoked. The + registered handler should not be able to distinguish a hardware-generated timer + interrupt from a software-generated timer interrupt. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + + @retval EFI_SUCCESS The soft timer interrupt was generated. + @retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_TIMER_GENERATE_SOFT_INTERRUPT)( + IN EFI_TIMER_ARCH_PROTOCOL *This + ); + +/// +/// This protocol provides the services to initialize a periodic timer +/// interrupt, and to register a handler that is called each time the timer +/// interrupt fires. It may also provide a service to adjust the rate of the +/// periodic timer interrupt. When a timer interrupt occurs, the handler is +/// passed the amount of time that has passed since the previous timer +/// interrupt. +/// +struct _EFI_TIMER_ARCH_PROTOCOL { + EFI_TIMER_REGISTER_HANDLER RegisterHandler; + EFI_TIMER_SET_TIMER_PERIOD SetTimerPeriod; + EFI_TIMER_GET_TIMER_PERIOD GetTimerPeriod; + EFI_TIMER_GENERATE_SOFT_INTERRUPT GenerateSoftInterrupt; +}; + +extern EFI_GUID gEfiTimerArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/UgaDraw.h b/sys/contrib/edk2/Include/Protocol/UgaDraw.h new file mode 100644 index 000000000000..c47908a16073 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/UgaDraw.h @@ -0,0 +1,159 @@ +/** @file + UGA Draw protocol from the EFI 1.10 specification. + + Abstraction of a very simple graphics device. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __UGA_DRAW_H__ +#define __UGA_DRAW_H__ + +#define EFI_UGA_DRAW_PROTOCOL_GUID \ + { \ + 0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } \ + } + +typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL; + +/** + Return the current video mode information. + + @param This The EFI_UGA_DRAW_PROTOCOL instance. + @param HorizontalResolution The size of video screen in pixels in the X dimension. + @param VerticalResolution The size of video screen in pixels in the Y dimension. + @param ColorDepth Number of bits per pixel, currently defined to be 32. + @param RefreshRate The refresh rate of the monitor in Hertz. + + @retval EFI_SUCCESS Mode information returned. + @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () + @retval EFI_INVALID_PARAMETER One of the input args was NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_UGA_DRAW_PROTOCOL_GET_MODE)( + IN EFI_UGA_DRAW_PROTOCOL *This, + OUT UINT32 *HorizontalResolution, + OUT UINT32 *VerticalResolution, + OUT UINT32 *ColorDepth, + OUT UINT32 *RefreshRate + ); + +/** + Set the current video mode information. + + @param This The EFI_UGA_DRAW_PROTOCOL instance. + @param HorizontalResolution The size of video screen in pixels in the X dimension. + @param VerticalResolution The size of video screen in pixels in the Y dimension. + @param ColorDepth Number of bits per pixel, currently defined to be 32. + @param RefreshRate The refresh rate of the monitor in Hertz. + + @retval EFI_SUCCESS Mode information returned. + @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_UGA_DRAW_PROTOCOL_SET_MODE)( + IN EFI_UGA_DRAW_PROTOCOL *This, + IN UINT32 HorizontalResolution, + IN UINT32 VerticalResolution, + IN UINT32 ColorDepth, + IN UINT32 RefreshRate + ); + +typedef struct { + UINT8 Blue; + UINT8 Green; + UINT8 Red; + UINT8 Reserved; +} EFI_UGA_PIXEL; + +typedef union { + EFI_UGA_PIXEL Pixel; + UINT32 Raw; +} EFI_UGA_PIXEL_UNION; + +/// +/// Enumration value for actions of Blt operations. +/// +typedef enum { + EfiUgaVideoFill, ///< Write data from the BltBuffer pixel (SourceX, SourceY) + ///< directly to every pixel of the video display rectangle + ///< (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). + ///< Only one pixel will be used from the BltBuffer. Delta is NOT used. + + EfiUgaVideoToBltBuffer, ///< Read data from the video display rectangle + ///< (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in + ///< the BltBuffer rectangle (DestinationX, DestinationY ) + ///< (DestinationX + Width, DestinationY + Height). If DestinationX or + ///< DestinationY is not zero then Delta must be set to the length in bytes + ///< of a row in the BltBuffer. + + EfiUgaBltBufferToVideo, ///< Write data from the BltBuffer rectangle + ///< (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the + ///< video display rectangle (DestinationX, DestinationY) + ///< (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is + ///< not zero then Delta must be set to the length in bytes of a row in the + ///< BltBuffer. + + EfiUgaVideoToVideo, ///< Copy from the video display rectangle (SourceX, SourceY) + ///< (SourceX + Width, SourceY + Height) .to the video display rectangle + ///< (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). + ///< The BltBuffer and Delta are not used in this mode. + + EfiUgaBltMax ///< Maxmimum value for enumration value of Blt operation. If a Blt operation + ///< larger or equal to this enumration value, it is invalid. +} EFI_UGA_BLT_OPERATION; + +/** + Blt a rectangle of pixels on the graphics screen. + + @param[in] This - Protocol instance pointer. + @param[in] BltBuffer - Buffer containing data to blit into video buffer. This + buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL) + @param[in] BltOperation - Operation to perform on BlitBuffer and video memory + @param[in] SourceX - X coordinate of source for the BltBuffer. + @param[in] SourceY - Y coordinate of source for the BltBuffer. + @param[in] DestinationX - X coordinate of destination for the BltBuffer. + @param[in] DestinationY - Y coordinate of destination for the BltBuffer. + @param[in] Width - Width of rectangle in BltBuffer in pixels. + @param[in] Height - Hight of rectangle in BltBuffer in pixels. + @param[in] Delta - OPTIONAL + + @retval EFI_SUCCESS - The Blt operation completed. + @retval EFI_INVALID_PARAMETER - BltOperation is not valid. + @retval EFI_DEVICE_ERROR - A hardware error occurred writting to the video buffer. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_UGA_DRAW_PROTOCOL_BLT)( + IN EFI_UGA_DRAW_PROTOCOL *This, + IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, + IN EFI_UGA_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL + ); + +/// +/// This protocol provides a basic abstraction to set video modes and +/// copy pixels to and from the graphics controller's frame buffer. +/// +struct _EFI_UGA_DRAW_PROTOCOL { + EFI_UGA_DRAW_PROTOCOL_GET_MODE GetMode; + EFI_UGA_DRAW_PROTOCOL_SET_MODE SetMode; + EFI_UGA_DRAW_PROTOCOL_BLT Blt; +}; + +extern EFI_GUID gEfiUgaDrawProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/UgaIo.h b/sys/contrib/edk2/Include/Protocol/UgaIo.h new file mode 100644 index 000000000000..4fdfb279a03e --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/UgaIo.h @@ -0,0 +1,189 @@ +/** @file + UGA IO protocol from the EFI 1.10 specification. + + Abstraction of a very simple graphics device. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __UGA_IO_H__ +#define __UGA_IO_H__ + +#define EFI_UGA_IO_PROTOCOL_GUID \ + { 0x61a4d49e, 0x6f68, 0x4f1b, { 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0xb, 0x7, 0xa2 } } + +typedef struct _EFI_UGA_IO_PROTOCOL EFI_UGA_IO_PROTOCOL; + +typedef UINT32 UGA_STATUS; + +typedef enum { + UgaDtParentBus = 1, + UgaDtGraphicsController, + UgaDtOutputController, + UgaDtOutputPort, + UgaDtOther +} UGA_DEVICE_TYPE, *PUGA_DEVICE_TYPE; + +typedef UINT32 UGA_DEVICE_ID, *PUGA_DEVICE_ID; + +typedef struct { + UGA_DEVICE_TYPE deviceType; + UGA_DEVICE_ID deviceId; + UINT32 ui32DeviceContextSize; + UINT32 ui32SharedContextSize; +} UGA_DEVICE_DATA, *PUGA_DEVICE_DATA; + +typedef struct _UGA_DEVICE { + VOID *pvDeviceContext; + VOID *pvSharedContext; + VOID *pvRunTimeContext; + struct _UGA_DEVICE *pParentDevice; + VOID *pvBusIoServices; + VOID *pvStdIoServices; + UGA_DEVICE_DATA deviceData; +} UGA_DEVICE, *PUGA_DEVICE; + +typedef enum { + UgaIoGetVersion = 1, + UgaIoGetChildDevice, + UgaIoStartDevice, + UgaIoStopDevice, + UgaIoFlushDevice, + UgaIoResetDevice, + UgaIoGetDeviceState, + UgaIoSetDeviceState, + UgaIoSetPowerState, + UgaIoGetMemoryConfiguration, + UgaIoSetVideoMode, + UgaIoCopyRectangle, + UgaIoGetEdidSegment, + UgaIoDeviceChannelOpen, + UgaIoDeviceChannelClose, + UgaIoDeviceChannelRead, + UgaIoDeviceChannelWrite, + UgaIoGetPersistentDataSize, + UgaIoGetPersistentData, + UgaIoSetPersistentData, + UgaIoGetDevicePropertySize, + UgaIoGetDeviceProperty, + UgaIoBtPrivateInterface +} UGA_IO_REQUEST_CODE, *PUGA_IO_REQUEST_CODE; + +typedef struct { + IN UGA_IO_REQUEST_CODE ioRequestCode; + IN VOID *pvInBuffer; + IN UINT64 ui64InBufferSize; + OUT VOID *pvOutBuffer; + IN UINT64 ui64OutBufferSize; + OUT UINT64 ui64BytesReturned; +} UGA_IO_REQUEST, *PUGA_IO_REQUEST; + +/** + Dynamically allocate storage for a child UGA_DEVICE. + + @param[in] This The EFI_UGA_IO_PROTOCOL instance. + @param[in] ParentDevice ParentDevice specifies a pointer to the parent device of Device. + @param[in] DeviceData A pointer to UGA_DEVICE_DATA returned from a call to DispatchService() + with a UGA_DEVICE of Parent and an IoRequest of type UgaIoGetChildDevice. + @param[in] RunTimeContext Context to associate with Device. + @param[out] Device The Device returns a dynamically allocated child UGA_DEVICE object + for ParentDevice. The caller is responsible for deleting Device. + + + @retval EFI_SUCCESS Device was returned. + @retval EFI_INVALID_PARAMETER One of the arguments was not valid. + @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_UGA_IO_PROTOCOL_CREATE_DEVICE)( + IN EFI_UGA_IO_PROTOCOL *This, + IN UGA_DEVICE *ParentDevice, + IN UGA_DEVICE_DATA *DeviceData, + IN VOID *RunTimeContext, + OUT UGA_DEVICE **Device + ); + +/** + Delete a dynamically allocated child UGA_DEVICE object that was allocated via CreateDevice(). + + @param[in] This The EFI_UGA_IO_PROTOCOL instance. Type EFI_UGA_IO_PROTOCOL is + defined in Section 10.7. + @param[in] Device The Device points to a UGA_DEVICE object that was dynamically + allocated via a CreateDevice() call. + + + @retval EFI_SUCCESS Device was returned. + @retval EFI_INVALID_PARAMETER The Device was not allocated via CreateDevice(). + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_UGA_IO_PROTOCOL_DELETE_DEVICE)( + IN EFI_UGA_IO_PROTOCOL *This, + IN UGA_DEVICE *Device + ); + +/** + This is the main UGA service dispatch routine for all UGA_IO_REQUEST s. + + @param pDevice pDevice specifies a pointer to a device object associated with a + device enumerated by a pIoRequest->ioRequestCode of type + UgaIoGetChildDevice. The root device for the EFI_UGA_IO_PROTOCOL + is represented by pDevice being set to NULL. + + @param pIoRequest + pIoRequest points to a caller allocated buffer that contains data + defined by pIoRequest->ioRequestCode. See Related Definitions for + a definition of UGA_IO_REQUEST_CODE s and their associated data + structures. + + @return UGA_STATUS + +**/ +typedef UGA_STATUS +(EFIAPI *PUGA_FW_SERVICE_DISPATCH)( + IN PUGA_DEVICE pDevice, + IN OUT PUGA_IO_REQUEST pIoRequest + ); + +/// +/// Provides a basic abstraction to send I/O requests to the graphics device and any of its children. +/// +struct _EFI_UGA_IO_PROTOCOL { + EFI_UGA_IO_PROTOCOL_CREATE_DEVICE CreateDevice; + EFI_UGA_IO_PROTOCOL_DELETE_DEVICE DeleteDevice; + PUGA_FW_SERVICE_DISPATCH DispatchService; +}; + +extern EFI_GUID gEfiUgaIoProtocolGuid; + +// +// Data structure that is stored in the EFI Configuration Table with the +// EFI_UGA_IO_PROTOCOL_GUID. The option ROMs listed in this table may have +// EBC UGA drivers. +// +typedef struct { + UINT32 Version; + UINT32 HeaderSize; + UINT32 SizeOfEntries; + UINT32 NumberOfEntries; +} EFI_DRIVER_OS_HANDOFF_HEADER; + +typedef enum { + EfiUgaDriverFromPciRom, + EfiUgaDriverFromSystem, + EfiDriverHandoffMax +} EFI_DRIVER_HANOFF_ENUM; + +typedef struct { + EFI_DRIVER_HANOFF_ENUM Type; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + VOID *PciRomImage; + UINT64 PciRomSize; +} EFI_DRIVER_OS_HANDOFF; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/UnicodeCollation.h b/sys/contrib/edk2/Include/Protocol/UnicodeCollation.h new file mode 100644 index 000000000000..351452e4baa8 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/UnicodeCollation.h @@ -0,0 +1,186 @@ +/** @file + Unicode Collation protocol that follows the UEFI 2.0 specification. + This protocol is used to allow code running in the boot services environment + to perform lexical comparison functions on Unicode strings for given languages. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __UNICODE_COLLATION_H__ +#define __UNICODE_COLLATION_H__ + +#define EFI_UNICODE_COLLATION_PROTOCOL_GUID \ + { \ + 0x1d85cd7f, 0xf43d, 0x11d2, {0x9a, 0xc, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define EFI_UNICODE_COLLATION_PROTOCOL2_GUID \ + { \ + 0xa4c751fc, 0x23ae, 0x4c3e, {0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49 } \ + } + +typedef struct _EFI_UNICODE_COLLATION_PROTOCOL EFI_UNICODE_COLLATION_PROTOCOL; + +/// +/// Protocol GUID name defined in EFI1.1. +/// +#define UNICODE_COLLATION_PROTOCOL EFI_UNICODE_COLLATION_PROTOCOL_GUID + +/// +/// Protocol defined in EFI1.1. +/// +typedef EFI_UNICODE_COLLATION_PROTOCOL UNICODE_COLLATION_INTERFACE; + +/// +/// Protocol data structures and defines +/// +#define EFI_UNICODE_BYTE_ORDER_MARK (CHAR16) (0xfeff) + +// +// Protocol member functions +// + +/** + Performs a case-insensitive comparison of two Null-terminated strings. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param Str1 A pointer to a Null-terminated string. + @param Str2 A pointer to a Null-terminated string. + + @retval 0 Str1 is equivalent to Str2. + @retval >0 Str1 is lexically greater than Str2. + @retval <0 Str1 is lexically less than Str2. + +**/ +typedef +INTN +(EFIAPI *EFI_UNICODE_COLLATION_STRICOLL)( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ); + +/** + Performs a case-insensitive comparison of a Null-terminated + pattern string and a Null-terminated string. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + @param Pattern A pointer to a Null-terminated pattern string. + + @retval TRUE Pattern was found in String. + @retval FALSE Pattern was not found in String. + +**/ +typedef +BOOLEAN +(EFIAPI *EFI_UNICODE_COLLATION_METAIMATCH)( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +/** + Converts all the characters in a Null-terminated string to + lower case characters. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + +**/ +typedef +VOID +(EFIAPI *EFI_UNICODE_COLLATION_STRLWR)( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +/** + Converts all the characters in a Null-terminated string to upper + case characters. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + +**/ +typedef +VOID +(EFIAPI *EFI_UNICODE_COLLATION_STRUPR)( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +/** + Converts an 8.3 FAT file name in an OEM character set to a Null-terminated + string. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param FatSize The size of the string Fat in bytes. + @param Fat A pointer to a Null-terminated string that contains an 8.3 file + name using an 8-bit OEM character set. + @param String A pointer to a Null-terminated string. The string must + be allocated in advance to hold FatSize characters. + +**/ +typedef +VOID +(EFIAPI *EFI_UNICODE_COLLATION_FATTOSTR)( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ); + +/** + Converts a Null-terminated string to legal characters in a FAT + filename using an OEM character set. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + @param FatSize The size of the string Fat in bytes. + @param Fat A pointer to a string that contains the converted version of + String using legal FAT characters from an OEM character set. + + @retval TRUE One or more conversions failed and were substituted with '_' + @retval FALSE None of the conversions failed. + +**/ +typedef +BOOLEAN +(EFIAPI *EFI_UNICODE_COLLATION_STRTOFAT)( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ); + +/// +/// The EFI_UNICODE_COLLATION_PROTOCOL is used to perform case-insensitive +/// comparisons of strings. +/// +struct _EFI_UNICODE_COLLATION_PROTOCOL { + EFI_UNICODE_COLLATION_STRICOLL StriColl; + EFI_UNICODE_COLLATION_METAIMATCH MetaiMatch; + EFI_UNICODE_COLLATION_STRLWR StrLwr; + EFI_UNICODE_COLLATION_STRUPR StrUpr; + + // + // for supporting fat volumes + // + EFI_UNICODE_COLLATION_FATTOSTR FatToStr; + EFI_UNICODE_COLLATION_STRTOFAT StrToFat; + + /// + /// A Null-terminated ASCII string array that contains one or more language codes. + /// When this field is used for UnicodeCollation2, it is specified in RFC 4646 format. + /// When it is used for UnicodeCollation, it is specified in ISO 639-2 format. + /// + CHAR8 *SupportedLanguages; +}; + +extern EFI_GUID gEfiUnicodeCollationProtocolGuid; +extern EFI_GUID gEfiUnicodeCollation2ProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Usb2HostController.h b/sys/contrib/edk2/Include/Protocol/Usb2HostController.h new file mode 100644 index 000000000000..b5dc003ec5cb --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Usb2HostController.h @@ -0,0 +1,657 @@ +/** @file + EFI_USB2_HC_PROTOCOL as defined in UEFI 2.0. + The USB Host Controller Protocol is used by code, typically USB bus drivers, + running in the EFI boot services environment, to perform data transactions over + a USB bus. In addition, it provides an abstraction for the root hub of the USB bus. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _USB2_HOSTCONTROLLER_H_ +#define _USB2_HOSTCONTROLLER_H_ + +#include <Protocol/UsbIo.h> + +#define EFI_USB2_HC_PROTOCOL_GUID \ + { \ + 0x3e745226, 0x9818, 0x45b6, {0xa2, 0xac, 0xd7, 0xcd, 0xe, 0x8b, 0xa2, 0xbc } \ + } + +/// +/// Forward reference for pure ANSI compatability +/// +typedef struct _EFI_USB2_HC_PROTOCOL EFI_USB2_HC_PROTOCOL; + +typedef struct { + UINT16 PortStatus; ///< Contains current port status bitmap. + UINT16 PortChangeStatus; ///< Contains current port status change bitmap. +} EFI_USB_PORT_STATUS; + +/// +/// EFI_USB_PORT_STATUS.PortStatus bit definition +/// +#define USB_PORT_STAT_CONNECTION 0x0001 +#define USB_PORT_STAT_ENABLE 0x0002 +#define USB_PORT_STAT_SUSPEND 0x0004 +#define USB_PORT_STAT_OVERCURRENT 0x0008 +#define USB_PORT_STAT_RESET 0x0010 +#define USB_PORT_STAT_POWER 0x0100 +#define USB_PORT_STAT_LOW_SPEED 0x0200 +#define USB_PORT_STAT_HIGH_SPEED 0x0400 +#define USB_PORT_STAT_SUPER_SPEED 0x0800 +#define USB_PORT_STAT_OWNER 0x2000 + +/// +/// EFI_USB_PORT_STATUS.PortChangeStatus bit definition +/// +#define USB_PORT_STAT_C_CONNECTION 0x0001 +#define USB_PORT_STAT_C_ENABLE 0x0002 +#define USB_PORT_STAT_C_SUSPEND 0x0004 +#define USB_PORT_STAT_C_OVERCURRENT 0x0008 +#define USB_PORT_STAT_C_RESET 0x0010 + +/// +/// Usb port features value +/// Each value indicates its bit index in the port status and status change bitmaps, +/// if combines these two bitmaps into a 32-bit bitmap. +/// +typedef enum { + EfiUsbPortEnable = 1, + EfiUsbPortSuspend = 2, + EfiUsbPortReset = 4, + EfiUsbPortPower = 8, + EfiUsbPortOwner = 13, + EfiUsbPortConnectChange = 16, + EfiUsbPortEnableChange = 17, + EfiUsbPortSuspendChange = 18, + EfiUsbPortOverCurrentChange = 19, + EfiUsbPortResetChange = 20 +} EFI_USB_PORT_FEATURE; + +#define EFI_USB_SPEED_FULL 0x0000 ///< 12 Mb/s, USB 1.1 OHCI and UHCI HC. +#define EFI_USB_SPEED_LOW 0x0001 ///< 1 Mb/s, USB 1.1 OHCI and UHCI HC. +#define EFI_USB_SPEED_HIGH 0x0002 ///< 480 Mb/s, USB 2.0 EHCI HC. +#define EFI_USB_SPEED_SUPER 0x0003 ///< 4.8 Gb/s, USB 3.0 XHCI HC. + +typedef struct { + UINT8 TranslatorHubAddress; ///< device address + UINT8 TranslatorPortNumber; ///< the port number of the hub that device is connected to. +} EFI_USB2_HC_TRANSACTION_TRANSLATOR; + +// +// Protocol definitions +// + +/** + Retrieves the Host Controller capabilities. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param MaxSpeed Host controller data transfer speed. + @param PortNumber Number of the root hub ports. + @param Is64BitCapable TRUE if controller supports 64-bit memory addressing, + FALSE otherwise. + + @retval EFI_SUCCESS The host controller capabilities were retrieved successfully. + @retval EFI_INVALID_PARAMETER One of the input args was NULL. + @retval EFI_DEVICE_ERROR An error was encountered while attempting to + retrieve the capabilities. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_GET_CAPABILITY)( + IN EFI_USB2_HC_PROTOCOL *This, + OUT UINT8 *MaxSpeed, + OUT UINT8 *PortNumber, + OUT UINT8 *Is64BitCapable + ); + +#define EFI_USB_HC_RESET_GLOBAL 0x0001 +#define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 +#define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 +#define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 + +/** + Provides software reset for the USB host controller. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param Attributes A bit mask of the reset operation to perform. + + @retval EFI_SUCCESS The reset operation succeeded. + @retval EFI_INVALID_PARAMETER Attributes is not valid. + @retval EFI_UNSUPPORTED The type of reset specified by Attributes is not currently + supported by the host controller hardware. + @retval EFI_ACCESS_DENIED Reset operation is rejected due to the debug port being configured + and active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or + EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Attributes can be used to + perform reset operation for this host controller. + @retval EFI_DEVICE_ERROR An error was encountered while attempting to + retrieve the capabilities. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_RESET)( + IN EFI_USB2_HC_PROTOCOL *This, + IN UINT16 Attributes + ); + +/** + Enumration value for status of USB HC. +**/ +typedef enum { + EfiUsbHcStateHalt, ///< The host controller is in halt + ///< state. No USB transactions can occur + ///< while in this state. The host + ///< controller can enter this state for + ///< three reasons: 1) After host + ///< controller hardware reset. 2) + ///< Explicitly set by software. 3) + ///< Triggered by a fatal error such as + ///< consistency check failure. + + EfiUsbHcStateOperational, ///< The host controller is in an + ///< operational state. When in + ///< this state, the host + ///< controller can execute bus + ///< traffic. This state must be + ///< explicitly set to enable the + ///< USB bus traffic. + + EfiUsbHcStateSuspend, ///< The host controller is in the + ///< suspend state. No USB + ///< transactions can occur while in + ///< this state. The host controller + ///< enters this state for the + ///< following reasons: 1) Explicitly + ///< set by software. 2) Triggered + ///< when there is no bus traffic for + ///< 3 microseconds. + + EfiUsbHcStateMaximum ///< Maximum value for enumration value of HC status. +} EFI_USB_HC_STATE; + +/** + Retrieves current state of the USB host controller. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param State A pointer to the EFI_USB_HC_STATE data structure that + indicates current state of the USB host controller. + + @retval EFI_SUCCESS The state information of the host controller was returned in State. + @retval EFI_INVALID_PARAMETER State is NULL. + @retval EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the + host controller's current state. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_GET_STATE)( + IN EFI_USB2_HC_PROTOCOL *This, + OUT EFI_USB_HC_STATE *State + ); + +/** + Sets the USB host controller to a specific state. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param State Indicates the state of the host controller that will be set. + + @retval EFI_SUCCESS The USB host controller was successfully placed in the state + specified by State. + @retval EFI_INVALID_PARAMETER State is not valid. + @retval EFI_DEVICE_ERROR Failed to set the state specified by State due to device error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_SET_STATE)( + IN EFI_USB2_HC_PROTOCOL *This, + IN EFI_USB_HC_STATE State + ); + +/** + Submits control transfer to a target USB device. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Represents the address of the target device on the USB. + @param DeviceSpeed Indicates device speed. + @param MaximumPacketLength Indicates the maximum packet size that the default control transfer + endpoint is capable of sending or receiving. + @param Request A pointer to the USB device request that will be sent to the USB device. + @param TransferDirection Specifies the data direction for the transfer. There are three values + available, EfiUsbDataIn, EfiUsbDataOut and EfiUsbNoData. + @param Data A pointer to the buffer of data that will be transmitted to USB device or + received from USB device. + @param DataLength On input, indicates the size, in bytes, of the data buffer specified by Data. + On output, indicates the amount of data actually transferred. + @param TimeOut Indicates the maximum time, in milliseconds, which the transfer is + allowed to complete. + @param Translator A pointer to the transaction translator data. + @param TransferResult A pointer to the detailed result information generated by this control + transfer. + + @retval EFI_SUCCESS The control transfer was completed successfully. + @retval EFI_INVALID_PARAMETER Some parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The control transfer could not be completed due to a lack of resources. + @retval EFI_TIMEOUT The control transfer failed due to timeout. + @retval EFI_DEVICE_ERROR The control transfer failed due to host controller or device error. + Caller should check TransferResult for detailed error information. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_CONTROL_TRANSFER)( + IN EFI_USB2_HC_PROTOCOL *This, + IN UINT8 DeviceAddress, + IN UINT8 DeviceSpeed, + IN UINTN MaximumPacketLength, + IN EFI_USB_DEVICE_REQUEST *Request, + IN EFI_USB_DATA_DIRECTION TransferDirection, + IN OUT VOID *Data OPTIONAL, + IN OUT UINTN *DataLength OPTIONAL, + IN UINTN TimeOut, + IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, + OUT UINT32 *TransferResult + ); + +#define EFI_USB_MAX_BULK_BUFFER_NUM 10 + +/** + Submits bulk transfer to a bulk endpoint of a USB device. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Represents the address of the target device on the USB. + @param EndPointAddress The combination of an endpoint number and an endpoint direction of the + target USB device. + @param DeviceSpeed Indicates device speed. + @param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of + sending or receiving. + @param DataBuffersNumber Number of data buffers prepared for the transfer. + @param Data Array of pointers to the buffers of data that will be transmitted to USB + device or received from USB device. + @param DataLength When input, indicates the size, in bytes, of the data buffers specified by + Data. When output, indicates the actually transferred data size. + @param DataToggle A pointer to the data toggle value. + @param TimeOut Indicates the maximum time, in milliseconds, which the transfer is + allowed to complete. + @param Translator A pointer to the transaction translator data. + @param TransferResult A pointer to the detailed result information of the bulk transfer. + + @retval EFI_SUCCESS The bulk transfer was completed successfully. + @retval EFI_INVALID_PARAMETER Some parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The bulk transfer could not be submitted due to a lack of resources. + @retval EFI_TIMEOUT The bulk transfer failed due to timeout. + @retval EFI_DEVICE_ERROR The bulk transfer failed due to host controller or device error. + Caller should check TransferResult for detailed error information. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_BULK_TRANSFER)( + IN EFI_USB2_HC_PROTOCOL *This, + IN UINT8 DeviceAddress, + IN UINT8 EndPointAddress, + IN UINT8 DeviceSpeed, + IN UINTN MaximumPacketLength, + IN UINT8 DataBuffersNumber, + IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], + IN OUT UINTN *DataLength, + IN OUT UINT8 *DataToggle, + IN UINTN TimeOut, + IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, + OUT UINT32 *TransferResult + ); + +/** + Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device. + Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated in the following specification version. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Represents the address of the target device on the USB. + @param EndPointAddress The combination of an endpoint number and an endpoint direction of the + target USB device. + @param DeviceSpeed Indicates device speed. + @param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of + sending or receiving. + @param IsNewTransfer If TRUE, an asynchronous interrupt pipe is built between the host and the + target interrupt endpoint. If FALSE, the specified asynchronous interrupt + pipe is canceled. If TRUE, and an interrupt transfer exists for the target + end point, then EFI_INVALID_PARAMETER is returned. + @param DataToggle A pointer to the data toggle value. + @param PollingInterval Indicates the interval, in milliseconds, that the asynchronous interrupt + transfer is polled. + @param DataLength Indicates the length of data to be received at the rate specified by + PollingInterval from the target asynchronous interrupt endpoint. + @param Translator A pointr to the transaction translator data. + @param CallBackFunction The Callback function. This function is called at the rate specified by + PollingInterval. + @param Context The context that is passed to the CallBackFunction. This is an + optional parameter and may be NULL. + + @retval EFI_SUCCESS The asynchronous interrupt transfer request has been successfully + submitted or canceled. + @retval EFI_INVALID_PARAMETER Some parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER)( + IN EFI_USB2_HC_PROTOCOL *This, + IN UINT8 DeviceAddress, + IN UINT8 EndPointAddress, + IN UINT8 DeviceSpeed, + IN UINTN MaxiumPacketLength, + IN BOOLEAN IsNewTransfer, + IN OUT UINT8 *DataToggle, + IN UINTN PollingInterval OPTIONAL, + IN UINTN DataLength OPTIONAL, + IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator OPTIONAL, + IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction OPTIONAL, + IN VOID *Context OPTIONAL + ); + +/** + Submits synchronous interrupt transfer to an interrupt endpoint of a USB device. + Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated in the following specification version. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Represents the address of the target device on the USB. + @param EndPointAddress The combination of an endpoint number and an endpoint direction of the + target USB device. + @param DeviceSpeed Indicates device speed. + @param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of + sending or receiving. + @param Data A pointer to the buffer of data that will be transmitted to USB device or + received from USB device. + @param DataLength On input, the size, in bytes, of the data buffer specified by Data. On + output, the number of bytes transferred. + @param DataToggle A pointer to the data toggle value. + @param TimeOut Indicates the maximum time, in milliseconds, which the transfer is + allowed to complete. + @param Translator A pointr to the transaction translator data. + @param TransferResult A pointer to the detailed result information from the synchronous + interrupt transfer. + + @retval EFI_SUCCESS The synchronous interrupt transfer was completed successfully. + @retval EFI_INVALID_PARAMETER Some parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The synchronous interrupt transfer could not be submitted due to a lack of resources. + @retval EFI_TIMEOUT The synchronous interrupt transfer failed due to timeout. + @retval EFI_DEVICE_ERROR The synchronous interrupt transfer failed due to host controller or device error. + Caller should check TransferResult for detailed error information. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER)( + IN EFI_USB2_HC_PROTOCOL *This, + IN UINT8 DeviceAddress, + IN UINT8 EndPointAddress, + IN UINT8 DeviceSpeed, + IN UINTN MaximumPacketLength, + IN OUT VOID *Data, + IN OUT UINTN *DataLength, + IN OUT UINT8 *DataToggle, + IN UINTN TimeOut, + IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, + OUT UINT32 *TransferResult + ); + +#define EFI_USB_MAX_ISO_BUFFER_NUM 7 +#define EFI_USB_MAX_ISO_BUFFER_NUM1 2 + +/** + Submits isochronous transfer to an isochronous endpoint of a USB device. + + This function is used to submit isochronous transfer to a target endpoint of a USB device. + The target endpoint is specified by DeviceAddressand EndpointAddress. Isochronous transfers are + used when working with isochronous date. It provides periodic, continuous communication between + the host and a device. Isochronous transfers can beused only by full-speed, high-speed, and + super-speed devices. + + High-speed isochronous transfers can be performed using multiple data buffers. The number of + buffers that are actually prepared for the transfer is specified by DataBuffersNumber. For + full-speed isochronous transfers this value is ignored. + + Data represents a list of pointers to the data buffers. For full-speed isochronous transfers + only the data pointed by Data[0]shall be used. For high-speed isochronous transfers and for + the split transactions depending on DataLengththere several data buffers canbe used. For the + high-speed isochronous transfers the total number of buffers must not exceed EFI_USB_MAX_ISO_BUFFER_NUM. + + For split transactions performed on full-speed device by high-speed host controller the total + number of buffers is limited to EFI_USB_MAX_ISO_BUFFER_NUM1. + If the isochronous transfer is successful, then EFI_SUCCESSis returned. The isochronous transfer + is designed to be completed within one USB frame time, if it cannot be completed, EFI_TIMEOUT + is returned. If an error other than timeout occurs during the USB transfer, then EFI_DEVICE_ERROR + is returned and the detailed status code will be returned in TransferResult. + + EFI_INVALID_PARAMETERis returned if one of the following conditionsis satisfied: + - Data is NULL. + - DataLength is 0. + - DeviceSpeed is not one of the supported values listed above. + - MaximumPacketLength is invalid. MaximumPacketLength must be 1023 or less for full-speed devices, + and 1024 or less for high-speed and super-speed devices. + - TransferResult is NULL. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Represents the address of the target device on the USB. + @param EndPointAddress The combination of an endpoint number and an endpoint direction of the + target USB device. + @param DeviceSpeed Indicates device speed. The supported values are EFI_USB_SPEED_FULL, + EFI_USB_SPEED_HIGH, or EFI_USB_SPEED_SUPER. + @param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of + sending or receiving. + @param DataBuffersNumber Number of data buffers prepared for the transfer. + @param Data Array of pointers to the buffers of data that will be transmitted to USB + device or received from USB device. + @param DataLength Specifies the length, in bytes, of the data to be sent to or received from + the USB device. + @param Translator A pointer to the transaction translator data. + @param TransferResult A pointer to the detailed result information of the isochronous transfer. + + @retval EFI_SUCCESS The isochronous transfer was completed successfully. + @retval EFI_INVALID_PARAMETER Some parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The isochronous transfer could not be submitted due to a lack of resources. + @retval EFI_TIMEOUT The isochronous transfer cannot be completed within the one USB frame time. + @retval EFI_DEVICE_ERROR The isochronous transfer failed due to host controller or device error. + Caller should check TransferResult for detailed error information. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_ISOCHRONOUS_TRANSFER)( + IN EFI_USB2_HC_PROTOCOL *This, + IN UINT8 DeviceAddress, + IN UINT8 EndPointAddress, + IN UINT8 DeviceSpeed, + IN UINTN MaximumPacketLength, + IN UINT8 DataBuffersNumber, + IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], + IN UINTN DataLength, + IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, + OUT UINT32 *TransferResult + ); + +/** + Submits nonblocking isochronous transfer to an isochronous endpoint of a USB device. + + This is an asynchronous type of USB isochronous transfer. If the caller submits a USB + isochronous transfer request through this function, this function will return immediately. + + When the isochronous transfer completes, the IsochronousCallbackfunction will be triggered, + the caller can know the transfer results. If the transfer is successful, the caller can get + the data received or sent in this callback function. + + The target endpoint is specified by DeviceAddressand EndpointAddress. Isochronous transfers + are used when working with isochronous date. It provides periodic, continuous communication + between the host and a device. Isochronous transfers can be used only by full-speed, high-speed, + and super-speed devices. + + High-speed isochronous transfers can be performed using multiple data buffers. The number of + buffers that are actually prepared for the transfer is specified by DataBuffersNumber. For + full-speed isochronous transfers this value is ignored. + + Data represents a list of pointers to the data buffers. For full-speed isochronous transfers + only the data pointed by Data[0] shall be used. For high-speed isochronous transfers and for + the split transactions depending on DataLength there several data buffers can be used. For + the high-speed isochronous transfers the total number of buffers must not exceed EFI_USB_MAX_ISO_BUFFER_NUM. + + For split transactions performed on full-speed device by high-speed host controller the total + number of buffers is limited to EFI_USB_MAX_ISO_BUFFER_NUM1. + + EFI_INVALID_PARAMETER is returned if one of the following conditionsis satisfied: + - Data is NULL. + - DataLength is 0. + - DeviceSpeed is not one of the supported values listed above. + - MaximumPacketLength is invalid. MaximumPacketLength must be 1023 or less for full-speed + devices and 1024 or less for high-speed and super-speed devices. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param DeviceAddress Represents the address of the target device on the USB. + @param EndPointAddress The combination of an endpoint number and an endpoint direction of the + target USB device. + @param DeviceSpeed Indicates device speed. The supported values are EFI_USB_SPEED_FULL, + EFI_USB_SPEED_HIGH, or EFI_USB_SPEED_SUPER. + @param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of + sending or receiving. + @param DataBuffersNumber Number of data buffers prepared for the transfer. + @param Data Array of pointers to the buffers of data that will be transmitted to USB + device or received from USB device. + @param DataLength Specifies the length, in bytes, of the data to be sent to or received from + the USB device. + @param Translator A pointer to the transaction translator data. + @param IsochronousCallback The Callback function. This function is called if the requested + isochronous transfer is completed. + @param Context Data passed to the IsochronousCallback function. This is an + optional parameter and may be NULL. + + @retval EFI_SUCCESS The asynchronous isochronous transfer request has been successfully + submitted or canceled. + @retval EFI_INVALID_PARAMETER Some parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The asynchronous isochronous transfer could not be submitted due to + a lack of resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER)( + IN EFI_USB2_HC_PROTOCOL *This, + IN UINT8 DeviceAddress, + IN UINT8 EndPointAddress, + IN UINT8 DeviceSpeed, + IN UINTN MaximumPacketLength, + IN UINT8 DataBuffersNumber, + IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], + IN UINTN DataLength, + IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, + IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack, + IN VOID *Context OPTIONAL + ); + +/** + Retrieves the current status of a USB root hub port. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param PortNumber Specifies the root hub port from which the status is to be retrieved. + This value is zero based. + @param PortStatus A pointer to the current port status bits and port status change bits. + + @retval EFI_SUCCESS The status of the USB root hub port specified by PortNumber + was returned in PortStatus. + @retval EFI_INVALID_PARAMETER PortNumber is invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS)( + IN EFI_USB2_HC_PROTOCOL *This, + IN UINT8 PortNumber, + OUT EFI_USB_PORT_STATUS *PortStatus + ); + +/** + Sets a feature for the specified root hub port. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param PortNumber Specifies the root hub port whose feature is requested to be set. This + value is zero based. + @param PortFeature Indicates the feature selector associated with the feature set request. + + @retval EFI_SUCCESS The feature specified by PortFeature was set for the USB + root hub port specified by PortNumber. + @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE)( + IN EFI_USB2_HC_PROTOCOL *This, + IN UINT8 PortNumber, + IN EFI_USB_PORT_FEATURE PortFeature + ); + +/** + Clears a feature for the specified root hub port. + + @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. + @param PortNumber Specifies the root hub port whose feature is requested to be cleared. This + value is zero based. + @param PortFeature Indicates the feature selector associated with the feature clear request. + + @retval EFI_SUCCESS The feature specified by PortFeature was cleared for the USB + root hub port specified by PortNumber. + @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB2_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE)( + IN EFI_USB2_HC_PROTOCOL *This, + IN UINT8 PortNumber, + IN EFI_USB_PORT_FEATURE PortFeature + ); + +/// +/// The EFI_USB2_HC_PROTOCOL provides USB host controller management, basic +/// data transactions over a USB bus, and USB root hub access. A device driver +/// that wishes to manage a USB bus in a system retrieves the EFI_USB2_HC_PROTOCOL +/// instance that is associated with the USB bus to be managed. A device handle +/// for a USB host controller will minimally contain an EFI_DEVICE_PATH_PROTOCOL +/// instance, and an EFI_USB2_HC_PROTOCOL instance. +/// +struct _EFI_USB2_HC_PROTOCOL { + EFI_USB2_HC_PROTOCOL_GET_CAPABILITY GetCapability; + EFI_USB2_HC_PROTOCOL_RESET Reset; + EFI_USB2_HC_PROTOCOL_GET_STATE GetState; + EFI_USB2_HC_PROTOCOL_SET_STATE SetState; + EFI_USB2_HC_PROTOCOL_CONTROL_TRANSFER ControlTransfer; + EFI_USB2_HC_PROTOCOL_BULK_TRANSFER BulkTransfer; + EFI_USB2_HC_PROTOCOL_ASYNC_INTERRUPT_TRANSFER AsyncInterruptTransfer; + EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER SyncInterruptTransfer; + EFI_USB2_HC_PROTOCOL_ISOCHRONOUS_TRANSFER IsochronousTransfer; + EFI_USB2_HC_PROTOCOL_ASYNC_ISOCHRONOUS_TRANSFER AsyncIsochronousTransfer; + EFI_USB2_HC_PROTOCOL_GET_ROOTHUB_PORT_STATUS GetRootHubPortStatus; + EFI_USB2_HC_PROTOCOL_SET_ROOTHUB_PORT_FEATURE SetRootHubPortFeature; + EFI_USB2_HC_PROTOCOL_CLEAR_ROOTHUB_PORT_FEATURE ClearRootHubPortFeature; + + /// + /// The major revision number of the USB host controller. The revision information + /// indicates the release of the Universal Serial Bus Specification with which the + /// host controller is compliant. + /// + UINT16 MajorRevision; + + /// + /// The minor revision number of the USB host controller. The revision information + /// indicates the release of the Universal Serial Bus Specification with which the + /// host controller is compliant. + /// + UINT16 MinorRevision; +}; + +extern EFI_GUID gEfiUsb2HcProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/UsbIo.h b/sys/contrib/edk2/Include/Protocol/UsbIo.h new file mode 100644 index 000000000000..489db0231f8e --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/UsbIo.h @@ -0,0 +1,505 @@ +/** @file + EFI Usb I/O Protocol as defined in UEFI specification. + This protocol is used by code, typically drivers, running in the EFI + boot services environment to access USB devices like USB keyboards, + mice and mass storage devices. In particular, functions for managing devices + on USB buses are defined here. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __USB_IO_H__ +#define __USB_IO_H__ + +#include <IndustryStandard/Usb.h> + +// +// Global ID for the USB I/O Protocol +// +#define EFI_USB_IO_PROTOCOL_GUID \ + { \ + 0x2B2F68D6, 0x0CD2, 0x44cf, {0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \ + } + +typedef struct _EFI_USB_IO_PROTOCOL EFI_USB_IO_PROTOCOL; + +// +// Related Definition for EFI USB I/O protocol +// + +// +// USB standard descriptors and reqeust +// +typedef USB_DEVICE_REQUEST EFI_USB_DEVICE_REQUEST; +typedef USB_DEVICE_DESCRIPTOR EFI_USB_DEVICE_DESCRIPTOR; +typedef USB_CONFIG_DESCRIPTOR EFI_USB_CONFIG_DESCRIPTOR; +typedef USB_INTERFACE_DESCRIPTOR EFI_USB_INTERFACE_DESCRIPTOR; +typedef USB_ENDPOINT_DESCRIPTOR EFI_USB_ENDPOINT_DESCRIPTOR; + +/// +/// USB data transfer direction +/// +typedef enum { + EfiUsbDataIn, + EfiUsbDataOut, + EfiUsbNoData +} EFI_USB_DATA_DIRECTION; + +// +// USB Transfer Results +// +#define EFI_USB_NOERROR 0x00 +#define EFI_USB_ERR_NOTEXECUTE 0x01 +#define EFI_USB_ERR_STALL 0x02 +#define EFI_USB_ERR_BUFFER 0x04 +#define EFI_USB_ERR_BABBLE 0x08 +#define EFI_USB_ERR_NAK 0x10 +#define EFI_USB_ERR_CRC 0x20 +#define EFI_USB_ERR_TIMEOUT 0x40 +#define EFI_USB_ERR_BITSTUFF 0x80 +#define EFI_USB_ERR_SYSTEM 0x100 + +/** + Async USB transfer callback routine. + + @param Data Data received or sent via the USB Asynchronous Transfer, if the + transfer completed successfully. + @param DataLength The length of Data received or sent via the Asynchronous + Transfer, if transfer successfully completes. + @param Context Data passed from UsbAsyncInterruptTransfer() request. + @param Status Indicates the result of the asynchronous transfer. + + @retval EFI_SUCCESS The asynchronous USB transfer request has been successfully executed. + @retval EFI_DEVICE_ERROR The asynchronous USB transfer request failed. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_ASYNC_USB_TRANSFER_CALLBACK)( + IN VOID *Data, + IN UINTN DataLength, + IN VOID *Context, + IN UINT32 Status + ); + +// +// Prototype for EFI USB I/O protocol +// + +/** + This function is used to manage a USB device with a control transfer pipe. A control transfer is + typically used to perform device initialization and configuration. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param Request A pointer to the USB device request that will be sent to the USB + device. + @param Direction Indicates the data direction. + @param Timeout Indicating the transfer should be completed within this time frame. + The units are in milliseconds. + @param Data A pointer to the buffer of data that will be transmitted to USB + device or received from USB device. + @param DataLength The size, in bytes, of the data buffer specified by Data. + @param Status A pointer to the result of the USB transfer. + + @retval EFI_SUCCESS The control transfer has been successfully executed. + @retval EFI_DEVICE_ERROR The transfer failed. The transfer status is returned in Status. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_TIMEOUT The control transfer fails due to timeout. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_CONTROL_TRANSFER)( + IN EFI_USB_IO_PROTOCOL *This, + IN EFI_USB_DEVICE_REQUEST *Request, + IN EFI_USB_DATA_DIRECTION Direction, + IN UINT32 Timeout, + IN OUT VOID *Data OPTIONAL, + IN UINTN DataLength OPTIONAL, + OUT UINT32 *Status + ); + +/** + This function is used to manage a USB device with the bulk transfer pipe. Bulk Transfers are + typically used to transfer large amounts of data to/from USB devices. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param DeviceEndpoint The destination USB device endpoint to which the + device request is being sent. DeviceEndpoint must + be between 0x01 and 0x0F or between 0x81 and 0x8F, + otherwise EFI_INVALID_PARAMETER is returned. If + the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER + is returned. The MSB of this parameter indicates + the endpoint direction. The number "1" stands for + an IN endpoint, and "0" stands for an OUT endpoint. + @param Data A pointer to the buffer of data that will be transmitted to USB + device or received from USB device. + @param DataLength The size, in bytes, of the data buffer specified by Data. + On input, the size, in bytes, of the data buffer specified by Data. + On output, the number of bytes that were actually transferred. + @param Timeout Indicating the transfer should be completed within this time frame. + The units are in milliseconds. If Timeout is 0, then the + caller must wait for the function to be completed until + EFI_SUCCESS or EFI_DEVICE_ERROR is returned. + @param Status This parameter indicates the USB transfer status. + + @retval EFI_SUCCESS The bulk transfer has been successfully executed. + @retval EFI_DEVICE_ERROR The transfer failed. The transfer status is returned in Status. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be submitted due to a lack of resources. + @retval EFI_TIMEOUT The control transfer fails due to timeout. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_BULK_TRANSFER)( + IN EFI_USB_IO_PROTOCOL *This, + IN UINT8 DeviceEndpoint, + IN OUT VOID *Data, + IN OUT UINTN *DataLength, + IN UINTN Timeout, + OUT UINT32 *Status + ); + +/** + This function is used to manage a USB device with an interrupt transfer pipe. An Asynchronous + Interrupt Transfer is typically used to query a device's status at a fixed rate. For example, + keyboard, mouse, and hub devices use this type of transfer to query their interrupt endpoints at + a fixed rate. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param DeviceEndpoint The destination USB device endpoint to which the + device request is being sent. DeviceEndpoint must + be between 0x01 and 0x0F or between 0x81 and 0x8F, + otherwise EFI_INVALID_PARAMETER is returned. If + the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER + is returned. The MSB of this parameter indicates + the endpoint direction. The number "1" stands for + an IN endpoint, and "0" stands for an OUT endpoint. + @param IsNewTransfer If TRUE, a new transfer will be submitted to USB controller. If + FALSE, the interrupt transfer is deleted from the device's interrupt + transfer queue. + @param PollingInterval Indicates the periodic rate, in milliseconds, that the transfer is to be + executed.This parameter is required when IsNewTransfer is TRUE. The + value must be between 1 to 255, otherwise EFI_INVALID_PARAMETER is returned. + The units are in milliseconds. + @param DataLength Specifies the length, in bytes, of the data to be received from the + USB device. This parameter is only required when IsNewTransfer is TRUE. + @param InterruptCallback The Callback function. This function is called if the asynchronous + interrupt transfer is completed. This parameter is required + when IsNewTransfer is TRUE. + @param Context Data passed to the InterruptCallback function. This is an optional + parameter and may be NULL. + + @retval EFI_SUCCESS The asynchronous USB transfer request transfer has been successfully executed. + @retval EFI_DEVICE_ERROR The asynchronous USB transfer request failed. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER)( + IN EFI_USB_IO_PROTOCOL *This, + IN UINT8 DeviceEndpoint, + IN BOOLEAN IsNewTransfer, + IN UINTN PollingInterval OPTIONAL, + IN UINTN DataLength OPTIONAL, + IN EFI_ASYNC_USB_TRANSFER_CALLBACK InterruptCallBack OPTIONAL, + IN VOID *Context OPTIONAL + ); + +/** + This function is used to manage a USB device with an interrupt transfer pipe. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param DeviceEndpoint The destination USB device endpoint to which the + device request is being sent. DeviceEndpoint must + be between 0x01 and 0x0F or between 0x81 and 0x8F, + otherwise EFI_INVALID_PARAMETER is returned. If + the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER + is returned. The MSB of this parameter indicates + the endpoint direction. The number "1" stands for + an IN endpoint, and "0" stands for an OUT endpoint. + @param Data A pointer to the buffer of data that will be transmitted to USB + device or received from USB device. + @param DataLength On input, then size, in bytes, of the buffer Data. On output, the + amount of data actually transferred. + @param Timeout The time out, in seconds, for this transfer. If Timeout is 0, + then the caller must wait for the function to be completed + until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. If the + transfer is not completed in this time frame, then EFI_TIMEOUT is returned. + @param Status This parameter indicates the USB transfer status. + + @retval EFI_SUCCESS The sync interrupt transfer has been successfully executed. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_DEVICE_ERROR The sync interrupt transfer request failed. + @retval EFI_OUT_OF_RESOURCES The request could not be submitted due to a lack of resources. + @retval EFI_TIMEOUT The transfer fails due to timeout. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_SYNC_INTERRUPT_TRANSFER)( + IN EFI_USB_IO_PROTOCOL *This, + IN UINT8 DeviceEndpoint, + IN OUT VOID *Data, + IN OUT UINTN *DataLength, + IN UINTN Timeout, + OUT UINT32 *Status + ); + +/** + This function is used to manage a USB device with an isochronous transfer pipe. An Isochronous + transfer is typically used to transfer streaming data. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param DeviceEndpoint The destination USB device endpoint to which the + device request is being sent. DeviceEndpoint must + be between 0x01 and 0x0F or between 0x81 and 0x8F, + otherwise EFI_INVALID_PARAMETER is returned. If + the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER + is returned. The MSB of this parameter indicates + the endpoint direction. The number "1" stands for + an IN endpoint, and "0" stands for an OUT endpoint. + @param Data A pointer to the buffer of data that will be transmitted to USB + device or received from USB device. + @param DataLength The size, in bytes, of the data buffer specified by Data. + @param Status This parameter indicates the USB transfer status. + + @retval EFI_SUCCESS The isochronous transfer has been successfully executed. + @retval EFI_INVALID_PARAMETER The parameter DeviceEndpoint is not valid. + @retval EFI_DEVICE_ERROR The transfer failed due to the reason other than timeout, The error status + is returned in Status. + @retval EFI_OUT_OF_RESOURCES The request could not be submitted due to a lack of resources. + @retval EFI_TIMEOUT The transfer fails due to timeout. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_ISOCHRONOUS_TRANSFER)( + IN EFI_USB_IO_PROTOCOL *This, + IN UINT8 DeviceEndpoint, + IN OUT VOID *Data, + IN UINTN DataLength, + OUT UINT32 *Status + ); + +/** + This function is used to manage a USB device with an isochronous transfer pipe. An Isochronous + transfer is typically used to transfer streaming data. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param DeviceEndpoint The destination USB device endpoint to which the + device request is being sent. DeviceEndpoint must + be between 0x01 and 0x0F or between 0x81 and 0x8F, + otherwise EFI_INVALID_PARAMETER is returned. If + the endpoint is not a BULK endpoint, EFI_INVALID_PARAMETER + is returned. The MSB of this parameter indicates + the endpoint direction. The number "1" stands for + an IN endpoint, and "0" stands for an OUT endpoint. + @param Data A pointer to the buffer of data that will be transmitted to USB + device or received from USB device. + @param DataLength The size, in bytes, of the data buffer specified by Data. + This is an optional parameter and may be NULL. + @param IsochronousCallback The IsochronousCallback() function.This function is + called if the requested isochronous transfer is completed. + @param Context Data passed to the IsochronousCallback() function. + + @retval EFI_SUCCESS The asynchronous isochronous transfer has been successfully submitted + to the system. + @retval EFI_INVALID_PARAMETER The parameter DeviceEndpoint is not valid. + @retval EFI_OUT_OF_RESOURCES The request could not be submitted due to a lack of resources. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_ASYNC_ISOCHRONOUS_TRANSFER)( + IN EFI_USB_IO_PROTOCOL *This, + IN UINT8 DeviceEndpoint, + IN OUT VOID *Data, + IN UINTN DataLength, + IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack, + IN VOID *Context OPTIONAL + ); + +/** + Resets and reconfigures the USB controller. This function will work for all USB devices except + USB Hub Controllers. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + + @retval EFI_SUCCESS The USB controller was reset. + @retval EFI_INVALID_PARAMETER If the controller specified by This is a USB hub. + @retval EFI_DEVICE_ERROR An error occurred during the reconfiguration process. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_PORT_RESET)( + IN EFI_USB_IO_PROTOCOL *This + ); + +/** + Retrieves the USB Device Descriptor. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param DeviceDescriptor A pointer to the caller allocated USB Device Descriptor. + + @retval EFI_SUCCESS The device descriptor was retrieved successfully. + @retval EFI_INVALID_PARAMETER DeviceDescriptor is NULL. + @retval EFI_NOT_FOUND The device descriptor was not found. The device may not be configured. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_GET_DEVICE_DESCRIPTOR)( + IN EFI_USB_IO_PROTOCOL *This, + OUT EFI_USB_DEVICE_DESCRIPTOR *DeviceDescriptor + ); + +/** + Retrieves the USB Device Descriptor. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param ConfigurationDescriptor A pointer to the caller allocated USB Active Configuration + Descriptor. + @retval EFI_SUCCESS The active configuration descriptor was retrieved successfully. + @retval EFI_INVALID_PARAMETER ConfigurationDescriptor is NULL. + @retval EFI_NOT_FOUND An active configuration descriptor cannot be found. The device may not + be configured. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_GET_CONFIG_DESCRIPTOR)( + IN EFI_USB_IO_PROTOCOL *This, + OUT EFI_USB_CONFIG_DESCRIPTOR *ConfigurationDescriptor + ); + +/** + Retrieves the Interface Descriptor for a USB Device Controller. As stated earlier, an interface + within a USB device is equivalently to a USB Controller within the current configuration. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param InterfaceDescriptor A pointer to the caller allocated USB Interface Descriptor within + the configuration setting. + @retval EFI_SUCCESS The interface descriptor retrieved successfully. + @retval EFI_INVALID_PARAMETER InterfaceDescriptor is NULL. + @retval EFI_NOT_FOUND The interface descriptor cannot be found. The device may not be + correctly configured. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_GET_INTERFACE_DESCRIPTOR)( + IN EFI_USB_IO_PROTOCOL *This, + OUT EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDescriptor + ); + +/** + Retrieves an Endpoint Descriptor within a USB Controller. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param EndpointIndex Indicates which endpoint descriptor to retrieve. + @param EndpointDescriptor A pointer to the caller allocated USB Endpoint Descriptor of + a USB controller. + + @retval EFI_SUCCESS The endpoint descriptor was retrieved successfully. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_NOT_FOUND The endpoint descriptor cannot be found. The device may not be + correctly configured. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_GET_ENDPOINT_DESCRIPTOR)( + IN EFI_USB_IO_PROTOCOL *This, + IN UINT8 EndpointIndex, + OUT EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor + ); + +/** + Retrieves a string stored in a USB Device. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param LangID The Language ID for the string being retrieved. + @param StringID The ID of the string being retrieved. + @param String A pointer to a buffer allocated by this function with + AllocatePool() to store the string.If this function + returns EFI_SUCCESS, it stores the string the caller + wants to get. The caller should release the string + buffer with FreePool() after the string is not used any more. + + @retval EFI_SUCCESS The string was retrieved successfully. + @retval EFI_NOT_FOUND The string specified by LangID and StringID was not found. + @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the return buffer String. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_GET_STRING_DESCRIPTOR)( + IN EFI_USB_IO_PROTOCOL *This, + IN UINT16 LangID, + IN UINT8 StringID, + OUT CHAR16 **String + ); + +/** + Retrieves all the language ID codes that the USB device supports. + + @param This A pointer to the EFI_USB_IO_PROTOCOL instance. + @param LangIDTable Language ID for the string the caller wants to get. + This is a 16-bit ID defined by Microsoft. This + buffer pointer is allocated and maintained by + the USB Bus Driver, the caller should not modify + its contents. + @param TableSize The size, in bytes, of the table LangIDTable. + + @retval EFI_SUCCESS The support languages were retrieved successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_USB_IO_GET_SUPPORTED_LANGUAGE)( + IN EFI_USB_IO_PROTOCOL *This, + OUT UINT16 **LangIDTable, + OUT UINT16 *TableSize + ); + +/// +/// The EFI_USB_IO_PROTOCOL provides four basic transfers types described +/// in the USB 1.1 Specification. These include control transfer, interrupt +/// transfer, bulk transfer and isochronous transfer. The EFI_USB_IO_PROTOCOL +/// also provides some basic USB device/controller management and configuration +/// interfaces. A USB device driver uses the services of this protocol to manage USB devices. +/// +struct _EFI_USB_IO_PROTOCOL { + // + // IO transfer + // + EFI_USB_IO_CONTROL_TRANSFER UsbControlTransfer; + EFI_USB_IO_BULK_TRANSFER UsbBulkTransfer; + EFI_USB_IO_ASYNC_INTERRUPT_TRANSFER UsbAsyncInterruptTransfer; + EFI_USB_IO_SYNC_INTERRUPT_TRANSFER UsbSyncInterruptTransfer; + EFI_USB_IO_ISOCHRONOUS_TRANSFER UsbIsochronousTransfer; + EFI_USB_IO_ASYNC_ISOCHRONOUS_TRANSFER UsbAsyncIsochronousTransfer; + + // + // Common device request + // + EFI_USB_IO_GET_DEVICE_DESCRIPTOR UsbGetDeviceDescriptor; + EFI_USB_IO_GET_CONFIG_DESCRIPTOR UsbGetConfigDescriptor; + EFI_USB_IO_GET_INTERFACE_DESCRIPTOR UsbGetInterfaceDescriptor; + EFI_USB_IO_GET_ENDPOINT_DESCRIPTOR UsbGetEndpointDescriptor; + EFI_USB_IO_GET_STRING_DESCRIPTOR UsbGetStringDescriptor; + EFI_USB_IO_GET_SUPPORTED_LANGUAGE UsbGetSupportedLanguages; + + // + // Reset controller's parent port + // + EFI_USB_IO_PORT_RESET UsbPortReset; +}; + +extern EFI_GUID gEfiUsbIoProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/Variable.h b/sys/contrib/edk2/Include/Protocol/Variable.h new file mode 100644 index 000000000000..91f56c33faf6 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/Variable.h @@ -0,0 +1,39 @@ +/** @file + Variable Architectural Protocol as defined in PI Specification VOLUME 2 DXE + + This provides the services required to get and set environment variables. This + protocol must be produced by a runtime DXE driver and may be consumed only by + the DXE Foundation. The DXE driver that produces this protocol must be a runtime + driver. This driver is responsible for initializing the GetVariable(), + GetNextVariableName(), and SetVariable() fields of the UEFI Runtime Services Table. + + After the three fields of the UEFI Runtime Services Table have been initialized, + the driver must install the EFI_VARIABLE_ARCH_PROTOCOL_GUID on a new handle with + a NULL interface pointer. The installation of this protocol informs the DXE Foundation + that the read-only and the volatile environment variable related services are + now available and that the DXE Foundation must update the 32-bit CRC of the UEFI + Runtime Services Table. The full complement of environment variable services are + not available until both this protocol and EFI_VARIABLE_WRITE_ARCH_PROTOCOL are + installed. DXE drivers that require read-only access or read/write access to volatile + environment variables must have this architectural protocol in their dependency + expressions. DXE drivers that require write access to nonvolatile environment + variables must have the EFI_VARIABLE_WRITE_ARCH_PROTOCOL in their dependency + expressions. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_VARIABLE_ARCH_H__ +#define __ARCH_PROTOCOL_VARIABLE_ARCH_H__ + +/// +/// Global ID for the Variable Architectural Protocol +/// +#define EFI_VARIABLE_ARCH_PROTOCOL_GUID \ + { 0x1e5668e2, 0x8481, 0x11d4, {0xbc, 0xf1, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +extern EFI_GUID gEfiVariableArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/VariableWrite.h b/sys/contrib/edk2/Include/Protocol/VariableWrite.h new file mode 100644 index 000000000000..1faa885d73f2 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/VariableWrite.h @@ -0,0 +1,39 @@ +/** @file + Variable Write Architectural Protocol as defined in PI Specification VOLUME 2 DXE + + This provides the services required to set nonvolatile environment variables. + This protocol must be produced by a runtime DXE driver and may be consumed only + by the DXE Foundation. + + The DXE driver that produces this protocol must be a runtime driver. This driver + may update the SetVariable() field of the UEFI Runtime Services Table. + + After the UEFI Runtime Services Table has been initialized, the driver must + install the EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID on a new handle with a NULL + interface pointer. The installation of this protocol informs the DXE Foundation + that the write services for nonvolatile environment variables are now available + and that the DXE Foundation must update the 32-bit CRC of the UEFI Runtime Services + Table. The full complement of environment variable services are not available + until both this protocol and EFI_VARIABLE_ARCH_PROTOCOL are installed. DXE drivers + that require read-only access or read/write access to volatile environment variables + must have the EFI_VARIABLE_WRITE_ARCH_PROTOCOL in their dependency expressions. + DXE drivers that require write access to nonvolatile environment variables must + have this architectural protocol in their dependency expressions. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __ARCH_PROTOCOL_VARIABLE_WRITE_ARCH_H__ +#define __ARCH_PROTOCOL_VARIABLE_WRITE_ARCH_H__ + +/// +/// Global ID for the Variable Write Architectural Protocol +/// +#define EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID \ + { 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53 } } + +extern EFI_GUID gEfiVariableWriteArchProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/VlanConfig.h b/sys/contrib/edk2/Include/Protocol/VlanConfig.h new file mode 100644 index 000000000000..64d04d778443 --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/VlanConfig.h @@ -0,0 +1,134 @@ +/** @file + EFI VLAN Config protocol is to provide manageability interface for VLAN configuration. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.2 + +**/ + +#ifndef __EFI_VLANCONFIG_PROTOCOL_H__ +#define __EFI_VLANCONFIG_PROTOCOL_H__ + +#define EFI_VLAN_CONFIG_PROTOCOL_GUID \ + { \ + 0x9e23d768, 0xd2f3, 0x4366, {0x9f, 0xc3, 0x3a, 0x7a, 0xba, 0x86, 0x43, 0x74 } \ + } + +typedef struct _EFI_VLAN_CONFIG_PROTOCOL EFI_VLAN_CONFIG_PROTOCOL; + +/// +/// EFI_VLAN_FIND_DATA +/// +typedef struct { + UINT16 VlanId; ///< Vlan Identifier. + UINT8 Priority; ///< Priority of this VLAN. +} EFI_VLAN_FIND_DATA; + +/** + Create a VLAN device or modify the configuration parameter of an + already-configured VLAN. + + The Set() function is used to create a new VLAN device or change the VLAN + configuration parameters. If the VlanId hasn't been configured in the + physical Ethernet device, a new VLAN device will be created. If a VLAN with + this VlanId is already configured, then related configuration will be updated + as the input parameters. + + If VlanId is zero, the VLAN device will send and receive untagged frames. + Otherwise, the VLAN device will send and receive VLAN-tagged frames containing the VlanId. + If VlanId is out of scope of (0-4094), EFI_INVALID_PARAMETER is returned. + If Priority is out of the scope of (0-7), then EFI_INVALID_PARAMETER is returned. + If there is not enough system memory to perform the registration, then + EFI_OUT_OF_RESOURCES is returned. + + @param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL. + @param[in] VlanId A unique identifier (1-4094) of the VLAN which is being created + or modified, or zero (0). + @param[in] Priority 3 bit priority in VLAN header. Priority 0 is default value. If + VlanId is zero (0), Priority is ignored. + + @retval EFI_SUCCESS The VLAN is successfully configured. + @retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE: + - This is NULL. + - VlanId is an invalid VLAN Identifier. + - Priority is invalid. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to perform the registration. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_VLAN_CONFIG_SET)( + IN EFI_VLAN_CONFIG_PROTOCOL *This, + IN UINT16 VlanId, + IN UINT8 Priority + ); + +/** + Find configuration information for specified VLAN or all configured VLANs. + + The Find() function is used to find the configuration information for matching + VLAN and allocate a buffer into which those entries are copied. + + @param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL. + @param[in] VlanId Pointer to VLAN identifier. Set to NULL to find all + configured VLANs. + @param[out] NumberOfVlan The number of VLANs which is found by the specified criteria. + @param[out] Entries The buffer which receive the VLAN configuration. + + @retval EFI_SUCCESS The VLAN is successfully found. + @retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE: + - This is NULL. + - Specified VlanId is invalid. + @retval EFI_NOT_FOUND No matching VLAN is found. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_VLAN_CONFIG_FIND)( + IN EFI_VLAN_CONFIG_PROTOCOL *This, + IN UINT16 *VlanId OPTIONAL, + OUT UINT16 *NumberOfVlan, + OUT EFI_VLAN_FIND_DATA **Entries + ); + +/** + Remove the configured VLAN device. + + The Remove() function is used to remove the specified VLAN device. + If the VlanId is out of the scope of (0-4094), EFI_INVALID_PARAMETER is returned. + If specified VLAN hasn't been previously configured, EFI_NOT_FOUND is returned. + + @param[in] This Points to the EFI_VLAN_CONFIG_PROTOCOL. + @param[in] VlanId Identifier (0-4094) of the VLAN to be removed. + + @retval EFI_SUCCESS The VLAN is successfully removed. + @retval EFI_INVALID_PARAMETER One or more of following conditions is TRUE: + - This is NULL. + - VlanId is an invalid parameter. + @retval EFI_NOT_FOUND The to-be-removed VLAN does not exist. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_VLAN_CONFIG_REMOVE)( + IN EFI_VLAN_CONFIG_PROTOCOL *This, + IN UINT16 VlanId + ); + +/// +/// EFI_VLAN_CONFIG_PROTOCOL +/// provide manageability interface for VLAN setting. The intended +/// VLAN tagging implementation is IEEE802.1Q. +/// +struct _EFI_VLAN_CONFIG_PROTOCOL { + EFI_VLAN_CONFIG_SET Set; + EFI_VLAN_CONFIG_FIND Find; + EFI_VLAN_CONFIG_REMOVE Remove; +}; + +extern EFI_GUID gEfiVlanConfigProtocolGuid; + +#endif diff --git a/sys/contrib/edk2/Include/Protocol/WatchdogTimer.h b/sys/contrib/edk2/Include/Protocol/WatchdogTimer.h new file mode 100644 index 000000000000..b2253217113b --- /dev/null +++ b/sys/contrib/edk2/Include/Protocol/WatchdogTimer.h @@ -0,0 +1,136 @@ +/** @file + Watchdog Timer Architectural Protocol as defined in PI Specification VOLUME 2 DXE + + Used to provide system watchdog timer services + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __ARCH_PROTOCOL_WATCHDOG_TIMER_H__ +#define __ARCH_PROTOCOL_WATCHDOG_TIMER_H__ + +/// +/// Global ID for the Watchdog Timer Architectural Protocol +/// +#define EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID \ + { 0x665E3FF5, 0x46CC, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } } + +/// +/// Declare forward reference for the Timer Architectural Protocol +/// +typedef struct _EFI_WATCHDOG_TIMER_ARCH_PROTOCOL EFI_WATCHDOG_TIMER_ARCH_PROTOCOL; + +/** + A function of this type is called when the watchdog timer fires if a + handler has been registered. + + @param Time The time in 100 ns units that has passed since the watchdog + timer was armed. For the notify function to be called, this + must be greater than TimerPeriod. + + @return None. + +**/ +typedef +VOID +(EFIAPI *EFI_WATCHDOG_TIMER_NOTIFY)( + IN UINT64 Time + ); + +/** + This function registers a handler that is to be invoked when the watchdog + timer fires. By default, the EFI_WATCHDOG_TIMER protocol will call the + Runtime Service ResetSystem() when the watchdog timer fires. If a + NotifyFunction is registered, then the NotifyFunction will be called before + the Runtime Service ResetSystem() is called. If NotifyFunction is NULL, then + the watchdog handler is unregistered. If a watchdog handler is registered, + then EFI_SUCCESS is returned. If an attempt is made to register a handler + when a handler is already registered, then EFI_ALREADY_STARTED is returned. + If an attempt is made to uninstall a handler when a handler is not installed, + then return EFI_INVALID_PARAMETER. + + @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance. + @param NotifyFunction The function to call when the watchdog timer fires. If this + is NULL, then the handler will be unregistered. + + @retval EFI_SUCCESS The watchdog timer handler was registered or + unregistered. + @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already + registered. + @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not + previously registered. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_WATCHDOG_TIMER_REGISTER_HANDLER)( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction + ); + +/** + This function sets the amount of time to wait before firing the watchdog + timer to TimerPeriod 100 nS units. If TimerPeriod is 0, then the watchdog + timer is disabled. + + @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod The amount of time in 100 nS units to wait before the watchdog + timer is fired. If TimerPeriod is zero, then the watchdog + timer is disabled. + + @retval EFI_SUCCESS The watchdog timer has been programmed to fire in Time + 100 nS units. + @retval EFI_DEVICE_ERROR A watchdog timer could not be programmed due to a device + error. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD)( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ); + +/** + This function retrieves the amount of time the system will wait before firing + the watchdog timer. This period is returned in TimerPeriod, and EFI_SUCCESS + is returned. If TimerPeriod is NULL, then EFI_INVALID_PARAMETER is returned. + + @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod A pointer to the amount of time in 100 nS units that the system + will wait before the watchdog timer is fired. If TimerPeriod of + zero is returned, then the watchdog timer is disabled. + + @retval EFI_SUCCESS The amount of time that the system will wait before + firing the watchdog timer was returned in TimerPeriod. + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD)( + IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ); + +/// +/// This protocol provides the services required to implement the Boot Service +/// SetWatchdogTimer(). It provides a service to set the amount of time to wait +/// before firing the watchdog timer, and it also provides a service to register +/// a handler that is invoked when the watchdog timer fires. This protocol can +/// implement the watchdog timer by using the event and timer Boot Services, or +/// it can make use of custom hardware. When the watchdog timer fires, control +/// will be passed to a handler if one has been registered. If no handler has +/// been registered, or the registered handler returns, then the system will be +/// reset by calling the Runtime Service ResetSystem(). +/// +struct _EFI_WATCHDOG_TIMER_ARCH_PROTOCOL { + EFI_WATCHDOG_TIMER_REGISTER_HANDLER RegisterHandler; + EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD SetTimerPeriod; + EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD GetTimerPeriod; +}; + +extern EFI_GUID gEfiWatchdogTimerArchProtocolGuid; + +#endif diff --git a/sys/contrib/openzfs/.github/workflows/scripts/generate-ci-type.py b/sys/contrib/openzfs/.github/workflows/scripts/generate-ci-type.py index 08021aabcb61..059d6ad3872b 100755 --- a/sys/contrib/openzfs/.github/workflows/scripts/generate-ci-type.py +++ b/sys/contrib/openzfs/.github/workflows/scripts/generate-ci-type.py @@ -7,7 +7,7 @@ Prints "quick" if (explicity required by user): - the *last* commit message contains 'ZFS-CI-Type: quick' or if (heuristics): - the files changed are not in the list of specified directories, and -- all commit messages do not contain 'ZFS-CI-Type: full' +- all commit messages do not contain 'ZFS-CI-Type: (full|linux|freebsd)' Otherwise prints "full". """ @@ -70,7 +70,7 @@ if __name__ == '__main__': for line in last_commit_message_raw.stdout.decode().splitlines(): if line.strip().lower() == 'zfs-ci-type: quick': - output_type('quick', f'explicitly requested by HEAD commit {head}') + output_type('quick', f'requested by HEAD commit {head}') # check all commit messages all_commit_message_raw = subprocess.run([ @@ -83,8 +83,12 @@ if __name__ == '__main__': for line in all_commit_message: if line.startswith('ZFS-CI-Commit:'): commit_ref = line.lstrip('ZFS-CI-Commit:').rstrip() + if line.strip().lower() == 'zfs-ci-type: freebsd': + output_type('freebsd', f'requested by commit {commit_ref}') + if line.strip().lower() == 'zfs-ci-type: linux': + output_type('linux', f'requested by commit {commit_ref}') if line.strip().lower() == 'zfs-ci-type: full': - output_type('full', f'explicitly requested by commit {commit_ref}') + output_type('full', f'requested by commit {commit_ref}') # check changed files changed_files_raw = subprocess.run([ diff --git a/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh b/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh index 422b3e9df388..5bdd84ca2435 100755 --- a/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh +++ b/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh @@ -47,16 +47,15 @@ case "$OS" in OSNAME="Archlinux" URL="https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2" ;; + centos-stream9) + OSNAME="CentOS Stream 9" + URL="https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2" + ;; centos-stream10) OSNAME="CentOS Stream 10" - # TODO: #16903 Overwrite OSv to stream9 for virt-install until it's added to osinfo OSv="centos-stream9" URL="https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2" ;; - centos-stream9) - OSNAME="CentOS Stream 9" - URL="https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2" - ;; debian11) OSNAME="Debian 11" URL="https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.qcow2" @@ -83,6 +82,11 @@ case "$OS" in OSv="fedora-unknown" URL="https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2" ;; + fedora43) + OSNAME="Fedora 43" + OSv="fedora-unknown" + URL="https://download.fedoraproject.org/pub/fedora/linux/releases/43/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-43-1.6.x86_64.qcow2" + ;; freebsd13-5r) FreeBSD="13.5-RELEASE" OSNAME="FreeBSD $FreeBSD" @@ -95,8 +99,8 @@ case "$OS" in FreeBSD="14.2-RELEASE" OSNAME="FreeBSD $FreeBSD" OSv="freebsd14.0" - KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz" URLxz="$FREEBSD_REL/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI.raw.xz" + KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz" ;; freebsd14-3r) FreeBSD="14.3-RELEASE" @@ -120,8 +124,8 @@ case "$OS" in URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz" KSRC="$FREEBSD_SNAP/../amd64/$FreeBSD/src.txz" ;; - freebsd15-0c) - FreeBSD="15.0-ALPHA4" + freebsd15-0s) + FreeBSD="15.0-STABLE" OSNAME="FreeBSD $FreeBSD" OSv="freebsd14.0" URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz" diff --git a/sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml b/sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml index d8a95954fe1a..6367fb3a6ce2 100644 --- a/sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml +++ b/sys/contrib/openzfs/.github/workflows/zfs-qemu-packages.yml @@ -52,7 +52,7 @@ jobs: strategy: fail-fast: false matrix: - os: ['almalinux8', 'almalinux9', 'almalinux10', 'fedora41', 'fedora42'] + os: ['almalinux8', 'almalinux9', 'almalinux10', 'fedora41', 'fedora42', 'fedora43'] runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml b/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml index 3b164548f9be..dad7611cf1a9 100644 --- a/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml +++ b/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml @@ -29,24 +29,34 @@ jobs: - name: Generate OS config and CI type id: os run: | - FULL_OS='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora41", "fedora42", "freebsd13-5r", "freebsd14-3s", "freebsd15-0c", "ubuntu22", "ubuntu24"]' - QUICK_OS='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd14-3s", "ubuntu24"]' + ci_type="default" + # determine CI type when running on PR - ci_type="full" if ${{ github.event_name == 'pull_request' }}; then head=${{ github.event.pull_request.head.sha }} base=${{ github.event.pull_request.base.sha }} ci_type=$(python3 .github/workflows/scripts/generate-ci-type.py $head $base) fi - if [ "$ci_type" == "quick" ]; then - os_selection="$QUICK_OS" - else - os_selection="$FULL_OS" - fi + + case "$ci_type" in + quick) + os_selection='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd15-0s", "ubuntu24"]' + ;; + linux) + os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian11", "debian12", "debian13", "fedora41", "fedora42", "fedora43", "ubuntu22", "ubuntu24"]' + ;; + freebsd) + os_selection='["freebsd13-5r", "freebsd14-2r", "freebsd14-3r", "freebsd13-5s", "freebsd14-3s", "freebsd15-0s", "freebsd16-0c"]' + ;; + *) + # default list + os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora42", "fedora43", "freebsd14-3r", "freebsd15-0s", "freebsd16-0c", "ubuntu22", "ubuntu24"]' + ;; + esac if ${{ github.event.inputs.fedora_kernel_ver != '' }}; then - # They specified a custom kernel version for Fedora. Use only - # Fedora runners. + # They specified a custom kernel version for Fedora. + # Use only Fedora runners. os_json=$(echo ${os_selection} | jq -c '[.[] | select(startswith("fedora"))]') else # Normal case @@ -62,13 +72,13 @@ jobs: strategy: fail-fast: false matrix: - # rhl: almalinux8, almalinux9, centos-stream9, fedora4x + # rhl: almalinux8, almalinux9, centos-streamX, fedora4x # debian: debian12, debian13, ubuntu22, ubuntu24 # misc: archlinux, tumbleweed - # FreeBSD variants of 2025-06: + # FreeBSD variants of november 2025: # FreeBSD Release: freebsd13-5r, freebsd14-2r, freebsd14-3r - # FreeBSD Stable: freebsd13-5s, freebsd14-3s - # FreeBSD Current: freebsd15-0c, freebsd16-0c + # FreeBSD Stable: freebsd13-5s, freebsd14-3s, freebsd15-0s + # FreeBSD Current: freebsd16-0c os: ${{ fromJson(needs.test-config.outputs.test_os) }} runs-on: ubuntu-24.04 steps: diff --git a/sys/contrib/openzfs/README.md b/sys/contrib/openzfs/README.md index a90736bb56b7..a39b88fedd12 100644 --- a/sys/contrib/openzfs/README.md +++ b/sys/contrib/openzfs/README.md @@ -10,7 +10,7 @@ This repository contains the code for running OpenZFS on Linux and FreeBSD. # Official Resources * [Documentation](https://openzfs.github.io/openzfs-docs/) - for using and developing this repo - * [ZoL Site](https://zfsonlinux.org) - Linux release info & links + * [ZoL site](https://zfsonlinux.org) - Linux release info & links * [Mailing lists](https://openzfs.github.io/openzfs-docs/Project%20and%20Community/Mailing%20Lists.html) * [OpenZFS site](https://openzfs.org/) - for conference videos and info on other platforms (illumos, OSX, Windows, etc) diff --git a/sys/contrib/openzfs/autogen.sh b/sys/contrib/openzfs/autogen.sh index 39eb82203d69..5cb152474698 100755 --- a/sys/contrib/openzfs/autogen.sh +++ b/sys/contrib/openzfs/autogen.sh @@ -1,62 +1,3 @@ #!/bin/sh -[ "${0%/*}" = "$0" ] || cd "${0%/*}" || exit -# %reldir%/%canon_reldir% (%D%/%C%) only appeared in automake 1.14, but RHEL/CentOS 7 has 1.13.4 -# This is an (overly) simplistic preprocessor that papers around this for the duration of the generation step, -# and can be removed once support for CentOS 7 is dropped -automake --version | awk '{print $NF; exit}' | ( - IFS=. read -r AM_MAJ AM_MIN _ - [ "$AM_MAJ" -gt 1 ] || [ "$AM_MIN" -ge 14 ] -) || { - process_root() { - root="$1"; shift - - grep -q '%[CD]%' "$root/Makefile.am" || return - find "$root" -name Makefile.am "$@" | while read -r dir; do - dir="${dir%/Makefile.am}" - grep -q '%[CD]%' "$dir/Makefile.am" || continue - - reldir="${dir#"$root"}" - reldir="${reldir#/}" - - canon_reldir="$(printf '%s' "$reldir" | tr -C 'a-zA-Z0-9@_' '_')" - - reldir_slash="$reldir/" - canon_reldir_slash="${canon_reldir}_" - [ -z "$reldir" ] && reldir_slash= - [ -z "$reldir" ] && canon_reldir_slash= - - echo "$dir/Makefile.am" >&3 - sed -i~ -e "s:%D%/:$reldir_slash:g" -e "s:%D%:$reldir:g" \ - -e "s:%C%_:$canon_reldir_slash:g" -e "s:%C%:$canon_reldir:g" "$dir/Makefile.am" - done 3>>"$substituted_files" - } - - rollback() { - while read -r f; do - mv "$f~" "$f" - done < "$substituted_files" - rm -f "$substituted_files" - } - - - echo "Automake <1.14; papering over missing %reldir%/%canon_reldir% support" >&2 - - substituted_files="$(mktemp)" - trap rollback EXIT - - roots="$(sed '/Makefile$/!d;/module/d;s:^\s*:./:;s:/Makefile::;/^\.$/d' configure.ac)" - - IFS=" -" - for root in $roots; do - root="${root#./}" - process_root "$root" - done - - set -f - # shellcheck disable=SC2086,SC2046 - process_root . $(printf '!\n-path\n%s/*\n' $roots) -} - -autoreconf -fiv && rm -rf autom4te.cache +autoreconf -fiv "$(dirname "$0")" && rm -rf "$(dirname "$0")"/autom4te.cache diff --git a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c index cf3e123c6090..4839e909e4f7 100644 --- a/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c +++ b/sys/contrib/openzfs/cmd/raidz_test/raidz_test.c @@ -33,6 +33,7 @@ #include <sys/vdev_raidz_impl.h> #include <assert.h> #include <stdio.h> +#include <libzpool.h> #include "raidz_test.h" static int *rand_data; diff --git a/sys/contrib/openzfs/cmd/zdb/zdb.c b/sys/contrib/openzfs/cmd/zdb/zdb.c index 2560ad045db3..09e144f66c68 100644 --- a/sys/contrib/openzfs/cmd/zdb/zdb.c +++ b/sys/contrib/openzfs/cmd/zdb/zdb.c @@ -89,6 +89,7 @@ #include <sys/zstd/zstd.h> #include <sys/backtrace.h> +#include <libzpool.h> #include <libnvpair.h> #include <libzutil.h> #include <libzfs_core.h> @@ -7899,11 +7900,11 @@ zdb_set_skip_mmp(char *target) * Disable the activity check to allow examination of * active pools. */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); if ((spa = spa_lookup(target)) != NULL) { spa->spa_import_flags |= ZFS_IMPORT_SKIP_MMP; } - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } #define BOGUS_SUFFIX "_CHECKPOINTED_UNIVERSE" @@ -10022,13 +10023,13 @@ main(int argc, char **argv) * try opening the pool after clearing the * log state. */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); if ((spa = spa_lookup(target)) != NULL && spa->spa_log_state == SPA_LOG_MISSING) { spa->spa_log_state = SPA_LOG_CLEAR; error = 0; } - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); if (!error) { error = spa_open_rewind(target, &spa, diff --git a/sys/contrib/openzfs/cmd/zfs/zfs_project.c b/sys/contrib/openzfs/cmd/zfs/zfs_project.c index fbf5e6cbdc68..8925e6672bef 100644 --- a/sys/contrib/openzfs/cmd/zfs/zfs_project.c +++ b/sys/contrib/openzfs/cmd/zfs/zfs_project.c @@ -145,11 +145,11 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc) switch (zpc->zpc_op) { case ZFS_PROJECT_OP_LIST: (void) printf("%5u %c %s\n", fsx.fsx_projid, - (fsx.fsx_xflags & ZFS_PROJINHERIT_FL) ? 'P' : '-', name); + (fsx.fsx_xflags & FS_XFLAG_PROJINHERIT) ? 'P' : '-', name); goto out; case ZFS_PROJECT_OP_CHECK: if (fsx.fsx_projid == zpc->zpc_expected_projid && - fsx.fsx_xflags & ZFS_PROJINHERIT_FL) + fsx.fsx_xflags & FS_XFLAG_PROJINHERIT) goto out; if (!zpc->zpc_newline) { @@ -164,29 +164,30 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc) "(%u/%u)\n", name, fsx.fsx_projid, (uint32_t)zpc->zpc_expected_projid); - if (!(fsx.fsx_xflags & ZFS_PROJINHERIT_FL)) + if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT)) (void) printf("%s - project inherit flag is not set\n", name); goto out; case ZFS_PROJECT_OP_CLEAR: - if (!(fsx.fsx_xflags & ZFS_PROJINHERIT_FL) && + if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT) && (zpc->zpc_keep_projid || fsx.fsx_projid == ZFS_DEFAULT_PROJID)) goto out; - fsx.fsx_xflags &= ~ZFS_PROJINHERIT_FL; + fsx.fsx_xflags &= ~FS_XFLAG_PROJINHERIT; if (!zpc->zpc_keep_projid) fsx.fsx_projid = ZFS_DEFAULT_PROJID; break; case ZFS_PROJECT_OP_SET: if (fsx.fsx_projid == zpc->zpc_expected_projid && - (!zpc->zpc_set_flag || fsx.fsx_xflags & ZFS_PROJINHERIT_FL)) + (!zpc->zpc_set_flag || + fsx.fsx_xflags & FS_XFLAG_PROJINHERIT)) goto out; fsx.fsx_projid = zpc->zpc_expected_projid; if (zpc->zpc_set_flag) - fsx.fsx_xflags |= ZFS_PROJINHERIT_FL; + fsx.fsx_xflags |= FS_XFLAG_PROJINHERIT; break; default: ASSERT(0); @@ -194,11 +195,30 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc) } ret = ioctl(fd, ZFS_IOC_FSSETXATTR, &fsx); - if (ret) + if (ret) { (void) fprintf(stderr, gettext("failed to set xattr for %s: %s\n"), name, strerror(errno)); + if (errno == ENOTSUP) { + char *kver = zfs_version_kernel(); + /* + * Special case: a module/userspace version mismatch can + * return ENOTSUP due to us fixing the XFLAGs bits in + * #17884. In that case give a hint to the user that + * they should take action to make the versions match. + */ + if (strcmp(kver, ZFS_META_ALIAS) != 0) { + fprintf(stderr, + gettext("Warning: The zfs module version " + "(%s) and userspace\nversion (%s) do not " + "match up. This may be the\ncause of the " + "\"Operation not supported\" error.\n"), + kver, ZFS_META_ALIAS); + } + } + } + out: close(fd); return (ret); diff --git a/sys/contrib/openzfs/cmd/zhack.c b/sys/contrib/openzfs/cmd/zhack.c index 8ffbf91ffb30..536e3880718c 100644 --- a/sys/contrib/openzfs/cmd/zhack.c +++ b/sys/contrib/openzfs/cmd/zhack.c @@ -55,6 +55,7 @@ #include <zfeature_common.h> #include <libzutil.h> #include <sys/metaslab_impl.h> +#include <libzpool.h> static importargs_t g_importargs; static char *g_pool; diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_main.c b/sys/contrib/openzfs/cmd/zpool/zpool_main.c index a6658a9c2800..b0e05aa2776a 100644 --- a/sys/contrib/openzfs/cmd/zpool/zpool_main.c +++ b/sys/contrib/openzfs/cmd/zpool/zpool_main.c @@ -43,6 +43,7 @@ #include <errno.h> #include <fcntl.h> #include <getopt.h> +#include <inttypes.h> #include <libgen.h> #include <libintl.h> #include <libuutil.h> @@ -51,6 +52,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <termios.h> #include <thread_pool.h> #include <time.h> #include <unistd.h> @@ -494,8 +496,7 @@ get_usage(zpool_help_t idx) "[--json-int, --json-pool-key-guid]] ...\n" "\t [-T d|u] [pool] [interval [count]]\n")); case HELP_PREFETCH: - return (gettext("\tprefetch -t <type> [<type opts>] <pool>\n" - "\t -t ddt <pool>\n")); + return (gettext("\tprefetch [-t <type>] <pool>\n")); case HELP_OFFLINE: return (gettext("\toffline [--power]|[[-f][-t]] <pool> " "<device> ...\n")); @@ -635,7 +636,7 @@ zpool_power_on_and_disk_wait(zpool_handle_t *zhp, char *vdev) if (rc != 0) return (rc); - zpool_disk_wait(vdev_name_to_path(zhp, vdev)); + (void) zpool_disk_wait(vdev_name_to_path(zhp, vdev)); return (0); } @@ -665,7 +666,7 @@ zpool_power_on_pool_and_wait_for_devices(zpool_handle_t *zhp) */ FOR_EACH_REAL_LEAF_VDEV(zhp, nv) { path = fnvlist_lookup_string(nv, ZPOOL_CONFIG_PATH); - zpool_disk_wait(path); + (void) zpool_disk_wait(path); } return (0); @@ -848,7 +849,6 @@ zpool_do_initialize(int argc, char **argv) if (argc < 1 && !initialize_all) { (void) fprintf(stderr, gettext("missing pool name argument\n")); usage(B_FALSE); - return (-1); } if (wait && (cmd_type != POOL_INITIALIZE_START)) { @@ -1039,9 +1039,10 @@ nice_num_str_nvlist(nvlist_t *item, const char *key, uint64_t value, boolean_t literal, boolean_t as_int, int format) { char buf[256]; + if (literal) { if (!as_int) - snprintf(buf, 256, "%llu", (u_longlong_t)value); + (void) snprintf(buf, 256, "%llu", (u_longlong_t)value); } else { switch (format) { case ZFS_NICENUM_1024: @@ -1087,7 +1088,7 @@ zpool_json_schema(int maj_v, int min_v) nvlist_t *sch = fnvlist_alloc(); nvlist_t *ov = fnvlist_alloc(); - snprintf(cmd, MAX_CMD_LEN, "zpool %s", current_command->name); + (void) snprintf(cmd, MAX_CMD_LEN, "zpool %s", current_command->name); fnvlist_add_string(ov, "command", cmd); fnvlist_add_uint32(ov, "vers_major", maj_v); fnvlist_add_uint32(ov, "vers_minor", min_v); @@ -1118,12 +1119,12 @@ fill_pool_info(nvlist_t *list, zpool_handle_t *zhp, boolean_t addtype, } else { char value[ZFS_MAXPROPLEN]; if (guid) { - snprintf(value, ZFS_MAXPROPLEN, "%llu", + (void) snprintf(value, ZFS_MAXPROPLEN, "%llu", (u_longlong_t)guid); fnvlist_add_string(list, ZPOOL_CONFIG_POOL_GUID, value); } if (txg) { - snprintf(value, ZFS_MAXPROPLEN, "%llu", + (void) snprintf(value, ZFS_MAXPROPLEN, "%llu", (u_longlong_t)txg); fnvlist_add_string(list, ZPOOL_CONFIG_POOL_TXG, value); } @@ -1182,7 +1183,7 @@ fill_vdev_info(nvlist_t *list, zpool_handle_t *zhp, char *name, fnvlist_add_uint64(list, "guid", guid); } else { char buf[ZFS_MAXPROPLEN]; - snprintf(buf, ZFS_MAXPROPLEN, "%llu", + (void) snprintf(buf, ZFS_MAXPROPLEN, "%llu", (u_longlong_t)guid); fnvlist_add_string(list, "guid", buf); } @@ -1764,7 +1765,7 @@ vdev_is_active(char *vdev_path) return (1); /* cant open O_EXCL - disk is active */ } - close(fd); + (void) close(fd); return (0); /* disk is inactive in the pool */ } @@ -2415,12 +2416,12 @@ zpool_export_one(zpool_handle_t *zhp, void *data) * So we serialize access here for 'zpool export -a' parallel case. */ if (cb->tpool != NULL) - pthread_mutex_lock(&cb->mnttab_lock); + (void) pthread_mutex_lock(&cb->mnttab_lock); int retval = zpool_disable_datasets(zhp, cb->force); if (cb->tpool != NULL) - pthread_mutex_unlock(&cb->mnttab_lock); + (void) pthread_mutex_unlock(&cb->mnttab_lock); if (retval) return (1); @@ -2533,7 +2534,7 @@ zpool_do_export(int argc, char **argv) cb.tpool = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN), 0, NULL); - pthread_mutex_init(&cb.mnttab_lock, NULL); + (void) pthread_mutex_init(&cb.mnttab_lock, NULL); /* Asynchronously call zpool_export_one using thread pool */ ret = for_each_pool(argc, argv, B_TRUE, NULL, ZFS_TYPE_POOL, @@ -2651,7 +2652,7 @@ zpool_nvlist_cmd(vdev_cmd_data_list_t *vcdl, const char *pool, const char *path, for (j = data->cols_cnt; j < data->lines_cnt; j++) { if (data->lines[j]) { - snprintf(tmp, 256, "extra_%d", k++); + (void) snprintf(tmp, 256, "extra_%d", k++); fnvlist_add_string(item, tmp, data->lines[j]); } @@ -2697,17 +2698,17 @@ zpool_print_cmd(vdev_cmd_data_list_t *vcdl, const char *pool, const char *path) printf("%*s", vcdl->uniq_cols_width[j], val); if (j < vcdl->uniq_cols_cnt - 1) - fputs(" ", stdout); + (void) fputs(" ", stdout); } /* Print out any values that aren't in a column at the end */ for (j = data->cols_cnt; j < data->lines_cnt; j++) { /* Did we have any columns? If so print a spacer. */ if (vcdl->uniq_cols_cnt > 0) - fputs(" ", stdout); + (void) fputs(" ", stdout); val = data->lines[j]; - fputs(val ?: "", stdout); + (void) fputs(val ?: "", stdout); } break; } @@ -2920,7 +2921,7 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name, return; } - printf_color(health_str_to_color(state), + (void) printf_color(health_str_to_color(state), "\t%*s%-*s %-8s", depth, "", cb->cb_namewidth - depth, name, state); @@ -2938,26 +2939,26 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name, scolor = ANSI_BLUE; if (cb->cb_literal) { - fputc(' ', stdout); - printf_color(rcolor, "%5llu", + (void) fputc(' ', stdout); + (void) printf_color(rcolor, "%5llu", (u_longlong_t)vs->vs_read_errors); - fputc(' ', stdout); - printf_color(wcolor, "%5llu", + (void) fputc(' ', stdout); + (void) printf_color(wcolor, "%5llu", (u_longlong_t)vs->vs_write_errors); - fputc(' ', stdout); - printf_color(ccolor, "%5llu", + (void) fputc(' ', stdout); + (void) printf_color(ccolor, "%5llu", (u_longlong_t)vs->vs_checksum_errors); } else { zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf)); - fputc(' ', stdout); - printf_color(rcolor, "%5s", rbuf); - fputc(' ', stdout); - printf_color(wcolor, "%5s", wbuf); - fputc(' ', stdout); - printf_color(ccolor, "%5s", cbuf); + (void) fputc(' ', stdout); + (void) printf_color(rcolor, "%5s", rbuf); + (void) fputc(' ', stdout); + (void) printf_color(wcolor, "%5s", wbuf); + (void) fputc(' ', stdout); + (void) printf_color(ccolor, "%5s", cbuf); } if (cb->cb_print_slow_ios) { if (children == 0) { @@ -2965,14 +2966,14 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name, zfs_nicenum(vs->vs_slow_ios, rbuf, sizeof (rbuf)); } else { - snprintf(rbuf, sizeof (rbuf), "-"); + (void) snprintf(rbuf, sizeof (rbuf), "-"); } if (cb->cb_literal) - printf_color(scolor, " %5llu", + (void) printf_color(scolor, " %5llu", (u_longlong_t)vs->vs_slow_ios); else - printf_color(scolor, " %5s", rbuf); + (void) printf_color(scolor, " %5s", rbuf); } if (cb->cb_print_power) { if (children == 0) { @@ -2981,7 +2982,7 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name, fnvlist_lookup_string(nv, ZPOOL_CONFIG_PATH))) { case 0: - printf_color(ANSI_RED, " %5s", + (void) printf_color(ANSI_RED, " %5s", gettext("off")); break; case 1: @@ -3427,70 +3428,70 @@ show_import(nvlist_t *config, boolean_t report_error) if (reason != ZPOOL_STATUS_OK) { (void) printf("%s", indent); - printf_color(ANSI_BOLD, gettext("status: ")); + (void) printf_color(ANSI_BOLD, gettext("status: ")); } switch (reason) { case ZPOOL_STATUS_MISSING_DEV_R: case ZPOOL_STATUS_MISSING_DEV_NR: case ZPOOL_STATUS_BAD_GUID_SUM: - printf_color(ANSI_YELLOW, gettext("One or more devices are " - "missing from the system.\n")); + (void) printf_color(ANSI_YELLOW, gettext("One or more devices " + "are missing from the system.\n")); break; case ZPOOL_STATUS_CORRUPT_LABEL_R: case ZPOOL_STATUS_CORRUPT_LABEL_NR: - printf_color(ANSI_YELLOW, gettext("One or more devices " + (void) printf_color(ANSI_YELLOW, gettext("One or more devices " "contains corrupted data.\n")); break; case ZPOOL_STATUS_CORRUPT_DATA: - printf_color(ANSI_YELLOW, gettext("The pool data is " + (void) printf_color(ANSI_YELLOW, gettext("The pool data is " "corrupted.\n")); break; case ZPOOL_STATUS_OFFLINE_DEV: - printf_color(ANSI_YELLOW, gettext("One or more devices " + (void) printf_color(ANSI_YELLOW, gettext("One or more devices " "are offlined.\n")); break; case ZPOOL_STATUS_CORRUPT_POOL: - printf_color(ANSI_YELLOW, gettext("The pool metadata is " + (void) printf_color(ANSI_YELLOW, gettext("The pool metadata is " "corrupted.\n")); break; case ZPOOL_STATUS_VERSION_OLDER: - printf_color(ANSI_YELLOW, gettext("The pool is formatted using " - "a legacy on-disk version.\n")); + (void) printf_color(ANSI_YELLOW, gettext("The pool is " + "formatted using a legacy on-disk version.\n")); break; case ZPOOL_STATUS_VERSION_NEWER: - printf_color(ANSI_YELLOW, gettext("The pool is formatted using " - "an incompatible version.\n")); + (void) printf_color(ANSI_YELLOW, gettext("The pool is " + "formatted using an incompatible version.\n")); break; case ZPOOL_STATUS_FEAT_DISABLED: - printf_color(ANSI_YELLOW, gettext("Some supported " + (void) printf_color(ANSI_YELLOW, gettext("Some supported " "features are not enabled on the pool.\n" "\t%s(Note that they may be intentionally disabled if the\n" "\t%s'compatibility' property is set.)\n"), indent, indent); break; case ZPOOL_STATUS_COMPATIBILITY_ERR: - printf_color(ANSI_YELLOW, gettext("Error reading or parsing " - "the file(s) indicated by the 'compatibility'\n" + (void) printf_color(ANSI_YELLOW, gettext("Error reading or " + "parsing the file(s) indicated by the 'compatibility'\n" "\t%sproperty.\n"), indent); break; case ZPOOL_STATUS_INCOMPATIBLE_FEAT: - printf_color(ANSI_YELLOW, gettext("One or more features " + (void) printf_color(ANSI_YELLOW, gettext("One or more features " "are enabled on the pool despite not being\n" "\t%srequested by the 'compatibility' property.\n"), indent); break; case ZPOOL_STATUS_UNSUP_FEAT_READ: - printf_color(ANSI_YELLOW, gettext("The pool uses the following " - "feature(s) not supported on this system:\n")); + (void) printf_color(ANSI_YELLOW, gettext("The pool uses the " + "following feature(s) not supported on this system:\n")); color_start(ANSI_YELLOW); zpool_collect_unsup_feat(config, buf, 2048); (void) printf("%s", buf); @@ -3498,7 +3499,7 @@ show_import(nvlist_t *config, boolean_t report_error) break; case ZPOOL_STATUS_UNSUP_FEAT_WRITE: - printf_color(ANSI_YELLOW, gettext("The pool can only be " + (void) printf_color(ANSI_YELLOW, gettext("The pool can only be " "accessed in read-only mode on this system. It\n" "\t%scannot be accessed in read-write mode because it uses " "the following\n" @@ -3511,47 +3512,48 @@ show_import(nvlist_t *config, boolean_t report_error) break; case ZPOOL_STATUS_HOSTID_ACTIVE: - printf_color(ANSI_YELLOW, gettext("The pool is currently " - "imported by another system.\n")); + (void) printf_color(ANSI_YELLOW, gettext("The pool is " + "currently imported by another system.\n")); break; case ZPOOL_STATUS_HOSTID_REQUIRED: - printf_color(ANSI_YELLOW, gettext("The pool has the " + (void) printf_color(ANSI_YELLOW, gettext("The pool has the " "multihost property on. It cannot\n" "\t%sbe safely imported when the system hostid is not " "set.\n"), indent); break; case ZPOOL_STATUS_HOSTID_MISMATCH: - printf_color(ANSI_YELLOW, gettext("The pool was last accessed " - "by another system.\n")); + (void) printf_color(ANSI_YELLOW, gettext("The pool was last " + "accessed by another system.\n")); break; case ZPOOL_STATUS_FAULTED_DEV_R: case ZPOOL_STATUS_FAULTED_DEV_NR: - printf_color(ANSI_YELLOW, gettext("One or more devices are " - "faulted.\n")); + (void) printf_color(ANSI_YELLOW, gettext("One or more devices " + "are faulted.\n")); break; case ZPOOL_STATUS_BAD_LOG: - printf_color(ANSI_YELLOW, gettext("An intent log record cannot " - "be read.\n")); + (void) printf_color(ANSI_YELLOW, gettext("An intent log record " + "cannot be read.\n")); break; case ZPOOL_STATUS_RESILVERING: case ZPOOL_STATUS_REBUILDING: - printf_color(ANSI_YELLOW, gettext("One or more devices were " - "being resilvered.\n")); + (void) printf_color(ANSI_YELLOW, gettext("One or more devices " + "were being resilvered.\n")); break; case ZPOOL_STATUS_ERRATA: - printf_color(ANSI_YELLOW, gettext("Errata #%d detected.\n"), + (void) printf_color(ANSI_YELLOW, + gettext("Errata #%d detected.\n"), errata); break; case ZPOOL_STATUS_NON_NATIVE_ASHIFT: - printf_color(ANSI_YELLOW, gettext("One or more devices are " - "configured to use a non-native block size.\n" + (void) printf_color(ANSI_YELLOW, gettext("One or more devices " + "are configured to use a non-native block size.\n" "\t%sExpect reduced performance.\n"), indent); break; @@ -4200,7 +4202,7 @@ zpool_do_checkpoint(int argc, char **argv) #define CHECKPOINT_OPT 1024 /* - * zpool prefetch <type> [<type opts>] <pool> + * zpool prefetch [-t <type>] <pool> * * Prefetchs a particular type of data in the specified pool. */ @@ -4245,20 +4247,27 @@ zpool_do_prefetch(int argc, char **argv) poolname = argv[0]; - argc--; - argv++; - - if (strcmp(typestr, "ddt") == 0) { - type = ZPOOL_PREFETCH_DDT; - } else { - (void) fprintf(stderr, gettext("unsupported prefetch type\n")); - usage(B_FALSE); - } - if ((zhp = zpool_open(g_zfs, poolname)) == NULL) return (1); - err = zpool_prefetch(zhp, type); + if (typestr == NULL) { + /* Prefetch all types */ + err = zpool_prefetch(zhp, ZPOOL_PREFETCH_DDT); + if (err == 0) + err = zpool_prefetch(zhp, ZPOOL_PREFETCH_BRT); + } else { + if (strcmp(typestr, "ddt") == 0) { + type = ZPOOL_PREFETCH_DDT; + } else if (strcmp(typestr, "brt") == 0) { + type = ZPOOL_PREFETCH_BRT; + } else { + (void) fprintf(stderr, + gettext("unsupported prefetch type\n")); + zpool_close(zhp); + usage(B_FALSE); + } + err = zpool_prefetch(zhp, type); + } zpool_close(zhp); @@ -4916,7 +4925,8 @@ print_cmd_columns(vdev_cmd_data_list_t *vcdl, int use_dashes) for (j = 0; j < vcdl->uniq_cols_width[i]; j++) printf("-"); } else { - printf_color(ANSI_BOLD, "%*s", vcdl->uniq_cols_width[i], + (void) printf_color(ANSI_BOLD, "%*s", + vcdl->uniq_cols_width[i], vcdl->uniq_cols[i]); } } @@ -5067,15 +5077,15 @@ print_iostat_header(iostat_cbdata_t *cb) static void print_stat_color(const char *statbuf, unsigned int column_size) { - fputs(" ", stdout); + (void) fputs(" ", stdout); size_t len = strlen(statbuf); while (len < column_size) { - fputc(' ', stdout); + (void) fputc(' ', stdout); column_size--; } if (*statbuf == '0') { color_start(ANSI_GRAY); - fputc('0', stdout); + (void) fputc('0', stdout); } else { for (; *statbuf; statbuf++) { if (*statbuf == 'K') color_start(ANSI_GREEN); @@ -5084,7 +5094,7 @@ print_stat_color(const char *statbuf, unsigned int column_size) else if (*statbuf == 'T') color_start(ANSI_BOLD_BLUE); else if (*statbuf == 'P') color_start(ANSI_MAGENTA); else if (*statbuf == 'E') color_start(ANSI_CYAN); - fputc(*statbuf, stdout); + (void) fputc(*statbuf, stdout); if (--column_size <= 0) break; } @@ -5992,7 +6002,7 @@ get_stat_flags(zpool_list_t *list) * get_stat_flags_cb() will lop off bits from "mask" until only the * flags that are supported on all pools remain. */ - pool_list_iter(list, B_FALSE, get_stat_flags_cb, &mask); + (void) pool_list_iter(list, B_FALSE, get_stat_flags_cb, &mask); return (mask); } @@ -6241,7 +6251,7 @@ print_zpool_dir_scripts(char *dirpath) print_zpool_script_help(ent->d_name, fullpath); } - closedir(dir); + (void) closedir(dir); } } @@ -6501,7 +6511,6 @@ zpool_do_iostat(int argc, char **argv) argv[0], &cb.cb_vdevs); fprintf(stderr, "\n"); usage(B_FALSE); - return (1); } } else { /* @@ -6544,7 +6553,6 @@ zpool_do_iostat(int argc, char **argv) (void) fprintf(stderr, gettext("[-r|-w] isn't allowed with [-c|-l|-q]\n")); usage(B_FALSE); - return (1); } if (l_histo && rq_histo) { @@ -6552,7 +6560,6 @@ zpool_do_iostat(int argc, char **argv) (void) fprintf(stderr, gettext("Only one of [-r|-w] can be passed at a time\n")); usage(B_FALSE); - return (1); } /* @@ -6681,7 +6688,7 @@ zpool_do_iostat(int argc, char **argv) continue; } - pool_list_iter(list, B_FALSE, print_iostat, &cb); + (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); /* * If there's more than one pool, and we're not in @@ -6896,7 +6903,7 @@ collect_pool(zpool_handle_t *zhp, list_cbdata_t *cb) uint64_t guid = fnvlist_lookup_uint64( zpool_get_config(zhp, NULL), ZPOOL_CONFIG_POOL_GUID); - snprintf(pool_guid, 256, "%llu", + (void) snprintf(pool_guid, 256, "%llu", (u_longlong_t)guid); fnvlist_add_nvlist(d, pool_guid, item); } else { @@ -6963,8 +6970,8 @@ collect_vdev_prop(zpool_prop_t prop, uint64_t value, const char *str, (void) strlcpy(propval, "-", sizeof (propval)); if (json) { - zprop_nvlist_one_property(zpool_prop_to_name(prop), propval, - ZPROP_SRC_NONE, NULL, NULL, nvl, as_int); + (void) zprop_nvlist_one_property(zpool_prop_to_name(prop), + propval, ZPROP_SRC_NONE, NULL, NULL, nvl, as_int); } else { if (scripted) (void) printf("\t%s", propval); @@ -7295,7 +7302,7 @@ list_callback(zpool_handle_t *zhp, void *data) if (cbp->cb_json_pool_key_guid) { guid = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID); - snprintf(pool_guid, 256, "%llu", + (void) snprintf(pool_guid, 256, "%llu", (u_longlong_t)guid); p = fnvlist_lookup_nvlist(d, pool_guid); } else { @@ -8124,14 +8131,12 @@ zpool_do_offline(int argc, char **argv) (void) fprintf(stderr, gettext("-0 and -f cannot be used together\n")); usage(B_FALSE); - return (1); } if (is_power_off && istmp) { (void) fprintf(stderr, gettext("-0 and -t cannot be used together\n")); usage(B_FALSE); - return (1); } argc -= optind; @@ -8169,7 +8174,8 @@ zpool_do_offline(int argc, char **argv) gettext("unable to power off slot for"), argv[i], ret); } - zpool_vdev_set_removed_state(zhp, guid, VDEV_AUX_NONE); + (void) zpool_vdev_set_removed_state(zhp, guid, + VDEV_AUX_NONE); } else if (fault) { vdev_aux_t aux; @@ -8285,9 +8291,9 @@ zpool_do_clear(int argc, char **argv) if (is_power_on) { if (device == NULL) { - zpool_power_on_pool_and_wait_for_devices(zhp); + (void) zpool_power_on_pool_and_wait_for_devices(zhp); } else { - zpool_power_on_and_disk_wait(zhp, device); + (void) zpool_power_on_and_disk_wait(zhp, device); } } @@ -8770,7 +8776,6 @@ zpool_do_trim(int argc, char **argv) if (argc < 1 && !trimall) { (void) fprintf(stderr, gettext("missing pool name argument\n")); usage(B_FALSE); - return (-1); } if (wait && (cmd_type != POOL_TRIM_START)) { @@ -8919,7 +8924,7 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps) char total_i_buf[7], srate_buf[7], irate_buf[7], time_buf[32]; printf(" "); - printf_color(ANSI_BOLD, gettext("scan:")); + (void) printf_color(ANSI_BOLD, gettext("scan:")); printf(" "); /* If there's never been a scan, there's not much to say. */ @@ -9059,7 +9064,7 @@ print_rebuild_status_impl(vdev_rebuild_stat_t *vrs, uint_t c, char *vdev_name) return; printf(" "); - printf_color(ANSI_BOLD, gettext("scan:")); + (void) printf_color(ANSI_BOLD, gettext("scan:")); printf(" "); uint64_t bytes_scanned = vrs->vrs_bytes_scanned; @@ -9762,7 +9767,7 @@ dedup_stats_nvlist(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *item) entry = fnvlist_alloc(); ddt_stats_nvlist(&ddh->ddh_stat[h], cb, entry); - snprintf(buf, 16, "%d", h); + (void) snprintf(buf, 16, "%d", h); fnvlist_add_nvlist(hist, buf, entry); fnvlist_free(entry); } @@ -10141,7 +10146,7 @@ print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs) vdev_name = zpool_vdev_name(g_zfs, zhp, child[prs->prs_removing_vdev], B_TRUE); - printf_color(ANSI_BOLD, gettext("remove: ")); + (void) printf_color(ANSI_BOLD, gettext("remove: ")); start = prs->prs_start_time; end = prs->prs_end_time; @@ -10241,7 +10246,7 @@ print_raidz_expand_status(zpool_handle_t *zhp, pool_raidz_expand_stat_t *pres) &child, &children) == 0); assert(pres->pres_expanding_vdev < children); - printf_color(ANSI_BOLD, gettext("expand: ")); + (void) printf_color(ANSI_BOLD, gettext("expand: ")); time_t start = pres->pres_start_time; time_t end = pres->pres_end_time; @@ -10485,32 +10490,38 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp, switch (reason) { case ZPOOL_STATUS_MISSING_DEV_R: - snprintf(status, ST_SIZE, gettext("One or more devices could " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices could " "not be opened. Sufficient replicas exist for\n\tthe pool " "to continue functioning in a degraded state.\n")); - snprintf(action, AC_SIZE, gettext("Attach the missing device " + (void) snprintf(action, AC_SIZE, + gettext("Attach the missing device " "and online it using 'zpool online'.\n")); break; case ZPOOL_STATUS_MISSING_DEV_NR: - snprintf(status, ST_SIZE, gettext("One or more devices could " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices could " "not be opened. There are insufficient\n\treplicas for the" " pool to continue functioning.\n")); - snprintf(action, AC_SIZE, gettext("Attach the missing device " + (void) snprintf(action, AC_SIZE, + gettext("Attach the missing device " "and online it using 'zpool online'.\n")); break; case ZPOOL_STATUS_CORRUPT_LABEL_R: - snprintf(status, ST_SIZE, gettext("One or more devices could " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices could " "not be used because the label is missing or\n\tinvalid. " "Sufficient replicas exist for the pool to continue\n\t" "functioning in a degraded state.\n")); - snprintf(action, AC_SIZE, gettext("Replace the device using " - "'zpool replace'.\n")); + (void) snprintf(action, AC_SIZE, + gettext("Replace the device using 'zpool replace'.\n")); break; case ZPOOL_STATUS_CORRUPT_LABEL_NR: - snprintf(status, ST_SIZE, gettext("One or more devices could " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices could " "not be used because the label is missing \n\tor invalid. " "There are insufficient replicas for the pool to " "continue\n\tfunctioning.\n")); @@ -10520,63 +10531,70 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp, break; case ZPOOL_STATUS_FAILING_DEV: - snprintf(status, ST_SIZE, gettext("One or more devices has " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices has " "experienced an unrecoverable error. An\n\tattempt was " "made to correct the error. Applications are " "unaffected.\n")); - snprintf(action, AC_SIZE, gettext("Determine if the " + (void) snprintf(action, AC_SIZE, gettext("Determine if the " "device needs to be replaced, and clear the errors\n\tusing" " 'zpool clear' or replace the device with 'zpool " "replace'.\n")); break; case ZPOOL_STATUS_OFFLINE_DEV: - snprintf(status, ST_SIZE, gettext("One or more devices has " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices has " "been taken offline by the administrator.\n\tSufficient " "replicas exist for the pool to continue functioning in " "a\n\tdegraded state.\n")); - snprintf(action, AC_SIZE, gettext("Online the device " + (void) snprintf(action, AC_SIZE, gettext("Online the device " "using 'zpool online' or replace the device with\n\t'zpool " "replace'.\n")); break; case ZPOOL_STATUS_REMOVED_DEV: - snprintf(status, ST_SIZE, gettext("One or more devices have " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices have " "been removed.\n\tSufficient replicas exist for the pool " "to continue functioning in a\n\tdegraded state.\n")); - snprintf(action, AC_SIZE, gettext("Online the device " + (void) snprintf(action, AC_SIZE, gettext("Online the device " "using zpool online' or replace the device with\n\t'zpool " "replace'.\n")); break; case ZPOOL_STATUS_RESILVERING: case ZPOOL_STATUS_REBUILDING: - snprintf(status, ST_SIZE, gettext("One or more devices is " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices is " "currently being resilvered. The pool will\n\tcontinue " "to function, possibly in a degraded state.\n")); - snprintf(action, AC_SIZE, gettext("Wait for the resilver to " - "complete.\n")); + (void) snprintf(action, AC_SIZE, + gettext("Wait for the resilver to complete.\n")); break; case ZPOOL_STATUS_REBUILD_SCRUB: - snprintf(status, ST_SIZE, gettext("One or more devices have " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices have " "been sequentially resilvered, scrubbing\n\tthe pool " "is recommended.\n")); - snprintf(action, AC_SIZE, gettext("Use 'zpool scrub' to " + (void) snprintf(action, AC_SIZE, gettext("Use 'zpool scrub' to " "verify all data checksums.\n")); break; case ZPOOL_STATUS_CORRUPT_DATA: - snprintf(status, ST_SIZE, gettext("One or more devices has " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices has " "experienced an error resulting in data\n\tcorruption. " "Applications may be affected.\n")); - snprintf(action, AC_SIZE, gettext("Restore the file in question" + (void) snprintf(action, AC_SIZE, + gettext("Restore the file in question" " if possible. Otherwise restore the\n\tentire pool from " "backup.\n")); break; case ZPOOL_STATUS_CORRUPT_POOL: - snprintf(status, ST_SIZE, gettext("The pool metadata is " + (void) snprintf(status, ST_SIZE, gettext("The pool metadata is " "corrupted and the pool cannot be opened.\n")); zpool_explain_recover(zpool_get_handle(zhp), zpool_get_name(zhp), reason, zpool_get_config(zhp, NULL), @@ -10584,75 +10602,84 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp, break; case ZPOOL_STATUS_VERSION_OLDER: - snprintf(status, ST_SIZE, gettext("The pool is formatted using " + (void) snprintf(status, ST_SIZE, + gettext("The pool is formatted using " "a legacy on-disk format. The pool can\n\tstill be used, " "but some features are unavailable.\n")); - snprintf(action, AC_SIZE, gettext("Upgrade the pool using " + (void) snprintf(action, AC_SIZE, + gettext("Upgrade the pool using " "'zpool upgrade'. Once this is done, the\n\tpool will no " "longer be accessible on software that does not support\n\t" "feature flags.\n")); break; case ZPOOL_STATUS_VERSION_NEWER: - snprintf(status, ST_SIZE, gettext("The pool has been upgraded " + (void) snprintf(status, ST_SIZE, + gettext("The pool has been upgraded " "to a newer, incompatible on-disk version.\n\tThe pool " "cannot be accessed on this system.\n")); - snprintf(action, AC_SIZE, gettext("Access the pool from a " + (void) snprintf(action, AC_SIZE, + gettext("Access the pool from a " "system running more recent software, or\n\trestore the " "pool from backup.\n")); break; case ZPOOL_STATUS_FEAT_DISABLED: - snprintf(status, ST_SIZE, gettext("Some supported and " + (void) snprintf(status, ST_SIZE, gettext("Some supported and " "requested features are not enabled on the pool.\n\t" "The pool can still be used, but some features are " "unavailable.\n")); - snprintf(action, AC_SIZE, gettext("Enable all features using " + (void) snprintf(action, AC_SIZE, + gettext("Enable all features using " "'zpool upgrade'. Once this is done,\n\tthe pool may no " "longer be accessible by software that does not support\n\t" "the features. See zpool-features(7) for details.\n")); break; case ZPOOL_STATUS_COMPATIBILITY_ERR: - snprintf(status, ST_SIZE, gettext("This pool has a " + (void) snprintf(status, ST_SIZE, gettext("This pool has a " "compatibility list specified, but it could not be\n\t" "read/parsed at this time. The pool can still be used, " "but this\n\tshould be investigated.\n")); - snprintf(action, AC_SIZE, gettext("Check the value of the " + (void) snprintf(action, AC_SIZE, + gettext("Check the value of the " "'compatibility' property against the\n\t" "appropriate file in " ZPOOL_SYSCONF_COMPAT_D " or " ZPOOL_DATA_COMPAT_D ".\n")); break; case ZPOOL_STATUS_INCOMPATIBLE_FEAT: - snprintf(status, ST_SIZE, gettext("One or more features " + (void) snprintf(status, ST_SIZE, gettext("One or more features " "are enabled on the pool despite not being\n\t" "requested by the 'compatibility' property.\n")); - snprintf(action, AC_SIZE, gettext("Consider setting " + (void) snprintf(action, AC_SIZE, gettext("Consider setting " "'compatibility' to an appropriate value, or\n\t" "adding needed features to the relevant file in\n\t" ZPOOL_SYSCONF_COMPAT_D " or " ZPOOL_DATA_COMPAT_D ".\n")); break; case ZPOOL_STATUS_UNSUP_FEAT_READ: - snprintf(status, ST_SIZE, gettext("The pool cannot be accessed " + (void) snprintf(status, ST_SIZE, + gettext("The pool cannot be accessed " "on this system because it uses the\n\tfollowing feature(s)" " not supported on this system:\n")); zpool_collect_unsup_feat(zpool_get_config(zhp, NULL), status, 1024); - snprintf(action, AC_SIZE, gettext("Access the pool from a " + (void) snprintf(action, AC_SIZE, + gettext("Access the pool from a " "system that supports the required feature(s),\n\tor " "restore the pool from backup.\n")); break; case ZPOOL_STATUS_UNSUP_FEAT_WRITE: - snprintf(status, ST_SIZE, gettext("The pool can only be " + (void) snprintf(status, ST_SIZE, gettext("The pool can only be " "accessed in read-only mode on this system. It\n\tcannot be" " accessed in read-write mode because it uses the " "following\n\tfeature(s) not supported on this system:\n")); zpool_collect_unsup_feat(zpool_get_config(zhp, NULL), status, 1024); - snprintf(action, AC_SIZE, gettext("The pool cannot be accessed " + (void) snprintf(action, AC_SIZE, + gettext("The pool cannot be accessed " "in read-write mode. Import the pool with\n" "\t\"-o readonly=on\", access the pool from a system that " "supports the\n\trequired feature(s), or restore the " @@ -10660,90 +10687,105 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp, break; case ZPOOL_STATUS_FAULTED_DEV_R: - snprintf(status, ST_SIZE, gettext("One or more devices are " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices are " "faulted in response to persistent errors.\n\tSufficient " "replicas exist for the pool to continue functioning " "in a\n\tdegraded state.\n")); - snprintf(action, AC_SIZE, gettext("Replace the faulted device, " + (void) snprintf(action, AC_SIZE, + gettext("Replace the faulted device, " "or use 'zpool clear' to mark the device\n\trepaired.\n")); break; case ZPOOL_STATUS_FAULTED_DEV_NR: - snprintf(status, ST_SIZE, gettext("One or more devices are " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices are " "faulted in response to persistent errors. There are " "insufficient replicas for the pool to\n\tcontinue " "functioning.\n")); - snprintf(action, AC_SIZE, gettext("Destroy and re-create the " + (void) snprintf(action, AC_SIZE, + gettext("Destroy and re-create the " "pool from a backup source. Manually marking the device\n" "\trepaired using 'zpool clear' may allow some data " "to be recovered.\n")); break; case ZPOOL_STATUS_IO_FAILURE_MMP: - snprintf(status, ST_SIZE, gettext("The pool is suspended " + (void) snprintf(status, ST_SIZE, + gettext("The pool is suspended " "because multihost writes failed or were delayed;\n\t" "another system could import the pool undetected.\n")); - snprintf(action, AC_SIZE, gettext("Make sure the pool's devices" + (void) snprintf(action, AC_SIZE, + gettext("Make sure the pool's devices" " are connected, then reboot your system and\n\timport the " "pool or run 'zpool clear' to resume the pool.\n")); break; case ZPOOL_STATUS_IO_FAILURE_WAIT: case ZPOOL_STATUS_IO_FAILURE_CONTINUE: - snprintf(status, ST_SIZE, gettext("One or more devices are " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices are " "faulted in response to IO failures.\n")); - snprintf(action, AC_SIZE, gettext("Make sure the affected " + (void) snprintf(action, AC_SIZE, + gettext("Make sure the affected " "devices are connected, then run 'zpool clear'.\n")); break; case ZPOOL_STATUS_BAD_LOG: - snprintf(status, ST_SIZE, gettext("An intent log record " + (void) snprintf(status, ST_SIZE, gettext("An intent log record " "could not be read.\n" "\tWaiting for administrator intervention to fix the " "faulted pool.\n")); - snprintf(action, AC_SIZE, gettext("Either restore the affected " + (void) snprintf(action, AC_SIZE, + gettext("Either restore the affected " "device(s) and run 'zpool online',\n" "\tor ignore the intent log records by running " "'zpool clear'.\n")); break; case ZPOOL_STATUS_NON_NATIVE_ASHIFT: - snprintf(status, ST_SIZE, gettext("One or more devices are " + (void) snprintf(status, ST_SIZE, + gettext("One or more devices are " "configured to use a non-native block size.\n" "\tExpect reduced performance.\n")); - snprintf(action, AC_SIZE, gettext("Replace affected devices " + (void) snprintf(action, AC_SIZE, + gettext("Replace affected devices " "with devices that support the\n\tconfigured block size, " "or migrate data to a properly configured\n\tpool.\n")); break; case ZPOOL_STATUS_HOSTID_MISMATCH: - snprintf(status, ST_SIZE, gettext("Mismatch between pool hostid" + (void) snprintf(status, ST_SIZE, + gettext("Mismatch between pool hostid" " and system hostid on imported pool.\n\tThis pool was " "previously imported into a system with a different " "hostid,\n\tand then was verbatim imported into this " "system.\n")); - snprintf(action, AC_SIZE, gettext("Export this pool on all " + (void) snprintf(action, AC_SIZE, + gettext("Export this pool on all " "systems on which it is imported.\n" "\tThen import it to correct the mismatch.\n")); break; case ZPOOL_STATUS_ERRATA: - snprintf(status, ST_SIZE, gettext("Errata #%d detected.\n"), - errata); + (void) snprintf(status, ST_SIZE, + gettext("Errata #%d detected.\n"), errata); switch (errata) { case ZPOOL_ERRATA_NONE: break; case ZPOOL_ERRATA_ZOL_2094_SCRUB: - snprintf(action, AC_SIZE, gettext("To correct the issue" - " run 'zpool scrub'.\n")); + (void) snprintf(action, AC_SIZE, + gettext("To correct the issue run " + "'zpool scrub'.\n")); break; case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION: (void) strlcat(status, gettext("\tExisting encrypted " "datasets contain an on-disk incompatibility\n\t " "which needs to be corrected.\n"), ST_SIZE); - snprintf(action, AC_SIZE, gettext("To correct the issue" + (void) snprintf(action, AC_SIZE, + gettext("To correct the issue" " backup existing encrypted datasets to new\n\t" "encrypted datasets and destroy the old ones. " "'zfs mount -o ro' can\n\tbe used to temporarily " @@ -10756,7 +10798,8 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp, "incompatibility. This may cause on-disk " "corruption if they are used\n\twith " "'zfs recv'.\n"), ST_SIZE); - snprintf(action, AC_SIZE, gettext("To correct the" + (void) snprintf(action, AC_SIZE, + gettext("To correct the" "issue, enable the bookmark_v2 feature. No " "additional\n\taction is needed if there are no " "encrypted snapshots or bookmarks.\n\tIf preserving" @@ -10786,8 +10829,8 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp, if (cbp->cb_json) fnvlist_add_string(item, "status", status); else { - printf_color(ANSI_BOLD, gettext("status: ")); - printf_color(ANSI_YELLOW, status); + (void) printf_color(ANSI_BOLD, gettext("status: ")); + (void) printf_color(ANSI_YELLOW, status); } } @@ -10795,8 +10838,8 @@ print_status_reason(zpool_handle_t *zhp, status_cbdata_t *cbp, if (cbp->cb_json) fnvlist_add_string(item, "action", action); else { - printf_color(ANSI_BOLD, gettext("action: ")); - printf_color(ANSI_YELLOW, action); + (void) printf_color(ANSI_BOLD, gettext("action: ")); + (void) printf_color(ANSI_YELLOW, action); } } } @@ -10846,13 +10889,14 @@ status_callback_json(zpool_handle_t *zhp, void *data) if (cbp->cb_json_pool_key_guid) { guid = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID); - snprintf(pool_guid, 256, "%llu", (u_longlong_t)guid); + (void) snprintf(pool_guid, 256, "%llu", + (u_longlong_t)guid); } cbp->cb_count++; print_status_reason(zhp, cbp, reason, errata, item); if (msgid != NULL) { - snprintf(msgbuf, 256, + (void) snprintf(msgbuf, 256, "https://openzfs.github.io/openzfs-docs/msg/%s", msgid); fnvlist_add_string(item, "msgid", msgid); @@ -10975,19 +11019,19 @@ status_callback(zpool_handle_t *zhp, void *data) health = zpool_get_state_str(zhp); printf(" "); - printf_color(ANSI_BOLD, gettext("pool:")); + (void) printf_color(ANSI_BOLD, gettext("pool:")); printf(" %s\n", zpool_get_name(zhp)); - fputc(' ', stdout); - printf_color(ANSI_BOLD, gettext("state: ")); + (void) fputc(' ', stdout); + (void) printf_color(ANSI_BOLD, gettext("state: ")); - printf_color(health_str_to_color(health), "%s", health); + (void) printf_color(health_str_to_color(health), "%s", health); - fputc('\n', stdout); + (void) fputc('\n', stdout); print_status_reason(zhp, cbp, reason, errata, NULL); if (msgid != NULL) { printf(" "); - printf_color(ANSI_BOLD, gettext("see:")); + (void) printf_color(ANSI_BOLD, gettext("see:")); printf(gettext( " https://openzfs.github.io/openzfs-docs/msg/%s\n"), msgid); @@ -11028,15 +11072,16 @@ status_callback(zpool_handle_t *zhp, void *data) color_end(); if (cbp->cb_print_slow_ios) { - printf_color(ANSI_BOLD, " %5s", gettext("SLOW")); + (void) printf_color(ANSI_BOLD, " %5s", gettext("SLOW")); } if (cbp->cb_print_power) { - printf_color(ANSI_BOLD, " %5s", gettext("POWER")); + (void) printf_color(ANSI_BOLD, " %5s", + gettext("POWER")); } if (cbp->cb_print_dio_verify) { - printf_color(ANSI_BOLD, " %5s", gettext("DIO")); + (void) printf_color(ANSI_BOLD, " %5s", gettext("DIO")); } if (cbp->vcdl != NULL) @@ -11353,7 +11398,7 @@ check_unsupp_fs(zfs_handle_t *zhp, void *unsupp_fs) (*count)++; } - zfs_iter_filesystems_v2(zhp, 0, check_unsupp_fs, unsupp_fs); + (void) zfs_iter_filesystems_v2(zhp, 0, check_unsupp_fs, unsupp_fs); zfs_close(zhp); @@ -12181,17 +12226,17 @@ zpool_do_events_nvprint(nvlist_t *nvl, int depth) FM_EREPORT_PAYLOAD_ZFS_ZIO_STAGE) == 0 || strcmp(name, FM_EREPORT_PAYLOAD_ZFS_ZIO_PIPELINE) == 0) { - zfs_valstr_zio_stage(i32, flagstr, + (void) zfs_valstr_zio_stage(i32, flagstr, sizeof (flagstr)); printf(gettext("0x%x [%s]"), i32, flagstr); } else if (strcmp(name, FM_EREPORT_PAYLOAD_ZFS_ZIO_TYPE) == 0) { - zfs_valstr_zio_type(i32, flagstr, + (void) zfs_valstr_zio_type(i32, flagstr, sizeof (flagstr)); printf(gettext("0x%x [%s]"), i32, flagstr); } else if (strcmp(name, FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY) == 0) { - zfs_valstr_zio_priority(i32, flagstr, + (void) zfs_valstr_zio_priority(i32, flagstr, sizeof (flagstr)); printf(gettext("0x%x [%s]"), i32, flagstr); } else { @@ -12219,7 +12264,7 @@ zpool_do_events_nvprint(nvlist_t *nvl, int depth) (u_longlong_t)i64); } else if (strcmp(name, FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS) == 0) { - zfs_valstr_zio_flag(i64, flagstr, + (void) zfs_valstr_zio_flag(i64, flagstr, sizeof (flagstr)); printf(gettext("0x%llx [%s]"), (u_longlong_t)i64, flagstr); @@ -12533,7 +12578,7 @@ get_callback_vdev(zpool_handle_t *zhp, char *vdevname, void *data) if (zpool_get_vdev_prop(zhp, vdevname, pl->pl_prop, prop_name, value, sizeof (value), &srctype, cbp->cb_literal) == 0) { - zprop_collect_property(vdevname, cbp, prop_name, + (void) zprop_collect_property(vdevname, cbp, prop_name, value, srctype, NULL, NULL, props); } } @@ -12605,19 +12650,19 @@ get_callback(zpool_handle_t *zhp, void *data) } if (strcmp(cbp->cb_vdevs.cb_names[0], "all-vdevs") == 0) { - for_each_vdev(zhp, get_callback_vdev_cb, data); + (void) for_each_vdev(zhp, get_callback_vdev_cb, data); } else { /* Adjust column widths for vdev properties */ for (vid = 0; vid < cbp->cb_vdevs.cb_names_count; vid++) { - vdev_expand_proplist(zhp, + (void) vdev_expand_proplist(zhp, cbp->cb_vdevs.cb_names[vid], &cbp->cb_proplist); } /* Display the properties */ for (vid = 0; vid < cbp->cb_vdevs.cb_names_count; vid++) { - get_callback_vdev(zhp, + (void) get_callback_vdev(zhp, cbp->cb_vdevs.cb_names[vid], data); } } @@ -12690,7 +12735,7 @@ get_callback(zpool_handle_t *zhp, void *data) uint64_t guid = fnvlist_lookup_uint64( zpool_get_config(zhp, NULL), ZPOOL_CONFIG_POOL_GUID); - snprintf(buf, 256, "%llu", + (void) snprintf(buf, 256, "%llu", (u_longlong_t)guid); fnvlist_add_nvlist(d, buf, item); } else { @@ -12889,7 +12934,6 @@ found: argv[0], &cb.cb_vdevs); fprintf(stderr, "\n"); usage(B_FALSE); - return (1); } } else { if (cb.cb_json) { @@ -13385,11 +13429,11 @@ wait_status_thread(void *arg) } else { timeout.tv_nsec = nanos; } - pthread_mutex_lock(&wd->wd_mutex); + (void) pthread_mutex_lock(&wd->wd_mutex); if (!wd->wd_should_exit) ret = pthread_cond_timedwait(&wd->wd_cv, &wd->wd_mutex, &timeout); - pthread_mutex_unlock(&wd->wd_mutex); + (void) pthread_mutex_unlock(&wd->wd_mutex); if (ret == 0) { break; /* signaled by main thread */ } else if (ret != ETIMEDOUT) { @@ -13420,8 +13464,8 @@ zpool_do_wait(int argc, char **argv) wd.wd_headers_once = B_FALSE; wd.wd_should_exit = B_FALSE; - pthread_mutex_init(&wd.wd_mutex, NULL); - pthread_cond_init(&wd.wd_cv, NULL); + (void) pthread_mutex_init(&wd.wd_mutex, NULL); + (void) pthread_cond_init(&wd.wd_cv, NULL); /* By default, wait for all types of activity. */ for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) @@ -13545,17 +13589,17 @@ found:; if (verbose) { uintptr_t status; - pthread_mutex_lock(&wd.wd_mutex); + (void) pthread_mutex_lock(&wd.wd_mutex); wd.wd_should_exit = B_TRUE; - pthread_cond_signal(&wd.wd_cv); - pthread_mutex_unlock(&wd.wd_mutex); + (void) pthread_cond_signal(&wd.wd_cv); + (void) pthread_mutex_unlock(&wd.wd_mutex); (void) pthread_join(status_thr, (void *)&status); if (status != 0) error = status; } - pthread_mutex_destroy(&wd.wd_mutex); - pthread_cond_destroy(&wd.wd_cv); + (void) pthread_mutex_destroy(&wd.wd_mutex); + (void) pthread_cond_destroy(&wd.wd_cv); return (error); } @@ -13708,14 +13752,14 @@ zpool_do_help(int argc, char **argv) { char page[MAXNAMELEN]; if (argc < 3 || strcmp(argv[2], "zpool") == 0) - strcpy(page, "zpool"); + (void) strcpy(page, "zpool"); else if (strcmp(argv[2], "concepts") == 0 || strcmp(argv[2], "props") == 0) - snprintf(page, sizeof (page), "zpool%s", argv[2]); + (void) snprintf(page, sizeof (page), "zpool%s", argv[2]); else - snprintf(page, sizeof (page), "zpool-%s", argv[2]); + (void) snprintf(page, sizeof (page), "zpool-%s", argv[2]); - execlp("man", "man", page, NULL); + (void) execlp("man", "man", page, NULL); fprintf(stderr, "couldn't run man program: %s", strerror(errno)); return (-1); @@ -13842,7 +13886,6 @@ main(int argc, char **argv) (void) fprintf(stderr, gettext("unrecognized " "command '%s'\n"), cmdname); usage(B_FALSE); - ret = 1; } for (i = 0; i < argc; i++) diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c b/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c index 222b5524669e..d1e9ef76dc10 100644 --- a/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c +++ b/sys/contrib/openzfs/cmd/zpool/zpool_vdev.c @@ -195,7 +195,7 @@ is_shorthand_path(const char *arg, char *path, size_t path_size, return (0); } - strlcpy(path, arg, path_size); + (void) strlcpy(path, arg, path_size); memset(statbuf, 0, sizeof (*statbuf)); *wholedisk = B_FALSE; @@ -308,7 +308,7 @@ make_leaf_vdev(const char *arg, boolean_t is_primary, uint64_t ashift) } /* After whole disk check restore original passed path */ - strlcpy(path, arg, sizeof (path)); + (void) strlcpy(path, arg, sizeof (path)); } else if (zpool_is_draid_spare(arg)) { if (!is_primary) { (void) fprintf(stderr, @@ -318,7 +318,7 @@ make_leaf_vdev(const char *arg, boolean_t is_primary, uint64_t ashift) } wholedisk = B_TRUE; - strlcpy(path, arg, sizeof (path)); + (void) strlcpy(path, arg, sizeof (path)); type = VDEV_TYPE_DRAID_SPARE; } else { err = is_shorthand_path(arg, path, sizeof (path), @@ -1010,7 +1010,7 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv, boolean_t replacing) * window between when udev deletes and recreates the link * during which access attempts will fail with ENOENT. */ - strlcpy(udevpath, path, MAXPATHLEN); + (void) strlcpy(udevpath, path, MAXPATHLEN); (void) zfs_append_partition(udevpath, MAXPATHLEN); fd = open(devpath, O_RDWR|O_EXCL); diff --git a/sys/contrib/openzfs/cmd/zstream/zstream_redup.c b/sys/contrib/openzfs/cmd/zstream/zstream_redup.c index 0e18c52496fd..c1cb6d4d3ad7 100644 --- a/sys/contrib/openzfs/cmd/zstream/zstream_redup.c +++ b/sys/contrib/openzfs/cmd/zstream/zstream_redup.c @@ -191,9 +191,9 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose) #ifdef _ILP32 uint64_t max_rde_size = SMALLEST_POSSIBLE_MAX_RDT_MB << 20; #else - uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); + uint64_t physbytes = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); uint64_t max_rde_size = - MAX((physmem * MAX_RDT_PHYSMEM_PERCENT) / 100, + MAX((physbytes * MAX_RDT_PHYSMEM_PERCENT) / 100, SMALLEST_POSSIBLE_MAX_RDT_MB << 20); #endif diff --git a/sys/contrib/openzfs/cmd/ztest.c b/sys/contrib/openzfs/cmd/ztest.c index 89752dcb0f0f..dc8ac85b6991 100644 --- a/sys/contrib/openzfs/cmd/ztest.c +++ b/sys/contrib/openzfs/cmd/ztest.c @@ -139,9 +139,10 @@ #include <sys/crypto/icp.h> #include <sys/zfs_impl.h> #include <sys/backtrace.h> +#include <libzpool.h> +#include <libspl.h> static int ztest_fd_data = -1; -static int ztest_fd_rand = -1; typedef struct ztest_shared_hdr { uint64_t zh_hdr_size; @@ -902,13 +903,10 @@ ztest_random(uint64_t range) { uint64_t r; - ASSERT3S(ztest_fd_rand, >=, 0); - if (range == 0) return (0); - if (read(ztest_fd_rand, &r, sizeof (r)) != sizeof (r)) - fatal(B_TRUE, "short read from /dev/urandom"); + random_get_pseudo_bytes((uint8_t *)&r, sizeof (r)); return (r % range); } @@ -1228,10 +1226,10 @@ ztest_kill(ztest_shared_t *zs) * See comment above spa_write_cachefile(). */ if (raidz_expand_pause_point != RAIDZ_EXPAND_PAUSE_NONE) { - if (mutex_tryenter(&spa_namespace_lock)) { + if (spa_namespace_tryenter(FTAG)) { spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE, B_FALSE); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); ztest_scratch_state->zs_raidz_scratch_verify_pause = raidz_expand_pause_point; @@ -1246,9 +1244,9 @@ ztest_kill(ztest_shared_t *zs) return; } } else { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE, B_FALSE); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } (void) raise(SIGKILL); @@ -2306,7 +2304,8 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap) } if (abuf == NULL) { - dmu_write(os, lr->lr_foid, offset, length, data, tx); + dmu_write(os, lr->lr_foid, offset, length, data, tx, + DMU_READ_PREFETCH); } else { memcpy(abuf->b_data, data, length); VERIFY0(dmu_assign_arcbuf_by_dbuf(db, offset, abuf, tx, 0)); @@ -3688,10 +3687,10 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id) if (error == 0) { (void) printf("successful split - results:\n"); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); show_pool_stats(spa); show_pool_stats(spa_lookup("splitp")); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); ++zs->zs_splits; --zs->zs_mirrors; } @@ -3975,11 +3974,11 @@ raidz_scratch_verify(void) kernel_init(SPA_MODE_READ); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa = spa_lookup(ztest_opts.zo_pool); ASSERT(spa); spa->spa_import_flags |= ZFS_IMPORT_SKIP_MMP; - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG)); @@ -5243,7 +5242,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id) * We've verified all the old bufwads, and made new ones. * Now write them out. */ - dmu_write(os, packobj, packoff, packsize, packbuf, tx); + dmu_write(os, packobj, packoff, packsize, packbuf, tx, + DMU_READ_PREFETCH); if (freeit) { if (ztest_opts.zo_verbose >= 7) { @@ -5258,7 +5258,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id) " txg %"PRIx64"\n", bigoff, bigsize, txg); } - dmu_write(os, bigobj, bigoff, bigsize, bigbuf, tx); + dmu_write(os, bigobj, bigoff, bigsize, bigbuf, tx, + DMU_READ_PREFETCH); } dmu_tx_commit(tx); @@ -5513,7 +5514,8 @@ ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id) * We've verified all the old bufwads, and made new ones. * Now write them out. */ - dmu_write(os, packobj, packoff, packsize, packbuf, tx); + dmu_write(os, packobj, packoff, packsize, packbuf, tx, + DMU_READ_PREFETCH); if (ztest_opts.zo_verbose >= 7) { (void) printf("writing offset %"PRIx64" size %"PRIx64"" " txg %"PRIx64"\n", @@ -6119,7 +6121,8 @@ ztest_dmu_commit_callbacks(ztest_ds_t *zd, uint64_t id) "future leak: got %"PRIu64", open txg is %"PRIu64"", old_txg, txg); - dmu_write(os, od->od_object, 0, sizeof (uint64_t), &txg, tx); + dmu_write(os, od->od_object, 0, sizeof (uint64_t), &txg, tx, + DMU_READ_PREFETCH); (void) mutex_enter(&zcl.zcl_callbacks_lock); @@ -7422,11 +7425,11 @@ ztest_walk_pool_directory(const char *header) if (ztest_opts.zo_verbose >= 6) (void) puts(header); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); while ((spa = spa_next(spa)) != NULL) if (ztest_opts.zo_verbose >= 6) (void) printf("\t%s\n", spa_name(spa)); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } static void @@ -8140,10 +8143,8 @@ ztest_raidz_expand_run(ztest_shared_t *zs, spa_t *spa) /* Setup a 1 MiB buffer of random data */ uint64_t bufsize = 1024 * 1024; void *buffer = umem_alloc(bufsize, UMEM_NOFAIL); + random_get_pseudo_bytes((uint8_t *)&buffer, bufsize); - if (read(ztest_fd_rand, buffer, bufsize) != bufsize) { - fatal(B_TRUE, "short read from /dev/urandom"); - } /* * Put some data in the pool and then attach a vdev to initiate * reflow. @@ -8541,11 +8542,11 @@ ztest_run(ztest_shared_t *zs) /* * Verify that we can loop over all pools. */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); for (spa = spa_next(NULL); spa != NULL; spa = spa_next(spa)) if (ztest_opts.zo_verbose > 3) (void) printf("spa_next: found %s\n", spa_name(spa)); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); /* * Verify that we can export the pool and reimport it under a @@ -8949,13 +8950,13 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } + libspl_init(); + /* * Force random_get_bytes() to use /dev/urandom in order to prevent * ztest from needlessly depleting the system entropy pool. */ - random_path = "/dev/urandom"; - ztest_fd_rand = open(random_path, O_RDONLY | O_CLOEXEC); - ASSERT3S(ztest_fd_rand, >=, 0); + random_force_pseudo(B_TRUE); if (!fd_data_str) { process_options(argc, argv); diff --git a/sys/contrib/openzfs/config/Rules.am b/sys/contrib/openzfs/config/Rules.am index deffa352ea24..ecc7ab23cd75 100644 --- a/sys/contrib/openzfs/config/Rules.am +++ b/sys/contrib/openzfs/config/Rules.am @@ -8,9 +8,9 @@ AM_CPPFLAGS = \ -include $(top_builddir)/zfs_config.h \ -I$(top_builddir)/include \ -I$(top_srcdir)/include \ - -I$(top_srcdir)/module/icp/include \ -I$(top_srcdir)/lib/libspl/include \ - -I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@ + -I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@ \ + -I$(top_srcdir)/lib/libzpool/include AM_LIBTOOLFLAGS = --silent diff --git a/sys/contrib/openzfs/config/deb.am b/sys/contrib/openzfs/config/deb.am index 9e58e1905b73..3e9a9379712e 100644 --- a/sys/contrib/openzfs/config/deb.am +++ b/sys/contrib/openzfs/config/deb.am @@ -58,9 +58,9 @@ deb-utils: deb-local rpm-utils-initramfs pkg1=$${name}-$${version}.$${arch}.rpm; \ pkg2=libnvpair3-$${version}.$${arch}.rpm; \ pkg3=libuutil3-$${version}.$${arch}.rpm; \ - pkg4=libzfs6-$${version}.$${arch}.rpm; \ - pkg5=libzpool6-$${version}.$${arch}.rpm; \ - pkg6=libzfs6-devel-$${version}.$${arch}.rpm; \ + pkg4=libzfs7-$${version}.$${arch}.rpm; \ + pkg5=libzpool7-$${version}.$${arch}.rpm; \ + pkg6=libzfs7-devel-$${version}.$${arch}.rpm; \ pkg7=$${name}-test-$${version}.$${arch}.rpm; \ pkg8=$${name}-dracut-$${version}.noarch.rpm; \ pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \ @@ -72,7 +72,7 @@ deb-utils: deb-local rpm-utils-initramfs path_prepend=`mktemp -d /tmp/intercept.XXXXXX`; \ echo "#!$(SHELL)" > $${path_prepend}/dh_shlibdeps; \ echo "`which dh_shlibdeps` -- \ - -xlibuutil3linux -xlibnvpair3linux -xlibzfs6linux -xlibzpool6linux" \ + -xlibuutil3linux -xlibnvpair3linux -xlibzfs7linux -xlibzpool7linux" \ >> $${path_prepend}/dh_shlibdeps; \ ## These -x arguments are passed to dpkg-shlibdeps, which exclude the ## Debianized packages from the auto-generated dependencies of the new debs, diff --git a/sys/contrib/openzfs/contrib/debian/Makefile.am b/sys/contrib/openzfs/contrib/debian/Makefile.am index 99d512312df6..3c219856005e 100644 --- a/sys/contrib/openzfs/contrib/debian/Makefile.am +++ b/sys/contrib/openzfs/contrib/debian/Makefile.am @@ -12,14 +12,14 @@ dist_noinst_DATA += %D%/openzfs-libpam-zfs.postinst dist_noinst_DATA += %D%/openzfs-libpam-zfs.prerm dist_noinst_DATA += %D%/openzfs-libuutil3.docs dist_noinst_DATA += %D%/openzfs-libuutil3.install.in -dist_noinst_DATA += %D%/openzfs-libzfs6.docs -dist_noinst_DATA += %D%/openzfs-libzfs6.install.in +dist_noinst_DATA += %D%/openzfs-libzfs7.docs +dist_noinst_DATA += %D%/openzfs-libzfs7.install.in dist_noinst_DATA += %D%/openzfs-libzfsbootenv1.docs dist_noinst_DATA += %D%/openzfs-libzfsbootenv1.install.in dist_noinst_DATA += %D%/openzfs-libzfs-dev.docs dist_noinst_DATA += %D%/openzfs-libzfs-dev.install.in -dist_noinst_DATA += %D%/openzfs-libzpool6.docs -dist_noinst_DATA += %D%/openzfs-libzpool6.install.in +dist_noinst_DATA += %D%/openzfs-libzpool7.docs +dist_noinst_DATA += %D%/openzfs-libzpool7.install.in dist_noinst_DATA += %D%/openzfs-python3-pyzfs.install dist_noinst_DATA += %D%/openzfs-zfs-dkms.config dist_noinst_DATA += %D%/openzfs-zfs-dkms.dkms diff --git a/sys/contrib/openzfs/contrib/debian/clean b/sys/contrib/openzfs/contrib/debian/clean index 4f52d01b8108..caabcd30c62a 100644 --- a/sys/contrib/openzfs/contrib/debian/clean +++ b/sys/contrib/openzfs/contrib/debian/clean @@ -6,6 +6,6 @@ contrib/pyzfs/libzfs_core/bindings/__pycache__/ contrib/pyzfs/pyzfs.egg-info/ debian/openzfs-libnvpair3.install debian/openzfs-libuutil3.install -debian/openzfs-libzfs6.install +debian/openzfs-libzfs7.install debian/openzfs-libzfs-dev.install -debian/openzfs-libzpool6.install +debian/openzfs-libzpool7.install diff --git a/sys/contrib/openzfs/contrib/debian/control b/sys/contrib/openzfs/contrib/debian/control index c5358dedc0fd..a886c2e86cc5 100644 --- a/sys/contrib/openzfs/contrib/debian/control +++ b/sys/contrib/openzfs/contrib/debian/control @@ -79,9 +79,9 @@ Architecture: linux-any Depends: libssl-dev | libssl1.0-dev, openzfs-libnvpair3 (= ${binary:Version}), openzfs-libuutil3 (= ${binary:Version}), - openzfs-libzfs6 (= ${binary:Version}), + openzfs-libzfs7 (= ${binary:Version}), openzfs-libzfsbootenv1 (= ${binary:Version}), - openzfs-libzpool6 (= ${binary:Version}), + openzfs-libzpool7 (= ${binary:Version}), ${misc:Depends} Replaces: libzfslinux-dev Conflicts: libzfslinux-dev @@ -91,18 +91,18 @@ Description: OpenZFS filesystem development files for Linux libraries of OpenZFS filesystem. . This package includes the development files of libnvpair3, libuutil3, - libzpool6 and libzfs6. + libzpool7 and libzfs7. -Package: openzfs-libzfs6 +Package: openzfs-libzfs7 Section: contrib/libs Architecture: linux-any Depends: ${misc:Depends}, ${shlibs:Depends} # The libcurl4 is loaded through dlopen("libcurl.so.4"). # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=988521 Recommends: libcurl4 -Breaks: libzfs2, libzfs4, libzfs4linux, libzfs6linux, openzfs-libzfs4 -Replaces: libzfs2, libzfs4, libzfs4linux, libzfs6linux, openzfs-libzfs4 -Conflicts: libzfs6linux +Breaks: libzfs2, libzfs4, libzfs4linux, libzfs6linux, libzfs7linux, openzfs-libzfs4, openzfs-libzfs6 +Replaces: libzfs2, libzfs4, libzfs4linux, libzfs6linux, libzfs7linux, openzfs-libzfs4, openzfs-libzfs6 +Conflicts: libzfs7linux Description: OpenZFS filesystem library for Linux - general support OpenZFS is a storage platform that encompasses the functionality of traditional filesystems and volume managers. It supports data checksums, @@ -124,13 +124,13 @@ Description: OpenZFS filesystem library for Linux - label info support . The zfsbootenv library provides support for modifying ZFS label information. -Package: openzfs-libzpool6 +Package: openzfs-libzpool7 Section: contrib/libs Architecture: linux-any Depends: ${misc:Depends}, ${shlibs:Depends} -Breaks: libzpool2, libzpool5, libzpool6linux -Replaces: libzpool2, libzpool5, libzpool6linux -Conflicts: libzpool6linux +Breaks: libzpool2, libzpool5, libzpool6linux, libzpool7linux +Replaces: libzpool2, libzpool5, libzpool6linux, libzpool7linux +Conflicts: libzpool7linux Description: OpenZFS pool library for Linux OpenZFS is a storage platform that encompasses the functionality of traditional filesystems and volume managers. It supports data checksums, @@ -247,8 +247,8 @@ Architecture: linux-any Pre-Depends: ${misc:Pre-Depends} Depends: openzfs-libnvpair3 (= ${binary:Version}), openzfs-libuutil3 (= ${binary:Version}), - openzfs-libzfs6 (= ${binary:Version}), - openzfs-libzpool6 (= ${binary:Version}), + openzfs-libzfs7 (= ${binary:Version}), + openzfs-libzpool7 (= ${binary:Version}), python3, ${misc:Depends}, ${shlibs:Depends} diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs6.docs b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs7.docs index 4302f1b2ab6a..4302f1b2ab6a 100644 --- a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs6.docs +++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs7.docs diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs6.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs7.install.in index a9054c14cc73..a9054c14cc73 100644 --- a/sys/contrib/openzfs/contrib/debian/openzfs-libzfs6.install.in +++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzfs7.install.in diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzpool6.docs b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool7.docs index 4302f1b2ab6a..4302f1b2ab6a 100644 --- a/sys/contrib/openzfs/contrib/debian/openzfs-libzpool6.docs +++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool7.docs diff --git a/sys/contrib/openzfs/contrib/debian/openzfs-libzpool6.install.in b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool7.install.in index 0e087a2709b3..0e087a2709b3 100644 --- a/sys/contrib/openzfs/contrib/debian/openzfs-libzpool6.install.in +++ b/sys/contrib/openzfs/contrib/debian/openzfs-libzpool7.install.in diff --git a/sys/contrib/openzfs/include/Makefile.am b/sys/contrib/openzfs/include/Makefile.am index 7588cd0aedc9..42457519e746 100644 --- a/sys/contrib/openzfs/include/Makefile.am +++ b/sys/contrib/openzfs/include/Makefile.am @@ -191,6 +191,7 @@ USER_H = \ libzfs.h \ libzfs_core.h \ libzfsbootenv.h \ + libzpool.h \ libzutil.h \ thread_pool.h diff --git a/sys/contrib/openzfs/include/libzpool.h b/sys/contrib/openzfs/include/libzpool.h new file mode 100644 index 000000000000..95991e68116e --- /dev/null +++ b/sys/contrib/openzfs/include/libzpool.h @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _LIBZPOOL_H +#define _LIBZPOOL_H extern __attribute__((visibility("default"))) + +#include <sys/zfs_context.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern char *vn_dumpdir; + +_LIBZPOOL_H void kernel_init(int mode); +_LIBZPOOL_H void kernel_fini(void); + +struct spa; +_LIBZPOOL_H void show_pool_stats(struct spa *); +_LIBZPOOL_H int handle_tunable_option(const char *, boolean_t); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sys/contrib/openzfs/include/libzutil.h b/sys/contrib/openzfs/include/libzutil.h index 001ece2280f6..59599b0f63f4 100644 --- a/sys/contrib/openzfs/include/libzutil.h +++ b/sys/contrib/openzfs/include/libzutil.h @@ -165,6 +165,7 @@ _LIBZUTIL_H void zfs_nicetime(uint64_t, char *, size_t); _LIBZUTIL_H void zfs_niceraw(uint64_t, char *, size_t); #define nicenum(num, buf, size) zfs_nicenum(num, buf, size) +#define NN_NUMBUF_SZ (6) _LIBZUTIL_H void zpool_dump_ddt(const ddt_stat_t *, const ddt_histogram_t *); _LIBZUTIL_H int zpool_history_unpack(char *, uint64_t, uint64_t *, nvlist_t ***, diff --git a/sys/contrib/openzfs/include/os/freebsd/Makefile.am b/sys/contrib/openzfs/include/os/freebsd/Makefile.am index d6b6923d033f..47cf6756ab7d 100644 --- a/sys/contrib/openzfs/include/os/freebsd/Makefile.am +++ b/sys/contrib/openzfs/include/os/freebsd/Makefile.am @@ -44,7 +44,6 @@ noinst_HEADERS = \ %D%/spl/sys/procfs_list.h \ %D%/spl/sys/random.h \ %D%/spl/sys/rwlock.h \ - %D%/spl/sys/sdt.h \ %D%/spl/sys/sid.h \ %D%/spl/sys/sig.h \ %D%/spl/sys/simd.h \ @@ -63,7 +62,6 @@ noinst_HEADERS = \ %D%/spl/sys/time.h \ %D%/spl/sys/timer.h \ %D%/spl/sys/trace.h \ - %D%/spl/sys/trace_zfs.h \ %D%/spl/sys/types.h \ %D%/spl/sys/types32.h \ %D%/spl/sys/uio.h \ @@ -82,10 +80,12 @@ noinst_HEADERS = \ %D%/zfs/sys/arc_os.h \ %D%/zfs/sys/freebsd_crypto.h \ %D%/zfs/sys/freebsd_event.h \ + %D%/zfs/sys/trace_zfs.h \ %D%/zfs/sys/vdev_os.h \ %D%/zfs/sys/zfs_bootenv_os.h \ %D%/zfs/sys/zfs_context_os.h \ %D%/zfs/sys/zfs_ctldir.h \ + %D%/zfs/sys/zfs_debug_os.h \ %D%/zfs/sys/zfs_dir.h \ %D%/zfs/sys/zfs_ioctl_compat.h \ %D%/zfs/sys/zfs_vfsops_os.h \ diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod.h b/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod.h index 4214189c32df..2aa66bbe19b7 100644 --- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod.h +++ b/sys/contrib/openzfs/include/os/freebsd/spl/sys/mod.h @@ -104,6 +104,9 @@ #define spa_taskq_write_param_set_args(var) \ CTLTYPE_STRING, NULL, 0, spa_taskq_write_param, "A" +#define spa_taskq_free_param_set_args(var) \ + CTLTYPE_STRING, NULL, 0, spa_taskq_free_param, "A" + #define fletcher_4_param_set_args(var) \ CTLTYPE_STRING, NULL, 0, fletcher_4_param, "A" diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/trace_zfs.h b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/trace_zfs.h index d9639d27b60e..d9639d27b60e 100644 --- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/trace_zfs.h +++ b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/trace_zfs.h diff --git a/sys/contrib/openzfs/include/os/freebsd/spl/sys/sdt.h b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_debug_os.h index ef1dad6c14c9..cc7540c4f83c 100644 --- a/sys/contrib/openzfs/include/os/freebsd/spl/sys/sdt.h +++ b/sys/contrib/openzfs/include/os/freebsd/zfs/sys/zfs_debug_os.h @@ -27,10 +27,11 @@ * $FreeBSD$ */ -#ifndef _OPENSOLARIS_SYS_SDT_H_ -#define _OPENSOLARIS_SYS_SDT_H_ +#ifndef _SYS_ZFS_DEBUG_OS_H +#define _SYS_ZFS_DEBUG_OS_H + +#include <sys/sdt.h> -#include_next <sys/sdt.h> #ifdef KDTRACE_HOOKS SDT_PROBE_DECLARE(sdt, , , set__error); @@ -44,4 +45,4 @@ SDT_PROBE_DECLARE(sdt, , , set__error); #define SET_ERROR(err) (err) #endif -#endif /* _OPENSOLARIS_SYS_SDT_H_ */ +#endif /* _SYS_ZFS_DEBUG_OS_H */ diff --git a/sys/contrib/openzfs/include/os/linux/Makefile.am b/sys/contrib/openzfs/include/os/linux/Makefile.am index e156ca183dbd..9188a974cc22 100644 --- a/sys/contrib/openzfs/include/os/linux/Makefile.am +++ b/sys/contrib/openzfs/include/os/linux/Makefile.am @@ -41,6 +41,7 @@ kernel_sys_HEADERS = \ %D%/zfs/sys/zfs_bootenv_os.h \ %D%/zfs/sys/zfs_context_os.h \ %D%/zfs/sys/zfs_ctldir.h \ + %D%/zfs/sys/zfs_debug_os.h \ %D%/zfs/sys/zfs_dir.h \ %D%/zfs/sys/zfs_vfsops_os.h \ %D%/zfs/sys/zfs_vnops_os.h \ @@ -97,7 +98,6 @@ kernel_spl_sys_HEADERS = \ %D%/spl/sys/time.h \ %D%/spl/sys/timer.h \ %D%/spl/sys/trace.h \ - %D%/spl/sys/trace_spl.h \ %D%/spl/sys/trace_taskq.h \ %D%/spl/sys/tsd.h \ %D%/spl/sys/types.h \ diff --git a/sys/contrib/openzfs/include/os/linux/spl/sys/sysmacros.h b/sys/contrib/openzfs/include/os/linux/spl/sys/sysmacros.h index db48222b712a..dc9e9e492ae4 100644 --- a/sys/contrib/openzfs/include/os/linux/spl/sys/sysmacros.h +++ b/sys/contrib/openzfs/include/os/linux/spl/sys/sysmacros.h @@ -34,11 +34,6 @@ #include <sys/signal.h> #include <asm/page.h> - -#ifndef _KERNEL -#define _KERNEL __KERNEL__ -#endif - #define FALSE 0 #define TRUE 1 @@ -202,9 +197,6 @@ makedev(unsigned int major, unsigned int minor) #define P2SAMEHIGHBIT_TYPED(x, y, type) \ (((type)(x) ^ (type)(y)) < ((type)(x) & (type)(y))) -#define SET_ERROR(err) \ - (__set_error(__FILE__, __func__, __LINE__, err), err) - #include <linux/sort.h> #define qsort(base, num, size, cmp) \ sort(base, num, size, cmp, NULL) diff --git a/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_debug_os.h b/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_debug_os.h new file mode 100644 index 000000000000..2841809528b6 --- /dev/null +++ b/sys/contrib/openzfs/include/os/linux/zfs/sys/zfs_debug_os.h @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +#ifndef _SYS_ZFS_DEBUG_OS_H +#define _SYS_ZFS_DEBUG_OS_H + +#define SET_ERROR(err) \ + (__set_error(__FILE__, __func__, __LINE__, err), err) + +#endif /* _SYS_ZFS_DEBUG_OS_H */ diff --git a/sys/contrib/openzfs/include/sys/brt.h b/sys/contrib/openzfs/include/sys/brt.h index d7c1814b084f..2a23a6a7f75d 100644 --- a/sys/contrib/openzfs/include/sys/brt.h +++ b/sys/contrib/openzfs/include/sys/brt.h @@ -56,6 +56,7 @@ extern void brt_create(spa_t *spa); extern int brt_load(spa_t *spa); extern void brt_unload(spa_t *spa); extern void brt_sync(spa_t *spa, uint64_t txg); +extern void brt_prefetch_all(spa_t *spa); #ifdef __cplusplus } diff --git a/sys/contrib/openzfs/include/sys/brt_impl.h b/sys/contrib/openzfs/include/sys/brt_impl.h index 1805d21b16b2..1843e6d988cd 100644 --- a/sys/contrib/openzfs/include/sys/brt_impl.h +++ b/sys/contrib/openzfs/include/sys/brt_impl.h @@ -65,7 +65,7 @@ _Static_assert(BRT_RANGESIZE / SPA_MINBLOCKSIZE <= UINT16_MAX, */ #define BRT_BLOCKSIZE (32 * 1024) #define BRT_RANGESIZE_TO_NBLOCKS(size) \ - (((size) - 1) / BRT_BLOCKSIZE / sizeof (uint16_t) + 1) + (((size) - 1) / (BRT_BLOCKSIZE / sizeof (uint16_t)) + 1) #define BRT_LITTLE_ENDIAN 0 #define BRT_BIG_ENDIAN 1 diff --git a/sys/contrib/openzfs/include/sys/crypto/common.h b/sys/contrib/openzfs/include/sys/crypto/common.h index 4a9b4f0e1f76..2428fb2737a0 100644 --- a/sys/contrib/openzfs/include/sys/crypto/common.h +++ b/sys/contrib/openzfs/include/sys/crypto/common.h @@ -38,6 +38,8 @@ extern "C" { #endif #include <sys/zfs_context.h> +#include <sys/types.h> +#include <sys/uio.h> /* Cryptographic Mechanisms */ diff --git a/sys/contrib/openzfs/include/sys/dmu.h b/sys/contrib/openzfs/include/sys/dmu.h index aa5035862def..aae99d71ba7c 100644 --- a/sys/contrib/openzfs/include/sys/dmu.h +++ b/sys/contrib/openzfs/include/sys/dmu.h @@ -126,7 +126,7 @@ typedef enum dmu_object_byteswap { (ot) < DMU_OT_NUMTYPES) #define DMU_OT_IS_METADATA_CACHED(ot) (((ot) & DMU_OT_NEWTYPE) ? \ - B_TRUE : dmu_ot[(ot)].ot_dbuf_metadata_cache) + ((ot) & DMU_OT_METADATA) != 0 : dmu_ot[(ot)].ot_dbuf_metadata_cache) /* * MDB doesn't have dmu_ot; it defines these macros itself. @@ -625,7 +625,7 @@ int dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset, const void *tag, dmu_buf_t **, dmu_flags_t flags); int dmu_buf_hold_array(objset_t *os, uint64_t object, uint64_t offset, uint64_t length, int read, const void *tag, int *numbufsp, - dmu_buf_t ***dbpp); + dmu_buf_t ***dbpp, dmu_flags_t flags); int dmu_buf_hold_noread(objset_t *os, uint64_t object, uint64_t offset, const void *tag, dmu_buf_t **dbp); int dmu_buf_hold_by_dnode(dnode_t *dn, uint64_t offset, @@ -668,7 +668,7 @@ uint64_t dmu_buf_user_refcount(dmu_buf_t *db); */ int dmu_buf_hold_array_by_bonus(dmu_buf_t *db, uint64_t offset, uint64_t length, boolean_t read, const void *tag, - int *numbufsp, dmu_buf_t ***dbpp); + int *numbufsp, dmu_buf_t ***dbpp, dmu_flags_t flags); void dmu_buf_rele_array(dmu_buf_t **, int numbufs, const void *tag); typedef void dmu_buf_evict_func_t(void *user_ptr); @@ -924,7 +924,7 @@ int dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, int dmu_read_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size, void *buf, dmu_flags_t flags); void dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, - const void *buf, dmu_tx_t *tx); + const void *buf, dmu_tx_t *tx, dmu_flags_t flags); int dmu_write_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size, const void *buf, dmu_tx_t *tx, dmu_flags_t flags); void dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, diff --git a/sys/contrib/openzfs/include/sys/fs/zfs.h b/sys/contrib/openzfs/include/sys/fs/zfs.h index 662fd81c5ee1..830c8455bb1a 100644 --- a/sys/contrib/openzfs/include/sys/fs/zfs.h +++ b/sys/contrib/openzfs/include/sys/fs/zfs.h @@ -387,6 +387,7 @@ typedef enum { VDEV_PROP_SLOW_IOS, VDEV_PROP_SIT_OUT, VDEV_PROP_AUTOSIT, + VDEV_PROP_SLOW_IO_EVENTS, VDEV_NUM_PROPS } vdev_prop_t; @@ -1713,7 +1714,8 @@ typedef enum { typedef enum { ZPOOL_PREFETCH_NONE = 0, - ZPOOL_PREFETCH_DDT + ZPOOL_PREFETCH_DDT, + ZPOOL_PREFETCH_BRT } zpool_prefetch_type_t; typedef enum { diff --git a/sys/contrib/openzfs/include/sys/spa.h b/sys/contrib/openzfs/include/sys/spa.h index f172f2af6f07..2a4cc60c4aa8 100644 --- a/sys/contrib/openzfs/include/sys/spa.h +++ b/sys/contrib/openzfs/include/sys/spa.h @@ -29,7 +29,7 @@ * Copyright 2017 Joyent, Inc. * Copyright (c) 2017, Intel Corporation. * Copyright (c) 2019, Allan Jude - * Copyright (c) 2019, Klara Inc. + * Copyright (c) 2019, 2025, Klara, Inc. * Copyright (c) 2019, Datto Inc. */ @@ -867,10 +867,14 @@ uint_t spa_acq_allocator(spa_t *spa); void spa_rel_allocator(spa_t *spa, uint_t allocator); void spa_select_allocator(zio_t *zio); -/* spa namespace global mutex */ -extern kmutex_t spa_namespace_lock; -extern avl_tree_t spa_namespace_avl; -extern kcondvar_t spa_namespace_cv; +/* spa namespace global lock */ +extern void spa_namespace_enter(const void *tag); +extern boolean_t spa_namespace_tryenter(const void *tag); +extern int spa_namespace_enter_interruptible(const void *tag); +extern void spa_namespace_exit(const void *tag); +extern boolean_t spa_namespace_held(void); +extern void spa_namespace_wait(void); +extern void spa_namespace_broadcast(void); /* * SPA configuration functions in spa_config.c diff --git a/sys/contrib/openzfs/include/sys/vdev_impl.h b/sys/contrib/openzfs/include/sys/vdev_impl.h index 5a8c2f846be2..afaa401343d9 100644 --- a/sys/contrib/openzfs/include/sys/vdev_impl.h +++ b/sys/contrib/openzfs/include/sys/vdev_impl.h @@ -470,6 +470,7 @@ struct vdev { uint64_t vdev_checksum_t; uint64_t vdev_io_n; uint64_t vdev_io_t; + boolean_t vdev_slow_io_events; uint64_t vdev_slow_io_n; uint64_t vdev_slow_io_t; }; diff --git a/sys/contrib/openzfs/include/sys/zfs_acl.h b/sys/contrib/openzfs/include/sys/zfs_acl.h index 753a128873d5..f9afee372c94 100644 --- a/sys/contrib/openzfs/include/sys/zfs_acl.h +++ b/sys/contrib/openzfs/include/sys/zfs_acl.h @@ -29,8 +29,8 @@ #ifdef _KERNEL #include <sys/isa_defs.h> #include <sys/types32.h> -#include <sys/xvattr.h> #endif +#include <sys/xvattr.h> #include <sys/acl.h> #include <sys/dmu.h> #include <sys/zfs_fuid.h> diff --git a/sys/contrib/openzfs/include/sys/zfs_bootenv.h b/sys/contrib/openzfs/include/sys/zfs_bootenv.h index 074e7e759576..4c4b2ab1ab1b 100644 --- a/sys/contrib/openzfs/include/sys/zfs_bootenv.h +++ b/sys/contrib/openzfs/include/sys/zfs_bootenv.h @@ -31,6 +31,7 @@ extern "C" { #define BE_FREEBSD_VENDOR "freebsd" #define BE_GRUB_VENDOR "grub" #define BE_LINUX_VENDOR "linux" +#define BE_POSIX_VENDOR "posix" #include <sys/zfs_bootenv_os.h> diff --git a/sys/contrib/openzfs/include/sys/zfs_context.h b/sys/contrib/openzfs/include/sys/zfs_context.h index 7112d3ef5c99..5e571d497642 100644 --- a/sys/contrib/openzfs/include/sys/zfs_context.h +++ b/sys/contrib/openzfs/include/sys/zfs_context.h @@ -77,14 +77,6 @@ extern "C" { #include <sys/zfs_context_os.h> #else /* _KERNEL || _STANDALONE */ -#define _SYS_MUTEX_H -#define _SYS_RWLOCK_H -#define _SYS_CONDVAR_H -#define _SYS_VNODE_H -#define _SYS_VFS_H -#define _SYS_SUNDDI_H -#define _SYS_CALLB_H - #include <stdio.h> #include <stdlib.h> #include <stddef.h> @@ -93,10 +85,8 @@ extern "C" { #include <unistd.h> #include <errno.h> #include <string.h> -#include <pthread.h> #include <setjmp.h> #include <assert.h> -#include <umem.h> #include <limits.h> #include <atomic.h> #include <dirent.h> @@ -119,666 +109,26 @@ extern "C" { #include <sys/sysevent/eventdefs.h> #include <sys/sunddi.h> #include <sys/debug.h> -#include <sys/utsname.h> -#include <sys/trace_zfs.h> - -#include <sys/zfs_context_os.h> - -/* - * Stack - */ - -#define noinline __attribute__((noinline)) -#define likely(x) __builtin_expect((x), 1) -#define unlikely(x) __builtin_expect((x), 0) - -/* - * Debugging - */ - -/* - * Note that we are not using the debugging levels. - */ - -#define CE_CONT 0 /* continuation */ -#define CE_NOTE 1 /* notice */ -#define CE_WARN 2 /* warning */ -#define CE_PANIC 3 /* panic */ -#define CE_IGNORE 4 /* print nothing */ - -/* - * ZFS debugging - */ - -extern void dprintf_setup(int *argc, char **argv); - -extern void cmn_err(int, const char *, ...) - __attribute__((format(printf, 2, 3))); -extern void vcmn_err(int, const char *, va_list) - __attribute__((format(printf, 2, 0))); -extern void panic(const char *, ...) - __attribute__((format(printf, 1, 2), noreturn)); -extern void vpanic(const char *, va_list) - __attribute__((format(printf, 1, 0), noreturn)); - -#define fm_panic panic - -/* - * DTrace SDT probes have different signatures in userland than they do in - * the kernel. If they're being used in kernel code, re-define them out of - * existence for their counterparts in libzpool. - * - * Here's an example of how to use the set-error probes in userland: - * zfs$target:::set-error /arg0 == EBUSY/ {stack();} - * - * Here's an example of how to use DTRACE_PROBE probes in userland: - * If there is a probe declared as follows: - * DTRACE_PROBE2(zfs__probe_name, uint64_t, blkid, dnode_t *, dn); - * Then you can use it as follows: - * zfs$target:::probe2 /copyinstr(arg0) == "zfs__probe_name"/ - * {printf("%u %p\n", arg1, arg2);} - */ - -#ifdef DTRACE_PROBE -#undef DTRACE_PROBE -#endif /* DTRACE_PROBE */ -#define DTRACE_PROBE(a) - -#ifdef DTRACE_PROBE1 -#undef DTRACE_PROBE1 -#endif /* DTRACE_PROBE1 */ -#define DTRACE_PROBE1(a, b, c) - -#ifdef DTRACE_PROBE2 -#undef DTRACE_PROBE2 -#endif /* DTRACE_PROBE2 */ -#define DTRACE_PROBE2(a, b, c, d, e) - -#ifdef DTRACE_PROBE3 -#undef DTRACE_PROBE3 -#endif /* DTRACE_PROBE3 */ -#define DTRACE_PROBE3(a, b, c, d, e, f, g) - -#ifdef DTRACE_PROBE4 -#undef DTRACE_PROBE4 -#endif /* DTRACE_PROBE4 */ -#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i) - -/* - * Threads. - */ -typedef pthread_t kthread_t; - -#define TS_RUN 0x00000002 -#define TS_JOINABLE 0x00000004 - -#define curthread ((void *)(uintptr_t)pthread_self()) -#define getcomm() "unknown" - -#define thread_create_named(name, stk, stksize, func, arg, len, \ - pp, state, pri) \ - zk_thread_create(name, func, arg, stksize, state) -#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \ - zk_thread_create(#func, func, arg, stksize, state) -#define thread_exit() pthread_exit(NULL) -#define thread_join(t) pthread_join((pthread_t)(t), NULL) - -#define newproc(f, a, cid, pri, ctp, pid) (ENOSYS) -/* - * Check if the current thread is a memory reclaim thread. - * Always returns false in userspace (no memory reclaim thread). - */ -#define current_is_reclaim_thread() (0) - -/* in libzpool, p0 exists only to have its address taken */ -typedef struct proc { - uintptr_t this_is_never_used_dont_dereference_it; -} proc_t; - -extern struct proc p0; -#define curproc (&p0) - -#define PS_NONE -1 - -extern kthread_t *zk_thread_create(const char *name, void (*func)(void *), - void *arg, size_t stksize, int state); - -#define issig() (FALSE) - -#define KPREEMPT_SYNC (-1) - -#define kpreempt(x) sched_yield() -#define kpreempt_disable() ((void)0) -#define kpreempt_enable() ((void)0) - -/* - * Mutexes - */ -typedef struct kmutex { - pthread_mutex_t m_lock; - pthread_t m_owner; -} kmutex_t; - -#define MUTEX_DEFAULT 0 -#define MUTEX_NOLOCKDEP MUTEX_DEFAULT -#define MUTEX_HELD(mp) pthread_equal((mp)->m_owner, pthread_self()) -#define MUTEX_NOT_HELD(mp) !MUTEX_HELD(mp) - -extern void mutex_init(kmutex_t *mp, char *name, int type, void *cookie); -extern void mutex_destroy(kmutex_t *mp); -extern void mutex_enter(kmutex_t *mp); -extern int mutex_enter_check_return(kmutex_t *mp); -extern void mutex_exit(kmutex_t *mp); -extern int mutex_tryenter(kmutex_t *mp); - -#define NESTED_SINGLE 1 -#define mutex_enter_nested(mp, class) mutex_enter(mp) -#define mutex_enter_interruptible(mp) mutex_enter_check_return(mp) -/* - * RW locks - */ -typedef struct krwlock { - pthread_rwlock_t rw_lock; - pthread_t rw_owner; - uint_t rw_readers; -} krwlock_t; - -typedef int krw_t; - -#define RW_READER 0 -#define RW_WRITER 1 -#define RW_DEFAULT RW_READER -#define RW_NOLOCKDEP RW_READER - -#define RW_READ_HELD(rw) ((rw)->rw_readers > 0) -#define RW_WRITE_HELD(rw) pthread_equal((rw)->rw_owner, pthread_self()) -#define RW_LOCK_HELD(rw) (RW_READ_HELD(rw) || RW_WRITE_HELD(rw)) - -extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg); -extern void rw_destroy(krwlock_t *rwlp); -extern void rw_enter(krwlock_t *rwlp, krw_t rw); -extern int rw_tryenter(krwlock_t *rwlp, krw_t rw); -extern int rw_tryupgrade(krwlock_t *rwlp); -extern void rw_exit(krwlock_t *rwlp); -#define rw_downgrade(rwlp) do { } while (0) - -/* - * Credentials - */ -extern uid_t crgetuid(cred_t *cr); -extern uid_t crgetruid(cred_t *cr); -extern gid_t crgetgid(cred_t *cr); -extern int crgetngroups(cred_t *cr); -extern gid_t *crgetgroups(cred_t *cr); - -/* - * Condition variables - */ -typedef pthread_cond_t kcondvar_t; - -#define CV_DEFAULT 0 -#define CALLOUT_FLAG_ABSOLUTE 0x2 - -extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg); -extern void cv_destroy(kcondvar_t *cv); -extern void cv_wait(kcondvar_t *cv, kmutex_t *mp); -extern int cv_wait_sig(kcondvar_t *cv, kmutex_t *mp); -extern int cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime); -extern int cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, - hrtime_t res, int flag); -extern void cv_signal(kcondvar_t *cv); -extern void cv_broadcast(kcondvar_t *cv); - -#define cv_timedwait_io(cv, mp, at) cv_timedwait(cv, mp, at) -#define cv_timedwait_idle(cv, mp, at) cv_timedwait(cv, mp, at) -#define cv_timedwait_sig(cv, mp, at) cv_timedwait(cv, mp, at) -#define cv_wait_io(cv, mp) cv_wait(cv, mp) -#define cv_wait_idle(cv, mp) cv_wait(cv, mp) -#define cv_wait_io_sig(cv, mp) cv_wait_sig(cv, mp) -#define cv_timedwait_sig_hires(cv, mp, t, r, f) \ - cv_timedwait_hires(cv, mp, t, r, f) -#define cv_timedwait_idle_hires(cv, mp, t, r, f) \ - cv_timedwait_hires(cv, mp, t, r, f) - -/* - * Thread-specific data - */ -#define tsd_get(k) pthread_getspecific(k) -#define tsd_set(k, v) pthread_setspecific(k, v) -#define tsd_create(kp, d) pthread_key_create((pthread_key_t *)kp, d) -#define tsd_destroy(kp) /* nothing */ -#ifdef __FreeBSD__ -typedef off_t loff_t; -#endif - -/* - * kstat creation, installation and deletion - */ -extern kstat_t *kstat_create(const char *, int, - const char *, const char *, uchar_t, ulong_t, uchar_t); -extern void kstat_install(kstat_t *); -extern void kstat_delete(kstat_t *); -extern void kstat_set_raw_ops(kstat_t *ksp, - int (*headers)(char *buf, size_t size), - int (*data)(char *buf, size_t size, void *data), - void *(*addr)(kstat_t *ksp, loff_t index)); - -/* - * procfs list manipulation - */ - -typedef struct procfs_list { - void *pl_private; - kmutex_t pl_lock; - list_t pl_list; - uint64_t pl_next_id; - size_t pl_node_offset; -} procfs_list_t; - -#ifndef __cplusplus -struct seq_file { }; -void seq_printf(struct seq_file *m, const char *fmt, ...); - -typedef struct procfs_list_node { - list_node_t pln_link; - uint64_t pln_id; -} procfs_list_node_t; - -void procfs_list_install(const char *module, - const char *submodule, - const char *name, - mode_t mode, - procfs_list_t *procfs_list, - int (*show)(struct seq_file *f, void *p), - int (*show_header)(struct seq_file *f), - int (*clear)(procfs_list_t *procfs_list), - size_t procfs_list_node_off); -void procfs_list_uninstall(procfs_list_t *procfs_list); -void procfs_list_destroy(procfs_list_t *procfs_list); -void procfs_list_add(procfs_list_t *procfs_list, void *p); -#endif - -/* - * Kernel memory - */ -#define KM_SLEEP UMEM_NOFAIL -#define KM_PUSHPAGE KM_SLEEP -#define KM_NOSLEEP UMEM_DEFAULT -#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */ -#define KMC_NODEBUG UMC_NODEBUG -#define KMC_KVMEM 0x0 -#define KMC_RECLAIMABLE 0x0 -#define kmem_alloc(_s, _f) umem_alloc(_s, _f) -#define kmem_zalloc(_s, _f) umem_zalloc(_s, _f) -#define kmem_free(_b, _s) umem_free(_b, _s) -#define vmem_alloc(_s, _f) kmem_alloc(_s, _f) -#define vmem_zalloc(_s, _f) kmem_zalloc(_s, _f) -#define vmem_free(_b, _s) kmem_free(_b, _s) -#define kmem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) \ - umem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) -#define kmem_cache_destroy(_c) umem_cache_destroy(_c) -#define kmem_cache_alloc(_c, _f) umem_cache_alloc(_c, _f) -#define kmem_cache_free(_c, _b) umem_cache_free(_c, _b) -#define kmem_debugging() 0 -#define kmem_cache_reap_now(_c) umem_cache_reap_now(_c); -#define kmem_cache_set_move(_c, _cb) /* nothing */ -#define POINTER_INVALIDATE(_pp) /* nothing */ -#define POINTER_IS_VALID(_p) 0 - -typedef umem_cache_t kmem_cache_t; - -typedef enum kmem_cbrc { - KMEM_CBRC_YES, - KMEM_CBRC_NO, - KMEM_CBRC_LATER, - KMEM_CBRC_DONT_NEED, - KMEM_CBRC_DONT_KNOW -} kmem_cbrc_t; - -/* - * Task queues - */ - -#define TASKQ_NAMELEN 31 - -typedef uintptr_t taskqid_t; -typedef void (task_func_t)(void *); - -typedef struct taskq_ent { - struct taskq_ent *tqent_next; - struct taskq_ent *tqent_prev; - task_func_t *tqent_func; - void *tqent_arg; - uintptr_t tqent_flags; -} taskq_ent_t; - -typedef struct taskq { - char tq_name[TASKQ_NAMELEN + 1]; - kmutex_t tq_lock; - krwlock_t tq_threadlock; - kcondvar_t tq_dispatch_cv; - kcondvar_t tq_wait_cv; - kthread_t **tq_threadlist; - int tq_flags; - int tq_active; - int tq_nthreads; - int tq_nalloc; - int tq_minalloc; - int tq_maxalloc; - kcondvar_t tq_maxalloc_cv; - int tq_maxalloc_wait; - taskq_ent_t *tq_freelist; - taskq_ent_t tq_task; -} taskq_t; - -#define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */ - -#define TASKQ_PREPOPULATE 0x0001 -#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */ -#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */ -#define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */ -#define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */ - -#define TQ_SLEEP KM_SLEEP /* Can block for memory */ -#define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */ -#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */ -#define TQ_FRONT 0x08 /* Queue in front */ - -#define TASKQID_INVALID ((taskqid_t)0) - -extern taskq_t *system_taskq; -extern taskq_t *system_delay_taskq; - -extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t); -extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t, - kthread_t ***); -#define taskq_create_proc(a, b, c, d, e, p, f) \ - (taskq_create(a, b, c, d, e, f)) -#define taskq_create_sysdc(a, b, d, e, p, dc, f) \ - ((void) sizeof (dc), taskq_create(a, b, maxclsyspri, d, e, f)) -extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t); -extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t, - clock_t); -extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t, - taskq_ent_t *); -extern int taskq_empty_ent(taskq_ent_t *); -extern void taskq_init_ent(taskq_ent_t *); -extern void taskq_destroy(taskq_t *); -extern void taskq_wait(taskq_t *); -extern void taskq_wait_id(taskq_t *, taskqid_t); -extern void taskq_wait_outstanding(taskq_t *, taskqid_t); -extern int taskq_member(taskq_t *, kthread_t *); -extern taskq_t *taskq_of_curthread(void); -extern int taskq_cancel_id(taskq_t *, taskqid_t); -extern void system_taskq_init(void); -extern void system_taskq_fini(void); - -#define XVA_MAPSIZE 3 -#define XVA_MAGIC 0x78766174 - -extern char *vn_dumpdir; -#define AV_SCANSTAMP_SZ 32 /* length of anti-virus scanstamp */ - -typedef struct xoptattr { - inode_timespec_t xoa_createtime; /* Create time of file */ - uint8_t xoa_archive; - uint8_t xoa_system; - uint8_t xoa_readonly; - uint8_t xoa_hidden; - uint8_t xoa_nounlink; - uint8_t xoa_immutable; - uint8_t xoa_appendonly; - uint8_t xoa_nodump; - uint8_t xoa_settable; - uint8_t xoa_opaque; - uint8_t xoa_av_quarantined; - uint8_t xoa_av_modified; - uint8_t xoa_av_scanstamp[AV_SCANSTAMP_SZ]; - uint8_t xoa_reparse; - uint8_t xoa_offline; - uint8_t xoa_sparse; -} xoptattr_t; - -typedef struct vattr { - uint_t va_mask; /* bit-mask of attributes */ - u_offset_t va_size; /* file size in bytes */ -} vattr_t; - - -typedef struct xvattr { - vattr_t xva_vattr; /* Embedded vattr structure */ - uint32_t xva_magic; /* Magic Number */ - uint32_t xva_mapsize; /* Size of attr bitmap (32-bit words) */ - uint32_t *xva_rtnattrmapp; /* Ptr to xva_rtnattrmap[] */ - uint32_t xva_reqattrmap[XVA_MAPSIZE]; /* Requested attrs */ - uint32_t xva_rtnattrmap[XVA_MAPSIZE]; /* Returned attrs */ - xoptattr_t xva_xoptattrs; /* Optional attributes */ -} xvattr_t; - -typedef struct vsecattr { - uint_t vsa_mask; /* See below */ - int vsa_aclcnt; /* ACL entry count */ - void *vsa_aclentp; /* pointer to ACL entries */ - int vsa_dfaclcnt; /* default ACL entry count */ - void *vsa_dfaclentp; /* pointer to default ACL entries */ - size_t vsa_aclentsz; /* ACE size in bytes of vsa_aclentp */ -} vsecattr_t; - -#define AT_MODE 0x00002 -#define AT_UID 0x00004 -#define AT_GID 0x00008 -#define AT_FSID 0x00010 -#define AT_NODEID 0x00020 -#define AT_NLINK 0x00040 -#define AT_SIZE 0x00080 -#define AT_ATIME 0x00100 -#define AT_MTIME 0x00200 -#define AT_CTIME 0x00400 -#define AT_RDEV 0x00800 -#define AT_BLKSIZE 0x01000 -#define AT_NBLOCKS 0x02000 -#define AT_SEQ 0x08000 -#define AT_XVATTR 0x10000 - -#define CRCREAT 0 - -#define F_FREESP 11 -#define FIGNORECASE 0x80000 /* request case-insensitive lookups */ - -/* - * Random stuff - */ -#define ddi_get_lbolt() (gethrtime() >> 23) -#define ddi_get_lbolt64() (gethrtime() >> 23) -#define hz 119 /* frequency when using gethrtime() >> 23 for lbolt */ - -#define ddi_time_before(a, b) (a < b) -#define ddi_time_after(a, b) ddi_time_before(b, a) -#define ddi_time_before_eq(a, b) (!ddi_time_after(a, b)) -#define ddi_time_after_eq(a, b) ddi_time_before_eq(b, a) - -#define ddi_time_before64(a, b) (a < b) -#define ddi_time_after64(a, b) ddi_time_before64(b, a) -#define ddi_time_before_eq64(a, b) (!ddi_time_after64(a, b)) -#define ddi_time_after_eq64(a, b) ddi_time_before_eq64(b, a) - -extern void delay(clock_t ticks); - -#define SEC_TO_TICK(sec) ((sec) * hz) -#define MSEC_TO_TICK(msec) (howmany((hrtime_t)(msec) * hz, MILLISEC)) -#define USEC_TO_TICK(usec) (howmany((hrtime_t)(usec) * hz, MICROSEC)) -#define NSEC_TO_TICK(nsec) (howmany((hrtime_t)(nsec) * hz, NANOSEC)) - -#define max_ncpus 64 -#define boot_ncpus (sysconf(_SC_NPROCESSORS_ONLN)) - -/* - * Process priorities as defined by setpriority(2) and getpriority(2). - */ -#define minclsyspri 19 -#define defclsyspri 0 -/* Write issue taskq priority. */ -#define wtqclsyspri -19 -#define maxclsyspri -20 - -#define CPU_SEQID ((uintptr_t)pthread_self() & (max_ncpus - 1)) -#define CPU_SEQID_UNSTABLE CPU_SEQID - -#define kcred NULL -#define CRED() NULL - -#define crhold(cr) ((void)cr) -#define crfree(cr) ((void)cr) - -#define ptob(x) ((x) * PAGESIZE) - -#define NN_DIVISOR_1000 (1U << 0) -#define NN_NUMBUF_SZ (6) - -extern uint64_t physmem; -extern const char *random_path; -extern const char *urandom_path; - -extern int highbit64(uint64_t i); -extern int lowbit64(uint64_t i); -extern int random_get_bytes(uint8_t *ptr, size_t len); -extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len); - -static __inline__ uint32_t -random_in_range(uint32_t range) -{ - uint32_t r; - - ASSERT(range != 0); - - if (range == 1) - return (0); - - (void) random_get_pseudo_bytes((uint8_t *)&r, sizeof (r)); - - return (r % range); -} - -extern void kernel_init(int mode); -extern void kernel_fini(void); -extern void random_init(void); -extern void random_fini(void); - -struct spa; -extern void show_pool_stats(struct spa *); -extern int handle_tunable_option(const char *, boolean_t); - -typedef struct callb_cpr { - kmutex_t *cc_lockp; -} callb_cpr_t; - -#define CALLB_CPR_INIT(cp, lockp, func, name) { \ - (cp)->cc_lockp = lockp; \ -} - -#define CALLB_CPR_SAFE_BEGIN(cp) { \ - ASSERT(MUTEX_HELD((cp)->cc_lockp)); \ -} - -#define CALLB_CPR_SAFE_END(cp, lockp) { \ - ASSERT(MUTEX_HELD((cp)->cc_lockp)); \ -} - -#define CALLB_CPR_EXIT(cp) { \ - ASSERT(MUTEX_HELD((cp)->cc_lockp)); \ - mutex_exit((cp)->cc_lockp); \ -} - -#define zone_dataset_visible(x, y) (1) -#define INGLOBALZONE(z) (1) -extern uint32_t zone_get_hostid(void *zonep); - -extern char *kmem_vasprintf(const char *fmt, va_list adx); -extern char *kmem_asprintf(const char *fmt, ...); -#define kmem_strfree(str) kmem_free((str), strlen(str) + 1) -#define kmem_strdup(s) strdup(s) - -#ifndef __cplusplus -extern int kmem_scnprintf(char *restrict str, size_t size, - const char *restrict fmt, ...); -#endif - -/* - * Hostname information - */ -extern int ddi_strtoull(const char *str, char **nptr, int base, - u_longlong_t *result); - -typedef struct utsname utsname_t; -extern utsname_t *utsname(void); - -/* ZFS Boot Related stuff. */ - -struct _buf { - intptr_t _fd; -}; - -struct bootstat { - uint64_t st_size; -}; - -typedef struct ace_object { - uid_t a_who; - uint32_t a_access_mask; - uint16_t a_flags; - uint16_t a_type; - uint8_t a_obj_type[16]; - uint8_t a_inherit_obj_type[16]; -} ace_object_t; - - -#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05 -#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06 -#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07 -#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08 - -extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr); -extern int zfs_secpolicy_rename_perms(const char *from, const char *to, - cred_t *cr); -extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr); -extern int secpolicy_zfs(const cred_t *cr); -extern zoneid_t getzoneid(void); - -/* SID stuff */ -typedef struct ksiddomain { - uint_t kd_ref; - uint_t kd_len; - char *kd_name; -} ksiddomain_t; - -ksiddomain_t *ksid_lookupdomain(const char *); -void ksiddomain_rele(ksiddomain_t *); - -#define DDI_SLEEP KM_SLEEP -#define ddi_log_sysevent(_a, _b, _c, _d, _e, _f, _g) \ - sysevent_post_event(_c, _d, _b, "libzpool", _e, _f) - -#define zfs_sleep_until(wakeup) \ - do { \ - hrtime_t delta = wakeup - gethrtime(); \ - struct timespec ts; \ - ts.tv_sec = delta / NANOSEC; \ - ts.tv_nsec = delta % NANOSEC; \ - (void) nanosleep(&ts, NULL); \ - } while (0) - -typedef int fstrans_cookie_t; - -extern fstrans_cookie_t spl_fstrans_mark(void); -extern void spl_fstrans_unmark(fstrans_cookie_t); -extern int kmem_cache_reap_active(void); +#include <sys/zone.h> +#include <sys/mutex.h> +#include <sys/rwlock.h> +#include <sys/condvar.h> +#include <sys/cmn_err.h> +#include <sys/thread.h> +#include <sys/taskq.h> +#include <sys/tsd.h> +#include <sys/procfs_list.h> +#include <sys/kmem.h> +#include <sys/zfs_delay.h> +#include <sys/vnode.h> +#include <sys/callb.h> +#include <sys/trace.h> +#include <sys/systm.h> +#include <sys/misc.h> +#include <sys/random.h> -/* - * Kernel modules - */ -#define __init -#define __exit +#include <sys/zfs_context_os.h> #endif /* _KERNEL || _STANDALONE */ diff --git a/sys/contrib/openzfs/include/sys/zfs_debug.h b/sys/contrib/openzfs/include/sys/zfs_debug.h index 4d4cd4c39e97..0f021d15157b 100644 --- a/sys/contrib/openzfs/include/sys/zfs_debug.h +++ b/sys/contrib/openzfs/include/sys/zfs_debug.h @@ -40,6 +40,7 @@ extern "C" { #endif #include <sys/nvpair.h> +#include <sys/zfs_debug_os.h> extern int zfs_flags; extern int zfs_recover; diff --git a/sys/contrib/openzfs/include/sys/zfs_project.h b/sys/contrib/openzfs/include/sys/zfs_project.h index 714c87a0d441..a368f49e14f5 100644 --- a/sys/contrib/openzfs/include/sys/zfs_project.h +++ b/sys/contrib/openzfs/include/sys/zfs_project.h @@ -35,18 +35,16 @@ #include <sys/vfs.h> -#ifdef FS_PROJINHERIT_FL -#define ZFS_PROJINHERIT_FL FS_PROJINHERIT_FL -#else -#define ZFS_PROJINHERIT_FL 0x20000000 -#endif - #ifdef FS_IOC_FSGETXATTR typedef struct fsxattr zfsxattr_t; #define ZFS_IOC_FSGETXATTR FS_IOC_FSGETXATTR #define ZFS_IOC_FSSETXATTR FS_IOC_FSSETXATTR #else +/* Non-Linux OS */ +#define FS_PROJINHERIT_FL 0x20000000 +#define FS_XFLAG_PROJINHERIT FS_PROJINHERIT_FL + struct zfsxattr { uint32_t fsx_xflags; /* xflags field value (get/set) */ uint32_t fsx_extsize; /* extsize field value (get/set) */ diff --git a/sys/contrib/openzfs/lib/libicp/Makefile.am b/sys/contrib/openzfs/lib/libicp/Makefile.am index 23adba10bc44..a8937e60b770 100644 --- a/sys/contrib/openzfs/lib/libicp/Makefile.am +++ b/sys/contrib/openzfs/lib/libicp/Makefile.am @@ -1,6 +1,9 @@ libicp_la_CCASFLAGS = $(AM_CCASFLAGS) libicp_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) $(LIBRARY_CFLAGS) +libicp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS) +libicp_la_CPPFLAGS += -I$(top_srcdir)/module/icp/include + noinst_LTLIBRARIES += libicp.la nodist_libicp_la_SOURCES = \ @@ -35,8 +38,7 @@ nodist_libicp_la_SOURCES = \ module/icp/core/kcf_prov_lib.c \ module/icp/core/kcf_callprov.c \ module/icp/core/kcf_mech_tabs.c \ - module/icp/core/kcf_prov_tabs.c \ - module/zfs/zfs_impl.c + module/icp/core/kcf_prov_tabs.c if TARGET_CPU_AARCH64 nodist_libicp_la_SOURCES += \ diff --git a/sys/contrib/openzfs/lib/libnvpair/Makefile.am b/sys/contrib/openzfs/lib/libnvpair/Makefile.am index 87b8d32aa175..0b3f964781b0 100644 --- a/sys/contrib/openzfs/lib/libnvpair/Makefile.am +++ b/sys/contrib/openzfs/lib/libnvpair/Makefile.am @@ -30,6 +30,6 @@ if !ASAN_ENABLED libnvpair_la_LDFLAGS += -Wl,-z,defs endif -libnvpair_la_LDFLAGS += -version-info 3:0:0 +libnvpair_la_LDFLAGS += -version-info 4:0:1 dist_noinst_DATA += %D%/libnvpair.abi %D%/libnvpair.suppr diff --git a/sys/contrib/openzfs/lib/libspl/Makefile.am b/sys/contrib/openzfs/lib/libspl/Makefile.am index 0fd907d3011e..27f004634487 100644 --- a/sys/contrib/openzfs/lib/libspl/Makefile.am +++ b/sys/contrib/openzfs/lib/libspl/Makefile.am @@ -16,12 +16,24 @@ libspl_assert_la_SOURCES = \ libspl_la_SOURCES = \ %D%/libspl_impl.h \ %D%/atomic.c \ + %D%/condvar.c \ + %D%/cred.c \ %D%/getexecname.c \ + %D%/kmem.c \ + %D%/kstat.c \ + %D%/libspl.c \ %D%/list.c \ %D%/mkdirp.c \ + %D%/mutex.c \ %D%/page.c \ + %D%/procfs_list.c \ + %D%/random.c \ + %D%/rwlock.c \ + %D%/sid.c \ %D%/strlcat.c \ %D%/strlcpy.c \ + %D%/taskq.c \ + %D%/thread.c \ %D%/timestamp.c \ %D%/tunables.c \ %D%/include/sys/list.h \ diff --git a/sys/contrib/openzfs/lib/libspl/condvar.c b/sys/contrib/openzfs/lib/libspl/condvar.c new file mode 100644 index 000000000000..3d70fe152089 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/condvar.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc. + */ + +#include <assert.h> +#include <pthread.h> +#include <errno.h> +#include <string.h> +#include <sys/timer.h> +#include <sys/condvar.h> + +/* + * ========================================================================= + * condition variables + * ========================================================================= + */ + +void +cv_init(kcondvar_t *cv, char *name, int type, void *arg) +{ + (void) name, (void) type, (void) arg; + VERIFY0(pthread_cond_init(cv, NULL)); +} + +void +cv_destroy(kcondvar_t *cv) +{ + VERIFY0(pthread_cond_destroy(cv)); +} + +void +cv_wait(kcondvar_t *cv, kmutex_t *mp) +{ + memset(&mp->m_owner, 0, sizeof (pthread_t)); + VERIFY0(pthread_cond_wait(cv, &mp->m_lock)); + mp->m_owner = pthread_self(); +} + +int +cv_wait_sig(kcondvar_t *cv, kmutex_t *mp) +{ + cv_wait(cv, mp); + return (1); +} + +int +cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime) +{ + int error; + struct timeval tv; + struct timespec ts; + clock_t delta; + + delta = abstime - ddi_get_lbolt(); + if (delta <= 0) + return (-1); + + VERIFY0(gettimeofday(&tv, NULL)); + + ts.tv_sec = tv.tv_sec + delta / hz; + ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % hz) * (NANOSEC / hz); + if (ts.tv_nsec >= NANOSEC) { + ts.tv_sec++; + ts.tv_nsec -= NANOSEC; + } + + memset(&mp->m_owner, 0, sizeof (pthread_t)); + error = pthread_cond_timedwait(cv, &mp->m_lock, &ts); + mp->m_owner = pthread_self(); + + if (error == ETIMEDOUT) + return (-1); + + VERIFY0(error); + + return (1); +} + +int +cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res, + int flag) +{ + (void) res; + int error; + struct timeval tv; + struct timespec ts; + hrtime_t delta; + + ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE); + + delta = tim; + if (flag & CALLOUT_FLAG_ABSOLUTE) + delta -= gethrtime(); + + if (delta <= 0) + return (-1); + + VERIFY0(gettimeofday(&tv, NULL)); + + ts.tv_sec = tv.tv_sec + delta / NANOSEC; + ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % NANOSEC); + if (ts.tv_nsec >= NANOSEC) { + ts.tv_sec++; + ts.tv_nsec -= NANOSEC; + } + + memset(&mp->m_owner, 0, sizeof (pthread_t)); + error = pthread_cond_timedwait(cv, &mp->m_lock, &ts); + mp->m_owner = pthread_self(); + + if (error == ETIMEDOUT) + return (-1); + + VERIFY0(error); + + return (1); +} + +void +cv_signal(kcondvar_t *cv) +{ + VERIFY0(pthread_cond_signal(cv)); +} + +void +cv_broadcast(kcondvar_t *cv) +{ + VERIFY0(pthread_cond_broadcast(cv)); +} diff --git a/sys/contrib/openzfs/lib/libspl/cred.c b/sys/contrib/openzfs/lib/libspl/cred.c new file mode 100644 index 000000000000..130323ea91a7 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/cred.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc. + */ + +#include <sys/cred.h> + +uid_t +crgetuid(cred_t *cr) +{ + (void) cr; + return (0); +} + +uid_t +crgetruid(cred_t *cr) +{ + (void) cr; + return (0); +} + +gid_t +crgetgid(cred_t *cr) +{ + (void) cr; + return (0); +} + +int +crgetngroups(cred_t *cr) +{ + (void) cr; + return (0); +} + +gid_t * +crgetgroups(cred_t *cr) +{ + (void) cr; + return (NULL); +} diff --git a/sys/contrib/openzfs/lib/libspl/include/Makefile.am b/sys/contrib/openzfs/lib/libspl/include/Makefile.am index 21f0c70db9e7..e68742409839 100644 --- a/sys/contrib/openzfs/lib/libspl/include/Makefile.am +++ b/sys/contrib/openzfs/lib/libspl/include/Makefile.am @@ -4,6 +4,7 @@ libspl_HEADERS = \ %D%/atomic.h \ %D%/libgen.h \ %D%/libshare.h \ + %D%/libspl.h \ %D%/statcommon.h \ %D%/stdlib.h \ %D%/string.h \ @@ -24,14 +25,13 @@ libspl_rpc_HEADERS = \ libspl_sysdir = $(libspldir)/sys libspl_sys_HEADERS = \ - %D%/sys/abd_os.h \ - %D%/sys/abd_impl_os.h \ %D%/sys/acl.h \ %D%/sys/acl_impl.h \ %D%/sys/asm_linkage.h \ %D%/sys/backtrace.h \ %D%/sys/callb.h \ %D%/sys/cmn_err.h \ + %D%/sys/condvar.h \ %D%/sys/cred.h \ %D%/sys/debug.h \ %D%/sys/dkio.h \ @@ -43,22 +43,33 @@ libspl_sys_HEADERS = \ %D%/sys/kstat.h \ %D%/sys/list.h \ %D%/sys/list_impl.h \ + %D%/sys/misc.h \ %D%/sys/mhd.h \ %D%/sys/mkdev.h \ %D%/sys/mod.h \ + %D%/sys/mutex.h \ %D%/sys/policy.h \ %D%/sys/poll.h \ %D%/sys/priv.h \ %D%/sys/processor.h \ + %D%/sys/procfs_list.h \ + %D%/sys/random.h \ + %D%/sys/rwlock.h \ + %D%/sys/sid.h \ %D%/sys/simd.h \ %D%/sys/stack.h \ %D%/sys/stdtypes.h \ %D%/sys/string.h \ %D%/sys/sunddi.h \ + %D%/sys/sysmacros.h \ %D%/sys/systeminfo.h \ + %D%/sys/systm.h \ + %D%/sys/thread.h \ + %D%/sys/taskq.h \ %D%/sys/time.h \ - %D%/sys/trace_spl.h \ - %D%/sys/trace_zfs.h \ + %D%/sys/timer.h \ + %D%/sys/trace.h \ + %D%/sys/tsd.h \ %D%/sys/tunables.h \ %D%/sys/types.h \ %D%/sys/types32.h \ @@ -77,8 +88,7 @@ libspl_sys_HEADERS += \ %D%/os/linux/sys/mount.h \ %D%/os/linux/sys/param.h \ %D%/os/linux/sys/stat.h \ - %D%/os/linux/sys/sysmacros.h \ - %D%/os/linux/sys/zfs_context_os.h + %D%/os/linux/sys/vfs.h libspl_ia32_HEADERS = \ %D%/os/linux/sys/ia32/asm_linkage.h @@ -93,9 +103,7 @@ libspl_sys_HEADERS += \ %D%/os/freebsd/sys/mount.h \ %D%/os/freebsd/sys/param.h \ %D%/os/freebsd/sys/stat.h \ - %D%/os/freebsd/sys/sysmacros.h \ - %D%/os/freebsd/sys/vfs.h \ - %D%/os/freebsd/sys/zfs_context_os.h + %D%/os/freebsd/sys/vfs.h libspl_ia32_HEADERS = \ %D%/os/freebsd/sys/ia32/asm_linkage.h diff --git a/sys/contrib/openzfs/lib/libspl/include/libspl.h b/sys/contrib/openzfs/lib/libspl/include/libspl.h new file mode 100644 index 000000000000..68756bb9597b --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/libspl.h @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2025, Rob Norris <robn@despairlabs.com> + */ + +#ifndef _LIBSPL_H +#define _LIBSPL_H extern __attribute__((visibility("default"))) + +#ifdef __cplusplus +extern "C" { +#endif + +_LIBSPL_H void libspl_init(void); +_LIBSPL_H void libspl_fini(void); + +#ifdef __cplusplus +}; +#endif + +#endif /* _LIBSPL_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/fcntl.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/fcntl.h index 64dd4d7ebe45..04fcc9f85c91 100644 --- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/fcntl.h +++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/fcntl.h @@ -27,7 +27,9 @@ #ifndef _LIBSPL_SYS_FCNTL_H_ #define _LIBSPL_SYS_FCNTL_H_ +#if !defined(__linux__) || !defined(IN_BASE) #include_next <sys/fcntl.h> +#endif #define O_LARGEFILE 0 #define O_RSYNC 0 diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mount.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mount.h index 231c250d3410..5548ad7d22b2 100644 --- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mount.h +++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/mount.h @@ -29,8 +29,10 @@ #ifndef _LIBSPL_SYS_MOUNT_H #define _LIBSPL_SYS_MOUNT_H +#if !defined(__linux__) || !defined(IN_BASE) #undef _SYS_MOUNT_H_ #include_next <sys/mount.h> +#endif #include <assert.h> #include <string.h> diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/param.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/param.h index 55fa1de0e8ff..a693149115db 100644 --- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/param.h +++ b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/param.h @@ -58,6 +58,8 @@ extern size_t spl_pagesize(void); #define PAGESIZE (spl_pagesize()) +#define ptob(x) ((x) * PAGESIZE) + #ifndef HAVE_EXECVPE extern int execvpe(const char *name, char * const argv[], char * const envp[]); #endif diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/zfs_context_os.h b/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/zfs_context_os.h deleted file mode 100644 index 1dd036d02ac6..000000000000 --- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/zfs_context_os.h +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * Copyright (c) 2020 iXsystems, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef ZFS_CONTEXT_OS_H_ -#define ZFS_CONTEXT_OS_H_ - -#define HAVE_LARGE_STACKS 1 - -#endif diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/param.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/param.h index 814f8feaf37f..169d5875fcf0 100644 --- a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/param.h +++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/param.h @@ -65,4 +65,6 @@ extern size_t spl_pagesize(void); #define PAGESIZE (spl_pagesize()) +#define ptob(x) ((x) * PAGESIZE) + #endif diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/zfs_context_os.h b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/vfs.h index bbfb4d17e06d..c7b567ff44a4 100644 --- a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/zfs_context_os.h +++ b/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/vfs.h @@ -20,10 +20,14 @@ * * CDDL HEADER END */ +/* Copyright 2025 by Lawrence Livermore National Security, LLC. */ -#ifndef ZFS_CONTEXT_OS_H -#define ZFS_CONTEXT_OS_H +/* This is the Linux userspace version of include/os/linux/spl/sys/vfs.h */ -#define HAVE_LARGE_STACKS 1 +#ifndef _LIBSPL_SYS_VFS_H +#define _LIBSPL_SYS_VFS_H + +#include <linux/fs.h> +#include <sys/statfs.h> #endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/acl.h b/sys/contrib/openzfs/lib/libspl/include/sys/acl.h index 602043bbb196..3e79040c5307 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/acl.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/acl.h @@ -141,8 +141,6 @@ typedef struct acl_info acl_t; #define ACE_ALL_TYPES 0x001F -#if defined(_KERNEL) - typedef struct ace_object { uid_t a_who; /* uid or gid */ uint32_t a_access_mask; /* read,write,... */ @@ -152,8 +150,6 @@ typedef struct ace_object { uint8_t a_inherit_obj_type[16]; /* inherit obj */ } ace_object_t; -#endif - #define ACE_ALL_PERMS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \ ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_READ_NAMED_ATTRS| \ ACE_WRITE_NAMED_ATTRS|ACE_EXECUTE|ACE_DELETE_CHILD|ACE_READ_ATTRIBUTES| \ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/callb.h b/sys/contrib/openzfs/lib/libspl/include/sys/callb.h index 46ed166e52f8..6e8e22338b8b 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/callb.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/callb.h @@ -21,11 +21,36 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #ifndef _SYS_CALLB_H #define _SYS_CALLB_H +#include <sys/mutex.h> + +typedef struct callb_cpr { + kmutex_t *cc_lockp; +} callb_cpr_t; + +#define CALLB_CPR_INIT(cp, lockp, func, name) { \ + (cp)->cc_lockp = lockp; \ +} + +#define CALLB_CPR_SAFE_BEGIN(cp) { \ + ASSERT(MUTEX_HELD((cp)->cc_lockp)); \ +} + +#define CALLB_CPR_SAFE_END(cp, lockp) { \ + ASSERT(MUTEX_HELD((cp)->cc_lockp)); \ +} + +#define CALLB_CPR_EXIT(cp) { \ + ASSERT(MUTEX_HELD((cp)->cc_lockp)); \ + mutex_exit((cp)->cc_lockp); \ +} + #endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/cmn_err.h b/sys/contrib/openzfs/lib/libspl/include/sys/cmn_err.h index 32930adaeffa..5e7136f7fdc2 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/cmn_err.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/cmn_err.h @@ -62,4 +62,31 @@ do { \ } \ } while (0) +/* + * Note that we are not using the debugging levels. + */ + +#define CE_CONT 0 /* continuation */ +#define CE_NOTE 1 /* notice */ +#define CE_WARN 2 /* warning */ +#define CE_PANIC 3 /* panic */ +#define CE_IGNORE 4 /* print nothing */ + +/* + * ZFS debugging + */ + +extern void dprintf_setup(int *argc, char **argv); + +extern void cmn_err(int, const char *, ...) + __attribute__((format(printf, 2, 3))); +extern void vcmn_err(int, const char *, va_list) + __attribute__((format(printf, 2, 0))); +extern void panic(const char *, ...) + __attribute__((format(printf, 1, 2), noreturn)); +extern void vpanic(const char *, va_list) + __attribute__((format(printf, 1, 0), noreturn)); + +#define fm_panic panic + #endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/condvar.h b/sys/contrib/openzfs/lib/libspl/include/sys/condvar.h new file mode 100644 index 000000000000..fb8f7c9bf6b1 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/condvar.h @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_CONDVAR_H +#define _SYS_CONDVAR_H + +#ifdef SKIP_SPL_SYS_CONDVAR_H +#include_next <sys/condvar.h> +#else + +#include <pthread.h> +#include <sys/time.h> +#include <sys/mutex.h> + +/* + * Condition variables + */ +typedef pthread_cond_t kcondvar_t; + +#define CV_DEFAULT 0 +#define CALLOUT_FLAG_ABSOLUTE 0x2 + +extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg); +extern void cv_destroy(kcondvar_t *cv); +extern void cv_wait(kcondvar_t *cv, kmutex_t *mp); +extern int cv_wait_sig(kcondvar_t *cv, kmutex_t *mp); +extern int cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime); +extern int cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, + hrtime_t res, int flag); +extern void cv_signal(kcondvar_t *cv); +extern void cv_broadcast(kcondvar_t *cv); + +#define cv_timedwait_io(cv, mp, at) cv_timedwait(cv, mp, at) +#define cv_timedwait_idle(cv, mp, at) cv_timedwait(cv, mp, at) +#define cv_timedwait_sig(cv, mp, at) cv_timedwait(cv, mp, at) +#define cv_wait_io(cv, mp) cv_wait(cv, mp) +#define cv_wait_idle(cv, mp) cv_wait(cv, mp) +#define cv_wait_io_sig(cv, mp) cv_wait_sig(cv, mp) +#define cv_timedwait_sig_hires(cv, mp, t, r, f) \ + cv_timedwait_hires(cv, mp, t, r, f) +#define cv_timedwait_idle_hires(cv, mp, t, r, f) \ + cv_timedwait_hires(cv, mp, t, r, f) + +#endif /* SKIP_SPL_CONDVAR_H */ +#endif /* _SYS_CONDVAR_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/cred.h b/sys/contrib/openzfs/lib/libspl/include/sys/cred.h index 4f6183762a0a..deceecee0f19 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/cred.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/cred.h @@ -28,6 +28,24 @@ #ifndef _LIBSPL_SYS_CRED_H #define _LIBSPL_SYS_CRED_H +#include <sys/stat.h> + +/* + * Credentials + */ + typedef struct cred cred_t; +extern uid_t crgetuid(cred_t *cr); +extern uid_t crgetruid(cred_t *cr); +extern gid_t crgetgid(cred_t *cr); +extern int crgetngroups(cred_t *cr); +extern gid_t *crgetgroups(cred_t *cr); + +#define kcred NULL +#define CRED() NULL + +#define crhold(cr) ((void)cr) +#define crfree(cr) ((void)cr) + #endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/debug.h b/sys/contrib/openzfs/lib/libspl/include/sys/debug.h index 02f33a68b75b..2bd077686f1c 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/debug.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/debug.h @@ -24,6 +24,12 @@ * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ #ifndef _LIBSPL_SYS_DEBUG_H #define _LIBSPL_SYS_DEBUG_H @@ -42,4 +48,22 @@ #define __must_check __attribute__((warn_unused_result)) #endif +#ifndef noinline +#define noinline __attribute__((noinline)) +#endif + +#ifndef likely +#define likely(x) __builtin_expect((x), 1) +#endif + +#ifndef unlikely +#define unlikely(x) __builtin_expect((x), 0) +#endif + +/* + * Kernel modules + */ +#define __init +#define __exit + #endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/kmem.h b/sys/contrib/openzfs/lib/libspl/include/sys/kmem.h index 279461f8d4c1..33e618f46bb0 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/kmem.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/kmem.h @@ -20,26 +20,76 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #ifndef _SYS_KMEM_H #define _SYS_KMEM_H -#include <stdlib.h> +#include <umem.h> +#include <sys/types.h> -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif -#define KM_SLEEP 0x00000000 /* same as KM_SLEEP */ -#define KM_NOSLEEP 0x00000001 /* same as KM_NOSLEEP */ +/* + * Kernel memory + */ +#define KM_SLEEP UMEM_NOFAIL +#define KM_PUSHPAGE KM_SLEEP +#define KM_NOSLEEP UMEM_DEFAULT +#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */ +#define KMC_NODEBUG UMC_NODEBUG +#define KMC_KVMEM 0x0 +#define KMC_RECLAIMABLE 0x0 +#define kmem_alloc(_s, _f) umem_alloc(_s, _f) +#define kmem_zalloc(_s, _f) umem_zalloc(_s, _f) +#define kmem_free(_b, _s) umem_free(_b, _s) +#define vmem_alloc(_s, _f) kmem_alloc(_s, _f) +#define vmem_zalloc(_s, _f) kmem_zalloc(_s, _f) +#define vmem_free(_b, _s) kmem_free(_b, _s) +#define kmem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) \ + umem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) +#define kmem_cache_destroy(_c) umem_cache_destroy(_c) +#define kmem_cache_alloc(_c, _f) umem_cache_alloc(_c, _f) +#define kmem_cache_free(_c, _b) umem_cache_free(_c, _b) +#define kmem_debugging() 0 +#define kmem_cache_reap_now(_c) umem_cache_reap_now(_c); +extern int kmem_cache_reap_active(void); +#define kmem_cache_set_move(_c, _cb) /* nothing */ +#define POINTER_INVALIDATE(_pp) /* nothing */ +#define POINTER_IS_VALID(_p) 0 + +extern char *kmem_vasprintf(const char *fmt, va_list adx); +extern char *kmem_asprintf(const char *fmt, ...); +#define kmem_strfree(str) kmem_free((str), strlen(str) + 1) +#define kmem_strdup(s) strdup(s) + +#ifndef __cplusplus +extern int kmem_scnprintf(char *restrict str, size_t size, + const char *restrict fmt, ...); +#endif + +typedef umem_cache_t kmem_cache_t; + +typedef enum kmem_cbrc { + KMEM_CBRC_YES, + KMEM_CBRC_NO, + KMEM_CBRC_LATER, + KMEM_CBRC_DONT_NEED, + KMEM_CBRC_DONT_KNOW +} kmem_cbrc_t; + +typedef int fstrans_cookie_t; -#define kmem_alloc(size, flags) ((void) sizeof (flags), malloc(size)) -#define kmem_free(ptr, size) ((void) sizeof (size), free(ptr)) +extern fstrans_cookie_t spl_fstrans_mark(void); +extern void spl_fstrans_unmark(fstrans_cookie_t); -#ifdef __cplusplus +#ifdef __cplusplus } #endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/kstat.h b/sys/contrib/openzfs/lib/libspl/include/sys/kstat.h index 7777888c31eb..361f24df3f58 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/kstat.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/kstat.h @@ -27,758 +27,65 @@ #ifndef _SYS_KSTAT_H #define _SYS_KSTAT_H - - -/* - * Definition of general kernel statistics structures and /dev/kstat ioctls - */ - #include <sys/types.h> #include <sys/time.h> -#ifdef __cplusplus -extern "C" { -#endif - -typedef int kid_t; /* unique kstat id */ - -/* - * Kernel statistics driver (/dev/kstat) ioctls - */ - -#define KSTAT_IOC_BASE ('K' << 8) - -#define KSTAT_IOC_CHAIN_ID KSTAT_IOC_BASE | 0x01 -#define KSTAT_IOC_READ KSTAT_IOC_BASE | 0x02 -#define KSTAT_IOC_WRITE KSTAT_IOC_BASE | 0x03 - -/* - * /dev/kstat ioctl usage (kd denotes /dev/kstat descriptor): - * - * kcid = ioctl(kd, KSTAT_IOC_CHAIN_ID, NULL); - * kcid = ioctl(kd, KSTAT_IOC_READ, kstat_t *); - * kcid = ioctl(kd, KSTAT_IOC_WRITE, kstat_t *); - */ - #define KSTAT_STRLEN 255 /* 254 chars + NULL; must be 16 * n - 1 */ -/* - * The generic kstat header - */ - typedef struct kstat { - /* - * Fields relevant to both kernel and user - */ - hrtime_t ks_crtime; /* creation time (from gethrtime()) */ - struct kstat *ks_next; /* kstat chain linkage */ - kid_t ks_kid; /* unique kstat ID */ - char ks_module[KSTAT_STRLEN]; /* provider module name */ - uchar_t ks_resv; /* reserved, currently just padding */ - int ks_instance; /* provider module's instance */ - char ks_name[KSTAT_STRLEN]; /* kstat name */ - uchar_t ks_type; /* kstat data type */ - char ks_class[KSTAT_STRLEN]; /* kstat class */ - uchar_t ks_flags; /* kstat flags */ - void *ks_data; /* kstat type-specific data */ - uint_t ks_ndata; /* # of type-specific data records */ - size_t ks_data_size; /* total size of kstat data section */ - hrtime_t ks_snaptime; /* time of last data snapshot */ - /* - * Fields relevant to kernel only - */ - int (*ks_update)(struct kstat *, int); /* dynamic update */ - void *ks_private; /* arbitrary provider-private data */ - int (*ks_snapshot)(struct kstat *, void *, int); - void *ks_lock; /* protects this kstat's data */ + uchar_t ks_flags; + void *ks_data; + uint_t ks_ndata; + size_t ks_data_size; + int (*ks_update)(struct kstat *, int); + void *ks_private; + void *ks_lock; } kstat_t; -/* - * kstat structure and locking strategy - * - * Each kstat consists of a header section (a kstat_t) and a data section. - * The system maintains a set of kstats, protected by kstat_chain_lock. - * kstat_chain_lock protects all additions to/deletions from this set, - * as well as all changes to kstat headers. kstat data sections are - * *optionally* protected by the per-kstat ks_lock. If ks_lock is non-NULL, - * kstat clients (e.g. /dev/kstat) will acquire this lock for all of their - * operations on that kstat. It is up to the kstat provider to decide whether - * guaranteeing consistent data to kstat clients is sufficiently important - * to justify the locking cost. Note, however, that most statistic updates - * already occur under one of the provider's mutexes, so if the provider sets - * ks_lock to point to that mutex, then kstat data locking is free. - * - * NOTE: variable-size kstats MUST employ kstat data locking, to prevent - * data-size races with kstat clients. - * - * NOTE: ks_lock is really of type (kmutex_t *); it is declared as (void *) - * in the kstat header so that users don't have to be exposed to all of the - * kernel's lock-related data structures. - */ - -#if defined(_KERNEL) - -#define KSTAT_ENTER(k) \ - { kmutex_t *lp = (k)->ks_lock; if (lp) mutex_enter(lp); } - -#define KSTAT_EXIT(k) \ - { kmutex_t *lp = (k)->ks_lock; if (lp) mutex_exit(lp); } - -#define KSTAT_UPDATE(k, rw) (*(k)->ks_update)((k), (rw)) - -#define KSTAT_SNAPSHOT(k, buf, rw) (*(k)->ks_snapshot)((k), (buf), (rw)) - -#endif /* defined(_KERNEL) */ - -/* - * kstat time - * - * All times associated with kstats (e.g. creation time, snapshot time, - * kstat_timer_t and kstat_io_t timestamps, etc.) are 64-bit nanosecond values, - * as returned by gethrtime(). The accuracy of these timestamps is machine - * dependent, but the precision (units) is the same across all platforms. - */ - -/* - * kstat identity (KID) - * - * Each kstat is assigned a unique KID (kstat ID) when it is added to the - * global kstat chain. The KID is used as a cookie by /dev/kstat to - * request information about the corresponding kstat. There is also - * an identity associated with the entire kstat chain, kstat_chain_id, - * which is bumped each time a kstat is added or deleted. /dev/kstat uses - * the chain ID to detect changes in the kstat chain (e.g., a new disk - * coming online) between ioctl()s. - */ - -/* - * kstat module, kstat instance - * - * ks_module and ks_instance contain the name and instance of the module - * that created the kstat. In cases where there can only be one instance, - * ks_instance is 0. The kernel proper (/kernel/unix) uses "unix" as its - * module name. - */ - -/* - * kstat name - * - * ks_name gives a meaningful name to a kstat. The full kstat namespace - * is module.instance.name, so the name only need be unique within a - * module. kstat_create() will fail if you try to create a kstat with - * an already-used (ks_module, ks_instance, ks_name) triplet. Spaces are - * allowed in kstat names, but strongly discouraged, since they hinder - * awk-style processing at user level. - */ - -/* - * kstat type - * - * The kstat mechanism provides several flavors of kstat data, defined - * below. The "raw" kstat type is just treated as an array of bytes; you - * can use this to export any kind of data you want. - * - * Some kstat types allow multiple data structures per kstat, e.g. - * KSTAT_TYPE_NAMED; others do not. This is part of the spec for each - * kstat data type. - * - * User-level tools should *not* rely on the #define KSTAT_NUM_TYPES. To - * get this information, read out the standard system kstat "kstat_types". - */ - -#define KSTAT_TYPE_RAW 0 /* can be anything */ - /* ks_ndata >= 1 */ -#define KSTAT_TYPE_NAMED 1 /* name/value pair */ - /* ks_ndata >= 1 */ -#define KSTAT_TYPE_INTR 2 /* interrupt statistics */ - /* ks_ndata == 1 */ -#define KSTAT_TYPE_IO 3 /* I/O statistics */ - /* ks_ndata == 1 */ -#define KSTAT_TYPE_TIMER 4 /* event timer */ - /* ks_ndata >= 1 */ - -#define KSTAT_NUM_TYPES 5 - -/* - * kstat class - * - * Each kstat can be characterized as belonging to some broad class - * of statistics, e.g. disk, tape, net, vm, streams, etc. This field - * can be used as a filter to extract related kstats. The following - * values are currently in use: disk, tape, net, controller, vm, kvm, - * hat, streams, kstat, and misc. (The kstat class encompasses things - * like kstat_types.) - */ - -/* - * kstat flags - * - * Any of the following flags may be passed to kstat_create(). They are - * all zero by default. - * - * KSTAT_FLAG_VIRTUAL: - * - * Tells kstat_create() not to allocate memory for the - * kstat data section; instead, you will set the ks_data - * field to point to the data you wish to export. This - * provides a convenient way to export existing data - * structures. - * - * KSTAT_FLAG_VAR_SIZE: - * - * The size of the kstat you are creating will vary over time. - * For example, you may want to use the kstat mechanism to - * export a linked list. NOTE: The kstat framework does not - * manage the data section, so all variable-size kstats must be - * virtual kstats. Moreover, variable-size kstats MUST employ - * kstat data locking to prevent data-size races with kstat - * clients. See the section on "kstat snapshot" for details. - * - * KSTAT_FLAG_WRITABLE: - * - * Makes the kstat's data section writable by root. - * The ks_snapshot routine (see below) does not need to check for - * this; permission checking is handled in the kstat driver. - * - * KSTAT_FLAG_PERSISTENT: - * - * Indicates that this kstat is to be persistent over time. - * For persistent kstats, kstat_delete() simply marks the - * kstat as dormant; a subsequent kstat_create() reactivates - * the kstat. This feature is provided so that statistics - * are not lost across driver close/open (e.g., raw disk I/O - * on a disk with no mounted partitions.) - * NOTE: Persistent kstats cannot be virtual, since ks_data - * points to garbage as soon as the driver goes away. - * - * The following flags are maintained by the kstat framework: - * - * KSTAT_FLAG_DORMANT: - * - * For persistent kstats, indicates that the kstat is in the - * dormant state (e.g., the corresponding device is closed). - * - * KSTAT_FLAG_INVALID: - * - * This flag is set when a kstat is in a transitional state, - * e.g. between kstat_create() and kstat_install(). - * kstat clients must not attempt to access the kstat's data - * if this flag is set. - */ +#define KSTAT_TYPE_RAW 0 +#define KSTAT_TYPE_NAMED 1 #define KSTAT_FLAG_VIRTUAL 0x01 -#define KSTAT_FLAG_VAR_SIZE 0x02 -#define KSTAT_FLAG_WRITABLE 0x04 -#define KSTAT_FLAG_PERSISTENT 0x08 -#define KSTAT_FLAG_DORMANT 0x10 -#define KSTAT_FLAG_INVALID 0x20 -#define KSTAT_FLAG_LONGSTRINGS 0x40 #define KSTAT_FLAG_NO_HEADERS 0x80 -/* - * Dynamic update support - * - * The kstat mechanism allows for an optional ks_update function to update - * kstat data. This is useful for drivers where the underlying device - * keeps cheap hardware stats, but extraction is expensive. Instead of - * constantly keeping the kstat data section up to date, you can supply a - * ks_update function which updates the kstat's data section on demand. - * To take advantage of this feature, simply set the ks_update field before - * calling kstat_install(). - * - * The ks_update function, if supplied, must have the following structure: - * - * int - * foo_kstat_update(kstat_t *ksp, int rw) - * { - * if (rw == KSTAT_WRITE) { - * ... update the native stats from ksp->ks_data; - * return EACCES if you don't support this - * } else { - * ... update ksp->ks_data from the native stats - * } - * } - * - * The ks_update return codes are: 0 for success, EACCES if you don't allow - * KSTAT_WRITE, and EIO for any other type of error. - * - * In general, the ks_update function may need to refer to provider-private - * data; for example, it may need a pointer to the provider's raw statistics. - * The ks_private field is available for this purpose. Its use is entirely - * at the provider's discretion. - * - * All variable-size kstats MUST supply a ks_update routine, which computes - * and sets ks_data_size (and ks_ndata if that is meaningful), since these - * are needed to perform kstat snapshots (see below). - * - * No kstat locking should be done inside the ks_update routine. The caller - * will already be holding the kstat's ks_lock (to ensure consistent data). - */ - #define KSTAT_READ 0 #define KSTAT_WRITE 1 -/* - * Kstat snapshot - * - * In order to get a consistent view of a kstat's data, clients must obey - * the kstat's locking strategy. However, these clients may need to perform - * operations on the data which could cause a fault (e.g. copyout()), or - * operations which are simply expensive. Doing so could cause deadlock - * (e.g. if you're holding a disk's kstat lock which is ultimately required - * to resolve a copyout() fault), performance degradation (since the providers' - * activity is serialized at the kstat lock), device timing problems, etc. - * - * To avoid these problems, kstat data is provided via snapshots. Taking - * a snapshot is a simple process: allocate a wired-down kernel buffer, - * acquire the kstat's data lock, copy the data into the buffer ("take the - * snapshot"), and release the lock. This ensures that the kstat's data lock - * will be held as briefly as possible, and that no faults will occur while - * the lock is held. - * - * Normally, the snapshot is taken by default_kstat_snapshot(), which - * timestamps the data (sets ks_snaptime), copies it, and does a little - * massaging to deal with incomplete transactions on i/o kstats. However, - * this routine only works for kstats with contiguous data (the typical case). - * If you create a kstat whose data is, say, a linked list, you must provide - * your own ks_snapshot routine. The routine you supply must have the - * following prototype (replace "foo" with something appropriate): - * - * int foo_kstat_snapshot(kstat_t *ksp, void *buf, int rw); - * - * The minimal snapshot routine -- one which copies contiguous data that - * doesn't need any massaging -- would be this: - * - * ksp->ks_snaptime = gethrtime(); - * if (rw == KSTAT_WRITE) - * memcpy(ksp->ks_data, buf, ksp->ks_data_size); - * else - * memcpy(buf, ksp->ks_data, ksp->ks_data_size); - * return (0); - * - * A more illuminating example is taking a snapshot of a linked list: - * - * ksp->ks_snaptime = gethrtime(); - * if (rw == KSTAT_WRITE) - * return (EACCES); ... See below ... - * for (foo = first_foo; foo; foo = foo->next) { - * memcpy(buf, foo, sizeof (struct foo)); - * buf = ((struct foo *) buf) + 1; - * } - * return (0); - * - * In the example above, we have decided that we don't want to allow - * KSTAT_WRITE access, so we return EACCES if this is attempted. - * - * The key points are: - * - * (1) ks_snaptime must be set (via gethrtime()) to timestamp the data. - * (2) Data gets copied from the kstat to the buffer on KSTAT_READ, - * and from the buffer to the kstat on KSTAT_WRITE. - * (3) ks_snapshot return values are: 0 for success, EACCES if you - * don't allow KSTAT_WRITE, and EIO for any other type of error. - * - * Named kstats (see section on "Named statistics" below) containing long - * strings (KSTAT_DATA_STRING) need special handling. The kstat driver - * assumes that all strings are copied into the buffer after the array of - * named kstats, and the pointers (KSTAT_NAMED_STR_PTR()) are updated to point - * into the copy within the buffer. The default snapshot routine does this, - * but overriding routines should contain at least the following: - * - * if (rw == KSTAT_READ) { - * kstat_named_t *knp = buf; - * char *end = knp + ksp->ks_ndata; - * uint_t i; - * - * ... Do the regular copy ... - * memcpy(buf, ksp->ks_data, sizeof (kstat_named_t) * ksp->ks_ndata); - * - * for (i = 0; i < ksp->ks_ndata; i++, knp++) { - * if (knp[i].data_type == KSTAT_DATA_STRING && - * KSTAT_NAMED_STR_PTR(knp) != NULL) { - * memcpy(end, KSTAT_NAMED_STR_PTR(knp), - * KSTAT_NAMED_STR_BUFLEN(knp)); - * KSTAT_NAMED_STR_PTR(knp) = end; - * end += KSTAT_NAMED_STR_BUFLEN(knp); - * } - * } - */ - -/* - * Named statistics. - * - * List of arbitrary name=value statistics. - */ - typedef struct kstat_named { - char name[KSTAT_STRLEN]; /* name of counter */ - uchar_t data_type; /* data type */ + char name[KSTAT_STRLEN]; + uchar_t data_type; union { - char c[16]; /* enough for 128-bit ints */ - int32_t i32; - uint32_t ui32; struct { union { - char *ptr; /* NULL-term string */ -#if defined(_KERNEL) && defined(_MULTI_DATAMODEL) - caddr32_t ptr32; -#endif - char __pad[8]; /* 64-bit padding */ + char *ptr; + char __pad[8]; } addr; - uint32_t len; /* # bytes for strlen + '\0' */ + uint32_t len; } str; -/* - * The int64_t and uint64_t types are not valid for a maximally conformant - * 32-bit compilation environment (cc -Xc) using compilers prior to the - * introduction of C99 conforming compiler (reference ISO/IEC 9899:1990). - * In these cases, the visibility of i64 and ui64 is only permitted for - * 64-bit compilation environments or 32-bit non-maximally conformant - * C89 or C90 ANSI C compilation environments (cc -Xt and cc -Xa). In the - * C99 ANSI C compilation environment, the long long type is supported. - * The _INT64_TYPE is defined by the implementation (see sys/inttypes.h). - */ -#if defined(_INT64_TYPE) int64_t i64; uint64_t ui64; -#endif - long l; - ulong_t ul; - - /* These structure members are obsolete */ - - longlong_t ll; - u_longlong_t ull; - float f; - double d; - } value; /* value of counter */ + } value; } kstat_named_t; -#define KSTAT_DATA_CHAR 0 -#define KSTAT_DATA_INT32 1 #define KSTAT_DATA_UINT32 2 #define KSTAT_DATA_INT64 3 #define KSTAT_DATA_UINT64 4 - -#if !defined(_LP64) -#define KSTAT_DATA_LONG KSTAT_DATA_INT32 -#define KSTAT_DATA_ULONG KSTAT_DATA_UINT32 -#else -#if !defined(_KERNEL) -#define KSTAT_DATA_LONG KSTAT_DATA_INT64 -#define KSTAT_DATA_ULONG KSTAT_DATA_UINT64 -#else -#define KSTAT_DATA_LONG 7 /* only visible to the kernel */ -#define KSTAT_DATA_ULONG 8 /* only visible to the kernel */ -#endif /* !_KERNEL */ -#endif /* !_LP64 */ - -/* - * Statistics exporting named kstats with long strings (KSTAT_DATA_STRING) - * may not make the assumption that ks_data_size is equal to (ks_ndata * sizeof - * (kstat_named_t)). ks_data_size in these cases is equal to the sum of the - * amount of space required to store the strings (ie, the sum of - * KSTAT_NAMED_STR_BUFLEN() for all KSTAT_DATA_STRING statistics) plus the - * space required to store the kstat_named_t's. - * - * The default update routine will update ks_data_size automatically for - * variable-length kstats containing long strings (using the default update - * routine only makes sense if the string is the only thing that is changing - * in size, and ks_ndata is constant). Fixed-length kstats containing long - * strings must explicitly change ks_data_size (after creation but before - * initialization) to reflect the correct amount of space required for the - * long strings and the kstat_named_t's. - */ #define KSTAT_DATA_STRING 9 -/* These types are obsolete */ - -#define KSTAT_DATA_LONGLONG KSTAT_DATA_INT64 -#define KSTAT_DATA_ULONGLONG KSTAT_DATA_UINT64 -#define KSTAT_DATA_FLOAT 5 -#define KSTAT_DATA_DOUBLE 6 - -#define KSTAT_NAMED_PTR(kptr) ((kstat_named_t *)(kptr)->ks_data) - -/* - * Retrieve the pointer of the string contained in the given named kstat. - */ -#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.str.addr.ptr) - -/* - * Retrieve the length of the buffer required to store the string in the given - * named kstat. - */ -#define KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.str.len) +#define KSTAT_NAMED_PTR(kptr) ((kstat_named_t *)(kptr)->ks_data) +#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.str.addr.ptr) +#define KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.str.len) /* - * Interrupt statistics. - * - * An interrupt is a hard interrupt (sourced from the hardware device - * itself), a soft interrupt (induced by the system via the use of - * some system interrupt source), a watchdog interrupt (induced by - * a periodic timer call), spurious (an interrupt entry point was - * entered but there was no interrupt condition to service), - * or multiple service (an interrupt condition was detected and - * serviced just prior to returning from any of the other types). - * - * Measurement of the spurious class of interrupts is useful for - * autovectored devices in order to pinpoint any interrupt latency - * problems in a particular system configuration. - * - * Devices that have more than one interrupt of the same - * type should use multiple structures. + * kstat creation, installation and deletion */ - -#define KSTAT_INTR_HARD 0 -#define KSTAT_INTR_SOFT 1 -#define KSTAT_INTR_WATCHDOG 2 -#define KSTAT_INTR_SPURIOUS 3 -#define KSTAT_INTR_MULTSVC 4 - -#define KSTAT_NUM_INTRS 5 - -typedef struct kstat_intr { - uint_t intrs[KSTAT_NUM_INTRS]; /* interrupt counters */ -} kstat_intr_t; - -#define KSTAT_INTR_PTR(kptr) ((kstat_intr_t *)(kptr)->ks_data) - -/* - * I/O statistics. - */ - -typedef struct kstat_io { - - /* - * Basic counters. - * - * The counters should be updated at the end of service - * (e.g., just prior to calling biodone()). - */ - - u_longlong_t nread; /* number of bytes read */ - u_longlong_t nwritten; /* number of bytes written */ - uint_t reads; /* number of read operations */ - uint_t writes; /* number of write operations */ - - /* - * Accumulated time and queue length statistics. - * - * Accumulated time statistics are kept as a running sum - * of "active" time. Queue length statistics are kept as a - * running sum of the product of queue length and elapsed time - * at that length -- i.e., a Riemann sum for queue length - * integrated against time. (You can also think of the active time - * as a Riemann sum, for the boolean function (queue_length > 0) - * integrated against time, or you can think of it as the - * Lebesgue measure of the set on which queue_length > 0.) - * - * ^ - * | _________ - * 8 | i4 | - * | | | - * Queue 6 | | - * Length | _________ | | - * 4 | i2 |_______| | - * | | i3 | - * 2_______| | - * | i1 | - * |_______________________________| - * Time-> t1 t2 t3 t4 - * - * At each change of state (entry or exit from the queue), - * we add the elapsed time (since the previous state change) - * to the active time if the queue length was non-zero during - * that interval; and we add the product of the elapsed time - * times the queue length to the running length*time sum. - * - * This method is generalizable to measuring residency - * in any defined system: instead of queue lengths, think - * of "outstanding RPC calls to server X". - * - * A large number of I/O subsystems have at least two basic - * "lists" of transactions they manage: one for transactions - * that have been accepted for processing but for which processing - * has yet to begin, and one for transactions which are actively - * being processed (but not done). For this reason, two cumulative - * time statistics are defined here: wait (pre-service) time, - * and run (service) time. - * - * All times are 64-bit nanoseconds (hrtime_t), as returned by - * gethrtime(). - * - * The units of cumulative busy time are accumulated nanoseconds. - * The units of cumulative length*time products are elapsed time - * times queue length. - * - * Updates to the fields below are performed implicitly by calls to - * these five functions: - * - * kstat_waitq_enter() - * kstat_waitq_exit() - * kstat_runq_enter() - * kstat_runq_exit() - * - * kstat_waitq_to_runq() (see below) - * kstat_runq_back_to_waitq() (see below) - * - * Since kstat_waitq_exit() is typically followed immediately - * by kstat_runq_enter(), there is a single kstat_waitq_to_runq() - * function which performs both operations. This is a performance - * win since only one timestamp is required. - * - * In some instances, it may be necessary to move a request from - * the run queue back to the wait queue, e.g. for write throttling. - * For these situations, call kstat_runq_back_to_waitq(). - * - * These fields should never be updated by any other means. - */ - - hrtime_t wtime; /* cumulative wait (pre-service) time */ - hrtime_t wlentime; /* cumulative wait length*time product */ - hrtime_t wlastupdate; /* last time wait queue changed */ - hrtime_t rtime; /* cumulative run (service) time */ - hrtime_t rlentime; /* cumulative run length*time product */ - hrtime_t rlastupdate; /* last time run queue changed */ - - uint_t wcnt; /* count of elements in wait state */ - uint_t rcnt; /* count of elements in run state */ - -} kstat_io_t; - -#define KSTAT_IO_PTR(kptr) ((kstat_io_t *)(kptr)->ks_data) - -/* - * Event timer statistics - cumulative elapsed time and number of events. - * - * Updates to these fields are performed implicitly by calls to - * kstat_timer_start() and kstat_timer_stop(). - */ - -typedef struct kstat_timer { - char name[KSTAT_STRLEN]; /* event name */ - uchar_t resv; /* reserved */ - u_longlong_t num_events; /* number of events */ - hrtime_t elapsed_time; /* cumulative elapsed time */ - hrtime_t min_time; /* shortest event duration */ - hrtime_t max_time; /* longest event duration */ - hrtime_t start_time; /* previous event start time */ - hrtime_t stop_time; /* previous event stop time */ -} kstat_timer_t; - -#define KSTAT_TIMER_PTR(kptr) ((kstat_timer_t *)(kptr)->ks_data) - -#if defined(_KERNEL) - -#include <sys/t_lock.h> - -extern kid_t kstat_chain_id; /* bumped at each state change */ -extern void kstat_init(void); /* initialize kstat framework */ - -/* - * Adding and deleting kstats. - * - * The typical sequence to add a kstat is: - * - * ksp = kstat_create(module, instance, name, class, type, ndata, flags); - * if (ksp) { - * ... provider initialization, if necessary - * kstat_install(ksp); - * } - * - * There are three logically distinct steps here: - * - * Step 1: System Initialization (kstat_create) - * - * kstat_create() performs system initialization. kstat_create() - * allocates memory for the entire kstat (header plus data), initializes - * all header fields, initializes the data section to all zeroes, assigns - * a unique KID, and puts the kstat onto the system's kstat chain. - * The returned kstat is marked invalid (KSTAT_FLAG_INVALID is set), - * because the provider (caller) has not yet had a chance to initialize - * the data section. - * - * By default, kstats are exported to all zones on the system. A kstat may be - * created via kstat_create_zone() to specify a zone to which the statistics - * should be exported. kstat_zone_add() may be used to specify additional - * zones to which the statistics are to be exported. - * - * Step 2: Provider Initialization - * - * The provider performs any necessary initialization of the data section, - * e.g. setting the name fields in a KSTAT_TYPE_NAMED. Virtual kstats set - * the ks_data field at this time. The provider may also set the ks_update, - * ks_snapshot, ks_private, and ks_lock fields if necessary. - * - * Step 3: Installation (kstat_install) - * - * Once the kstat is completely initialized, kstat_install() clears the - * INVALID flag, thus making the kstat accessible to the outside world. - * kstat_install() also clears the DORMANT flag for persistent kstats. - * - * Removing a kstat from the system - * - * kstat_delete(ksp) removes ksp from the kstat chain and frees all - * associated system resources. NOTE: When you call kstat_delete(), - * you must NOT be holding that kstat's ks_lock. Otherwise, you may - * deadlock with a kstat reader. - * - * Persistent kstats - * - * From the provider's point of view, persistence is transparent. The only - * difference between ephemeral (normal) kstats and persistent kstats - * is that you pass KSTAT_FLAG_PERSISTENT to kstat_create(). Magically, - * this has the effect of making your data visible even when you're - * not home. Persistence is important to tools like iostat, which want - * to get a meaningful picture of disk activity. Without persistence, - * raw disk i/o statistics could never accumulate: they would come and - * go with each open/close of the raw device. - * - * The magic of persistence works by slightly altering the behavior of - * kstat_create() and kstat_delete(). The first call to kstat_create() - * creates a new kstat, as usual. However, kstat_delete() does not - * actually delete the kstat: it performs one final update of the data - * (i.e., calls the ks_update routine), marks the kstat as dormant, and - * sets the ks_lock, ks_update, ks_private, and ks_snapshot fields back - * to their default values (since they might otherwise point to garbage, - * e.g. if the provider is going away). kstat clients can still access - * the dormant kstat just like a live kstat; they just continue to see - * the final data values as long as the kstat remains dormant. - * All subsequent kstat_create() calls simply find the already-existing, - * dormant kstat and return a pointer to it, without altering any fields. - * The provider then performs its usual initialization sequence, and - * calls kstat_install(). kstat_install() uses the old data values to - * initialize the native data (i.e., ks_update is called with KSTAT_WRITE), - * thus making it seem like you were never gone. - */ - -extern kstat_t *kstat_create(const char *, int, const char *, const char *, - uchar_t, uint_t, uchar_t); -extern kstat_t *kstat_create_zone(const char *, int, const char *, - const char *, uchar_t, uint_t, uchar_t, zoneid_t); +extern kstat_t *kstat_create(const char *, int, + const char *, const char *, uchar_t, ulong_t, uchar_t); extern void kstat_install(kstat_t *); extern void kstat_delete(kstat_t *); -extern void kstat_named_setstr(kstat_named_t *knp, const char *src); -extern void kstat_set_string(char *, const char *); -extern void kstat_delete_byname(const char *, int, const char *); -extern void kstat_delete_byname_zone(const char *, int, const char *, zoneid_t); -extern void kstat_named_init(kstat_named_t *, const char *, uchar_t); -extern void kstat_timer_init(kstat_timer_t *, const char *); -extern void kstat_timer_start(kstat_timer_t *); -extern void kstat_timer_stop(kstat_timer_t *); - -extern void kstat_zone_add(kstat_t *, zoneid_t); -extern void kstat_zone_remove(kstat_t *, zoneid_t); -extern int kstat_zone_find(kstat_t *, zoneid_t); - -extern kstat_t *kstat_hold_bykid(kid_t kid, zoneid_t); -extern kstat_t *kstat_hold_byname(const char *, int, const char *, zoneid_t); -extern void kstat_rele(kstat_t *); - -#endif /* defined(_KERNEL) */ - -#ifdef __cplusplus -} -#endif +extern void kstat_set_raw_ops(kstat_t *ksp, + int (*headers)(char *buf, size_t size), + int (*data)(char *buf, size_t size, void *data), + void *(*addr)(kstat_t *ksp, loff_t index)); #endif /* _SYS_KSTAT_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/misc.h b/sys/contrib/openzfs/lib/libspl/include/sys/misc.h new file mode 100644 index 000000000000..171bbc1de798 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/misc.h @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _LIBSPL_SYS_MISC_H +#define _LIBSPL_SYS_MISC_H + +#include <sys/utsname.h> + +/* + * Hostname information + */ +typedef struct utsname utsname_t; +extern utsname_t *utsname(void); + +#endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/mutex.h b/sys/contrib/openzfs/lib/libspl/include/sys/mutex.h new file mode 100644 index 000000000000..1da0e632d60f --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/mutex.h @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_MUTEX_H +#define _SYS_MUTEX_H + +#include <pthread.h> + +/* + * Mutexes + */ +typedef struct kmutex { + pthread_mutex_t m_lock; + pthread_t m_owner; +} kmutex_t; + +#define MUTEX_DEFAULT 0 +#define MUTEX_NOLOCKDEP MUTEX_DEFAULT +#define MUTEX_HELD(mp) pthread_equal((mp)->m_owner, pthread_self()) +#define MUTEX_NOT_HELD(mp) !MUTEX_HELD(mp) + +extern void mutex_init(kmutex_t *mp, char *name, int type, void *cookie); +extern void mutex_destroy(kmutex_t *mp); +extern void mutex_enter(kmutex_t *mp); +extern int mutex_enter_check_return(kmutex_t *mp); +extern void mutex_exit(kmutex_t *mp); +extern int mutex_tryenter(kmutex_t *mp); + +#define NESTED_SINGLE 1 +#define mutex_enter_nested(mp, class) mutex_enter(mp) +#define mutex_enter_interruptible(mp) mutex_enter_check_return(mp) + +#endif /* _SYS_MUTEX_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/procfs_list.h b/sys/contrib/openzfs/lib/libspl/include/sys/procfs_list.h new file mode 100644 index 000000000000..144a8a22b9b5 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/procfs_list.h @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_PROCFS_LIST_H +#define _SYS_PROCFS_LIST_H + +#include <sys/types.h> +#include <sys/mutex.h> +#include <sys/list.h> + +/* + * procfs list manipulation + */ + +typedef struct procfs_list { + void *pl_private; + kmutex_t pl_lock; + list_t pl_list; + uint64_t pl_next_id; + size_t pl_node_offset; +} procfs_list_t; + +#ifndef __cplusplus +struct seq_file { }; +void seq_printf(struct seq_file *m, const char *fmt, ...); + +typedef struct procfs_list_node { + list_node_t pln_link; + uint64_t pln_id; +} procfs_list_node_t; + +void procfs_list_install(const char *module, + const char *submodule, + const char *name, + mode_t mode, + procfs_list_t *procfs_list, + int (*show)(struct seq_file *f, void *p), + int (*show_header)(struct seq_file *f), + int (*clear)(procfs_list_t *procfs_list), + size_t procfs_list_node_off); +void procfs_list_uninstall(procfs_list_t *procfs_list); +void procfs_list_destroy(procfs_list_t *procfs_list); +void procfs_list_add(procfs_list_t *procfs_list, void *p); +#endif + +#endif /* _SYS_PROCFS_LIST_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/random.h b/sys/contrib/openzfs/lib/libspl/include/sys/random.h new file mode 100644 index 000000000000..09ca0662d1a3 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/random.h @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_RANDOM_H +#define _SYS_RANDOM_H + +extern int random_get_bytes(uint8_t *ptr, size_t len); +extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len); + +extern void random_force_pseudo(boolean_t onoff); + +static __inline__ uint32_t +random_in_range(uint32_t range) +{ + uint32_t r; + +#if !defined(__APPLE__) || !defined(IN_BASE) + ASSERT(range != 0); +#endif + + if (range == 1) + return (0); + + (void) random_get_pseudo_bytes((uint8_t *)&r, sizeof (r)); + + return (r % range); +} + +#endif /* _SYS_RANDOM_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/rwlock.h b/sys/contrib/openzfs/lib/libspl/include/sys/rwlock.h new file mode 100644 index 000000000000..9f82f270d939 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/rwlock.h @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_RWLOCK_H +#define _SYS_RWLOCK_H + +#include <pthread.h> + +/* + * RW locks + */ +typedef struct krwlock { + pthread_rwlock_t rw_lock; + pthread_t rw_owner; + uint_t rw_readers; +} krwlock_t; + +typedef int krw_t; + +#define RW_READER 0 +#define RW_WRITER 1 +#define RW_DEFAULT RW_READER +#define RW_NOLOCKDEP RW_READER + +#define RW_READ_HELD(rw) ((rw)->rw_readers > 0) +#define RW_WRITE_HELD(rw) pthread_equal((rw)->rw_owner, pthread_self()) +#define RW_LOCK_HELD(rw) (RW_READ_HELD(rw) || RW_WRITE_HELD(rw)) + +extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg); +extern void rw_destroy(krwlock_t *rwlp); +extern void rw_enter(krwlock_t *rwlp, krw_t rw); +extern int rw_tryenter(krwlock_t *rwlp, krw_t rw); +extern int rw_tryupgrade(krwlock_t *rwlp); +extern void rw_exit(krwlock_t *rwlp); +#define rw_downgrade(rwlp) do { } while (0) + +#endif /* _SYS_RWLOCK_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/sid.h b/sys/contrib/openzfs/lib/libspl/include/sys/sid.h new file mode 100644 index 000000000000..74789c5d9a62 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/sid.h @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_SID_H +#define _SYS_SID_H + +#include <sys/types.h> + +/* SID stuff */ +typedef struct ksiddomain { + uint_t kd_ref; + uint_t kd_len; + char *kd_name; +} ksiddomain_t; + +ksiddomain_t *ksid_lookupdomain(const char *); +void ksiddomain_rele(ksiddomain_t *); + +#endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/string.h b/sys/contrib/openzfs/lib/libspl/include/sys/string.h index 3b2f5900276f..55ccbd09041a 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/string.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/string.h @@ -1 +1,4 @@ +#ifndef _LIBSPL_SYS_STRING_H +#define _LIBSPL_SYS_STRING_H #include <string.h> +#endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h b/sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h index 8489c7139bad..48e0b15a4542 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/sunddi.h @@ -21,10 +21,16 @@ * CDDL HEADER END */ /* - * Copyright (c) 2008 by Sun Microsystems, Inc. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #ifndef _SYS_SUNDDI_H #define _SYS_SUNDDI_H +extern int ddi_strtoull(const char *str, char **nptr, int base, + u_longlong_t *result); + #endif /* _SYS_SUNDDI_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/sysmacros.h b/sys/contrib/openzfs/lib/libspl/include/sys/sysmacros.h index 66e0da6b5afe..f67b081c42fa 100644 --- a/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/sysmacros.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/sysmacros.h @@ -3,9 +3,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or https://opensource.org/licenses/CDDL-1.0. @@ -21,14 +20,32 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #ifndef _LIBSPL_SYS_SYSMACROS_H #define _LIBSPL_SYS_SYSMACROS_H +#include <stdint.h> + +#ifdef __linux__ +/* + * On Linux, we need the system-provided sysmacros.h to get the makedev(), + * major() and minor() definitions for makedevice() below. FreeBSD does not + * have this header, so include_next won't find it and will abort. So, we + * protect it with a platform check. + */ +#ifndef IN_BASE #include_next <sys/sysmacros.h> +#endif +#endif + +#ifdef __FreeBSD__ +#include <sys/param.h> +#endif /* common macros */ #ifndef MIN @@ -94,10 +111,22 @@ #define P2SAMEHIGHBIT_TYPED(x, y, type) \ (((type)(x) ^ (type)(y)) < ((type)(x) & (type)(y))) +#define max_ncpus 64 +#define boot_ncpus (sysconf(_SC_NPROCESSORS_ONLN)) -/* avoid any possibility of clashing with <stddef.h> version */ -#if defined(_KERNEL) && !defined(_KMEMUSER) && !defined(offsetof) -#define offsetof(s, m) ((size_t)(&(((s *)0)->m))) -#endif +/* + * Process priorities as defined by setpriority(2) and getpriority(2). + */ +#define minclsyspri 19 +#define defclsyspri 0 +/* Write issue taskq priority. */ +#define wtqclsyspri -19 +#define maxclsyspri -20 + +#define CPU_SEQID ((uintptr_t)pthread_self() & (max_ncpus - 1)) +#define CPU_SEQID_UNSTABLE CPU_SEQID + +extern int lowbit64(uint64_t i); +extern int highbit64(uint64_t i); -#endif /* _LIBSPL_SYS_SYSMACROS_H */ +#endif /* _SYS_SYSMACROS_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/systm.h b/sys/contrib/openzfs/lib/libspl/include/sys/systm.h new file mode 100644 index 000000000000..f984125c3315 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/systm.h @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _LIBSPL_SYS_SYSTM_H +#define _LIBSPL_SYS_SYSTM_H + +uint64_t libspl_physmem(void); + +#define physmem libspl_physmem() + +#endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/taskq.h b/sys/contrib/openzfs/lib/libspl/include/sys/taskq.h new file mode 100644 index 000000000000..fbe3f388c05f --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/taskq.h @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_TASKQ_H +#define _SYS_TASKQ_H + +#include <pthread.h> +#include <stdint.h> +#include <sys/mutex.h> +#include <sys/rwlock.h> +#include <sys/condvar.h> + +/* + * Task queues + */ + +#define TASKQ_NAMELEN 31 + +typedef uintptr_t taskqid_t; +typedef void (task_func_t)(void *); + +typedef struct taskq_ent { + struct taskq_ent *tqent_next; + struct taskq_ent *tqent_prev; + task_func_t *tqent_func; + void *tqent_arg; + uintptr_t tqent_flags; +} taskq_ent_t; + +typedef struct taskq { + char tq_name[TASKQ_NAMELEN + 1]; + kmutex_t tq_lock; + krwlock_t tq_threadlock; + kcondvar_t tq_dispatch_cv; + kcondvar_t tq_wait_cv; + kthread_t **tq_threadlist; + int tq_flags; + int tq_active; + int tq_nthreads; + int tq_nalloc; + int tq_minalloc; + int tq_maxalloc; + kcondvar_t tq_maxalloc_cv; + int tq_maxalloc_wait; + taskq_ent_t *tq_freelist; + taskq_ent_t tq_task; +} taskq_t; + +#define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */ + +#define TASKQ_PREPOPULATE 0x0001 +#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */ +#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */ +#define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */ +#define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */ + +#define TQ_SLEEP KM_SLEEP /* Can block for memory */ +#define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */ +#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */ +#define TQ_FRONT 0x08 /* Queue in front */ + +#define TASKQID_INVALID ((taskqid_t)0) + +extern taskq_t *_system_taskq(void); +extern taskq_t *_system_delay_taskq(void); + +#define system_taskq _system_taskq() +#define system_delay_taskq _system_delay_taskq() + +extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t); +extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t, + kthread_t ***); +#define taskq_create_proc(a, b, c, d, e, p, f) \ + (taskq_create(a, b, c, d, e, f)) +#define taskq_create_sysdc(a, b, d, e, p, dc, f) \ + ((void) sizeof (dc), taskq_create(a, b, maxclsyspri, d, e, f)) +extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t); +extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t, + clock_t); +extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t, + taskq_ent_t *); +extern int taskq_empty_ent(taskq_ent_t *); +extern void taskq_init_ent(taskq_ent_t *); +extern void taskq_destroy(taskq_t *); +extern void taskq_wait(taskq_t *); +extern void taskq_wait_id(taskq_t *, taskqid_t); +extern void taskq_wait_outstanding(taskq_t *, taskqid_t); +extern int taskq_member(taskq_t *, kthread_t *); +extern taskq_t *taskq_of_curthread(void); +extern int taskq_cancel_id(taskq_t *, taskqid_t); +extern void system_taskq_init(void); +extern void system_taskq_fini(void); + +#endif /* _SYS_TASKQ_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/thread.h b/sys/contrib/openzfs/lib/libspl/include/sys/thread.h new file mode 100644 index 000000000000..6390c5bfd863 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/thread.h @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_THREAD_H +#define _SYS_THREAD_H + +#include <pthread.h> + +/* + * Threads. + */ +typedef pthread_t kthread_t; + +#define TS_RUN 0x00000002 +#define TS_JOINABLE 0x00000004 + +#define curthread ((void *)(uintptr_t)pthread_self()) +#define getcomm() "unknown" + +#define thread_create_named(name, stk, stksize, func, arg, len, \ + pp, state, pri) \ + zk_thread_create(name, func, arg, stksize, state) +#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \ + zk_thread_create(#func, func, arg, stksize, state) +#define thread_exit() pthread_exit(NULL) +#define thread_join(t) pthread_join((pthread_t)(t), NULL) + +#define newproc(f, a, cid, pri, ctp, pid) (ENOSYS) +/* + * Check if the current thread is a memory reclaim thread. + * Always returns false in userspace (no memory reclaim thread). + */ +#define current_is_reclaim_thread() (0) + +/* in libzpool, p0 exists only to have its address taken */ +typedef void (proc_t)(void); +extern void p0(void); + +#define curproc (&p0) + +#define PS_NONE -1 + +extern kthread_t *zk_thread_create(const char *name, void (*func)(void *), + void *arg, size_t stksize, int state); + +#define issig() (FALSE) + +#define KPREEMPT_SYNC (-1) + +#define kpreempt(x) sched_yield() +#define kpreempt_disable() ((void)0) +#define kpreempt_enable() ((void)0) + +#endif /* _SYS_THREAD_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/timer.h b/sys/contrib/openzfs/lib/libspl/include/sys/timer.h new file mode 100644 index 000000000000..850d11f063c3 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/timer.h @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SPL_TIMER_H +#define _SPL_TIMER_H + +#include <sys/time.h> + +#define ddi_get_lbolt() (gethrtime() >> 23) +#define ddi_get_lbolt64() (gethrtime() >> 23) +#define hz 119 /* frequency when using gethrtime() >> 23 for lbolt */ + +#define ddi_time_before(a, b) (a < b) +#define ddi_time_after(a, b) ddi_time_before(b, a) +#define ddi_time_before_eq(a, b) (!ddi_time_after(a, b)) +#define ddi_time_after_eq(a, b) ddi_time_before_eq(b, a) + +#define ddi_time_before64(a, b) (a < b) +#define ddi_time_after64(a, b) ddi_time_before64(b, a) +#define ddi_time_before_eq64(a, b) (!ddi_time_after64(a, b)) +#define ddi_time_after_eq64(a, b) ddi_time_before_eq64(b, a) + +extern void delay(clock_t ticks); + +#define SEC_TO_TICK(sec) ((sec) * hz) +#define MSEC_TO_TICK(msec) (howmany((hrtime_t)(msec) * hz, MILLISEC)) +#define USEC_TO_TICK(usec) (howmany((hrtime_t)(usec) * hz, MICROSEC)) +#define NSEC_TO_TICK(nsec) (howmany((hrtime_t)(nsec) * hz, NANOSEC)) + +#define usleep_range(min, max) \ + do { \ + struct timespec ts; \ + ts.tv_sec = min / MICROSEC; \ + ts.tv_nsec = USEC2NSEC(min); \ + (void) nanosleep(&ts, NULL); \ + } while (0) + +#endif /* _SPL_TIMER_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/trace.h b/sys/contrib/openzfs/lib/libspl/include/sys/trace.h new file mode 100644 index 000000000000..17b812faed20 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/trace.h @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_TRACE_H +#define _SYS_TRACE_H + +/* + * DTrace SDT probes have different signatures in userland than they do in + * the kernel. If they're being used in kernel code, re-define them out of + * existence for their counterparts in libzpool. + * + * Here's an example of how to use the set-error probes in userland: + * zfs$target:::set-error /arg0 == EBUSY/ {stack();} + * + * Here's an example of how to use DTRACE_PROBE probes in userland: + * If there is a probe declared as follows: + * DTRACE_PROBE2(zfs__probe_name, uint64_t, blkid, dnode_t *, dn); + * Then you can use it as follows: + * zfs$target:::probe2 /copyinstr(arg0) == "zfs__probe_name"/ + * {printf("%u %p\n", arg1, arg2);} + */ + +#ifdef DTRACE_PROBE +#undef DTRACE_PROBE +#endif /* DTRACE_PROBE */ +#define DTRACE_PROBE(a) + +#ifdef DTRACE_PROBE1 +#undef DTRACE_PROBE1 +#endif /* DTRACE_PROBE1 */ +#define DTRACE_PROBE1(a, b, c) + +#ifdef DTRACE_PROBE2 +#undef DTRACE_PROBE2 +#endif /* DTRACE_PROBE2 */ +#define DTRACE_PROBE2(a, b, c, d, e) + +#ifdef DTRACE_PROBE3 +#undef DTRACE_PROBE3 +#endif /* DTRACE_PROBE3 */ +#define DTRACE_PROBE3(a, b, c, d, e, f, g) + +#ifdef DTRACE_PROBE4 +#undef DTRACE_PROBE4 +#endif /* DTRACE_PROBE4 */ +#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i) + +#endif /* _SYS_TRACE_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/trace_spl.h b/sys/contrib/openzfs/lib/libspl/include/sys/trace_spl.h deleted file mode 100644 index b80d288f7332..000000000000 --- a/sys/contrib/openzfs/lib/libspl/include/sys/trace_spl.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Here to keep the libspl build happy */ - -#ifndef _LIBSPL_SPL_TRACE_H -#define _LIBSPL_SPL_TRACE_H - -/* - * The set-error SDT probe is extra static, in that we declare its fake - * function literally, rather than with the DTRACE_PROBE1() macro. This is - * necessary so that SET_ERROR() can evaluate to a value, which wouldn't - * be possible if it required multiple statements (to declare the function - * and then call it). - * - * SET_ERROR() uses the comma operator so that it can be used without much - * additional code. For example, "return (EINVAL);" becomes - * "return (SET_ERROR(EINVAL));". Note that the argument will be evaluated - * twice, so it should not have side effects (e.g. something like: - * "return (SET_ERROR(log_error(EINVAL, info)));" would log the error twice). - */ -#undef SET_ERROR -#define SET_ERROR(err) \ - (__set_error(__FILE__, __func__, __LINE__, err), err) - - -#endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/trace_zfs.h b/sys/contrib/openzfs/lib/libspl/include/sys/trace_zfs.h deleted file mode 100644 index 87ed5ad3c3be..000000000000 --- a/sys/contrib/openzfs/lib/libspl/include/sys/trace_zfs.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Here to keep the libspl build happy */ - -#ifndef _LIBSPL_ZFS_TRACE_H -#define _LIBSPL_ZFS_TRACE_H - -/* - * The set-error SDT probe is extra static, in that we declare its fake - * function literally, rather than with the DTRACE_PROBE1() macro. This is - * necessary so that SET_ERROR() can evaluate to a value, which wouldn't - * be possible if it required multiple statements (to declare the function - * and then call it). - * - * SET_ERROR() uses the comma operator so that it can be used without much - * additional code. For example, "return (EINVAL);" becomes - * "return (SET_ERROR(EINVAL));". Note that the argument will be evaluated - * twice, so it should not have side effects (e.g. something like: - * "return (SET_ERROR(log_error(EINVAL, info)));" would log the error twice). - */ -#undef SET_ERROR -#define SET_ERROR(err) \ - (__set_error(__FILE__, __func__, __LINE__, err), err) - - -#endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/tsd.h b/sys/contrib/openzfs/lib/libspl/include/sys/tsd.h new file mode 100644 index 000000000000..fa91519b3de5 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/include/sys/tsd.h @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef _SYS_TSD_H +#define _SYS_TSD_H + +#include <pthread.h> + +/* + * Thread-specific data + */ +#define tsd_get(k) pthread_getspecific(k) +#define tsd_set(k, v) pthread_setspecific(k, v) +#define tsd_create(kp, d) pthread_key_create((pthread_key_t *)kp, d) +#define tsd_destroy(kp) /* nothing */ + +#endif /* _SYS_MUTEX_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/tunables.h b/sys/contrib/openzfs/lib/libspl/include/sys/tunables.h index 5d9bb3d71a4a..d93425733709 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/tunables.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/tunables.h @@ -25,7 +25,8 @@ */ #ifndef _SYS_TUNABLES_H -#define _SYS_TUNABLES_H +//#define _SYS_TUNABLES_H extern __attribute__((visibility("hidden"))) +#define _SYS_TUNABLES_H extern typedef enum { ZFS_TUNABLE_TYPE_INT, @@ -49,12 +50,14 @@ typedef struct zfs_tunable { const char *zt_desc; } zfs_tunable_t; -int zfs_tunable_set(const zfs_tunable_t *tunable, const char *val); -int zfs_tunable_get(const zfs_tunable_t *tunable, char *val, size_t valsz); +_SYS_TUNABLES_H int zfs_tunable_set(const zfs_tunable_t *tunable, + const char *val); +_SYS_TUNABLES_H int zfs_tunable_get(const zfs_tunable_t *tunable, char *val, + size_t valsz); -const zfs_tunable_t *zfs_tunable_lookup(const char *name); +_SYS_TUNABLES_H const zfs_tunable_t *zfs_tunable_lookup(const char *name); typedef int (*zfs_tunable_iter_t)(const zfs_tunable_t *tunable, void *arg); -void zfs_tunable_iter(zfs_tunable_iter_t cb, void *arg); +_SYS_TUNABLES_H void zfs_tunable_iter(zfs_tunable_iter_t cb, void *arg); #endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/types.h b/sys/contrib/openzfs/lib/libspl/include/sys/types.h index f4bb85c7942e..9af20d781674 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/types.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/types.h @@ -50,4 +50,8 @@ typedef int projid_t; #include <sys/param.h> /* for NBBY */ +#ifdef __FreeBSD__ +typedef off_t loff_t; +#endif + #endif diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/vnode.h b/sys/contrib/openzfs/lib/libspl/include/sys/vnode.h index 49afe12c52b1..ed9901eede22 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/vnode.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/vnode.h @@ -25,7 +25,36 @@ * Use is subject to license terms. */ -#ifndef _LIBSPL_SYS_VNODE_H -#define _LIBSPL_SYS_VNODE_H +#ifndef _SYS_VNODE_H +#define _SYS_VNODE_H -#endif /* _LIBSPL_SYS_VNODE_H */ +typedef struct vattr { + uint_t va_mask; /* bit-mask of attributes */ + u_offset_t va_size; /* file size in bytes */ +} vattr_t; + +#define AT_MODE 0x00002 +#define AT_UID 0x00004 +#define AT_GID 0x00008 +#define AT_FSID 0x00010 +#define AT_NODEID 0x00020 +#define AT_NLINK 0x00040 +#define AT_SIZE 0x00080 +#define AT_ATIME 0x00100 +#define AT_MTIME 0x00200 +#define AT_CTIME 0x00400 +#define AT_RDEV 0x00800 +#define AT_BLKSIZE 0x01000 +#define AT_NBLOCKS 0x02000 +#define AT_SEQ 0x08000 +#define AT_XVATTR 0x10000 + +#define ATTR_XVATTR AT_XVATTR + +#define CRCREAT 0 + +#define F_FREESP 11 +#define FIGNORECASE 0x80000 /* request case-insensitive lookups */ + + +#endif /* _SYS_VNODE_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/zone.h b/sys/contrib/openzfs/lib/libspl/include/sys/zone.h index f4037b4875a9..179cc004fdb8 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/zone.h +++ b/sys/contrib/openzfs/lib/libspl/include/sys/zone.h @@ -21,11 +21,19 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ -#ifndef _LIBSPL_SYS_ZONE_H -#define _LIBSPL_SYS_ZONE_H +#ifndef _SYS_ZONE_H +#define _SYS_ZONE_H -#endif +#define zone_dataset_visible(x, y) (1) + +#define INGLOBALZONE(z) (1) + +extern uint32_t zone_get_hostid(void *zonep); + +#endif /* _SYS_ZONE_H */ diff --git a/sys/contrib/openzfs/lib/libspl/include/umem.h b/sys/contrib/openzfs/lib/libspl/include/umem.h index 3e44610e4e21..1b79fee56d23 100644 --- a/sys/contrib/openzfs/lib/libspl/include/umem.h +++ b/sys/contrib/openzfs/lib/libspl/include/umem.h @@ -42,6 +42,7 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <errno.h> #ifdef __cplusplus extern "C" { diff --git a/sys/contrib/openzfs/lib/libspl/kmem.c b/sys/contrib/openzfs/lib/libspl/kmem.c new file mode 100644 index 000000000000..c64e94597cf4 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/kmem.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc. + */ + +#include <sys/kmem.h> + +char * +kmem_vasprintf(const char *fmt, va_list adx) +{ + char *buf = NULL; + va_list adx_copy; + + va_copy(adx_copy, adx); + VERIFY(vasprintf(&buf, fmt, adx_copy) != -1); + va_end(adx_copy); + + return (buf); +} + +char * +kmem_asprintf(const char *fmt, ...) +{ + char *buf = NULL; + va_list adx; + + va_start(adx, fmt); + VERIFY(vasprintf(&buf, fmt, adx) != -1); + va_end(adx); + + return (buf); +} + +/* + * kmem_scnprintf() will return the number of characters that it would have + * printed whenever it is limited by value of the size variable, rather than + * the number of characters that it did print. This can cause misbehavior on + * subsequent uses of the return value, so we define a safe version that will + * return the number of characters actually printed, minus the NULL format + * character. Subsequent use of this by the safe string functions is safe + * whether it is snprintf(), strlcat() or strlcpy(). + */ +int +kmem_scnprintf(char *restrict str, size_t size, const char *restrict fmt, ...) +{ + int n; + va_list ap; + + /* Make the 0 case a no-op so that we do not return -1 */ + if (size == 0) + return (0); + + va_start(ap, fmt); + n = vsnprintf(str, size, fmt, ap); + va_end(ap); + + if (n >= size) + n = size - 1; + + return (n); +} + +fstrans_cookie_t +spl_fstrans_mark(void) +{ + return ((fstrans_cookie_t)0); +} + +void +spl_fstrans_unmark(fstrans_cookie_t cookie) +{ + (void) cookie; +} + +int +kmem_cache_reap_active(void) +{ + return (0); +} diff --git a/sys/contrib/openzfs/lib/libspl/kstat.c b/sys/contrib/openzfs/lib/libspl/kstat.c new file mode 100644 index 000000000000..af4b870edadf --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/kstat.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc. + */ + +#include <sys/kstat.h> + +/* + * ========================================================================= + * kstats + * ========================================================================= + */ +kstat_t * +kstat_create(const char *module, int instance, const char *name, + const char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag) +{ + (void) module, (void) instance, (void) name, (void) class, (void) type, + (void) ndata, (void) ks_flag; + return (NULL); +} + +void +kstat_install(kstat_t *ksp) +{ + (void) ksp; +} + +void +kstat_delete(kstat_t *ksp) +{ + (void) ksp; +} + +void +kstat_set_raw_ops(kstat_t *ksp, + int (*headers)(char *buf, size_t size), + int (*data)(char *buf, size_t size, void *data), + void *(*addr)(kstat_t *ksp, loff_t index)) +{ + (void) ksp, (void) headers, (void) data, (void) addr; +} diff --git a/sys/contrib/openzfs/lib/libspl/libspl.c b/sys/contrib/openzfs/lib/libspl/libspl.c new file mode 100644 index 000000000000..208b3e428536 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/libspl.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc. + * Copyright (c) 2025, Rob Norris <robn@despairlabs.com> + */ + +#include <libspl.h> +#include <assert.h> +#include <unistd.h> +#include <sys/misc.h> +#include <sys/systm.h> +#include <sys/utsname.h> +#include "libspl_impl.h" + +static uint64_t hw_physmem = 0; +static struct utsname hw_utsname = {}; + +uint64_t +libspl_physmem(void) +{ + return (hw_physmem); +} + +utsname_t * +utsname(void) +{ + return (&hw_utsname); +} + +void +libspl_init(void) +{ + hw_physmem = sysconf(_SC_PHYS_PAGES); + + VERIFY0(uname(&hw_utsname)); + + random_init(); +} + +void +libspl_fini(void) +{ + random_fini(); +} diff --git a/sys/contrib/openzfs/lib/libspl/libspl_impl.h b/sys/contrib/openzfs/lib/libspl/libspl_impl.h index 39392da09ef5..446801f2564b 100644 --- a/sys/contrib/openzfs/lib/libspl/libspl_impl.h +++ b/sys/contrib/openzfs/lib/libspl/libspl_impl.h @@ -21,5 +21,12 @@ * CDDL HEADER END */ +#ifndef _LIBSPL_IMPL_H +#define _LIBSPL_IMPL_H extern ssize_t getexecname_impl(char *execname); + +extern void random_init(void); +extern void random_fini(void); + +#endif diff --git a/sys/contrib/openzfs/lib/libspl/mutex.c b/sys/contrib/openzfs/lib/libspl/mutex.c new file mode 100644 index 000000000000..36e5bec396ed --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/mutex.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc. + */ + +#include <assert.h> +#include <pthread.h> +#include <string.h> +#include <errno.h> +#include <sys/mutex.h> + +/* + * ========================================================================= + * mutexes + * ========================================================================= + */ + +void +mutex_init(kmutex_t *mp, char *name, int type, void *cookie) +{ + (void) name, (void) type, (void) cookie; + VERIFY0(pthread_mutex_init(&mp->m_lock, NULL)); + memset(&mp->m_owner, 0, sizeof (pthread_t)); +} + +void +mutex_destroy(kmutex_t *mp) +{ + VERIFY0(pthread_mutex_destroy(&mp->m_lock)); +} + +void +mutex_enter(kmutex_t *mp) +{ + VERIFY0(pthread_mutex_lock(&mp->m_lock)); + mp->m_owner = pthread_self(); +} + +int +mutex_enter_check_return(kmutex_t *mp) +{ + int error = pthread_mutex_lock(&mp->m_lock); + if (error == 0) + mp->m_owner = pthread_self(); + return (error); +} + +int +mutex_tryenter(kmutex_t *mp) +{ + int error = pthread_mutex_trylock(&mp->m_lock); + if (error == 0) { + mp->m_owner = pthread_self(); + return (1); + } else { + VERIFY3S(error, ==, EBUSY); + return (0); + } +} + +void +mutex_exit(kmutex_t *mp) +{ + memset(&mp->m_owner, 0, sizeof (pthread_t)); + VERIFY0(pthread_mutex_unlock(&mp->m_lock)); +} diff --git a/sys/contrib/openzfs/lib/libspl/procfs_list.c b/sys/contrib/openzfs/lib/libspl/procfs_list.c new file mode 100644 index 000000000000..0ce327db6343 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/procfs_list.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc. + */ + +#include <assert.h> +#include <pthread.h> +#include <stddef.h> +#include <sys/procfs_list.h> +#include <sys/mutex.h> +#include <sys/list.h> + +/* + * ========================================================================= + * procfs list + * ========================================================================= + */ + +void +seq_printf(struct seq_file *m, const char *fmt, ...) +{ + (void) m, (void) fmt; +} + +void +procfs_list_install(const char *module, + const char *submodule, + const char *name, + mode_t mode, + procfs_list_t *procfs_list, + int (*show)(struct seq_file *f, void *p), + int (*show_header)(struct seq_file *f), + int (*clear)(procfs_list_t *procfs_list), + size_t procfs_list_node_off) +{ + (void) module, (void) submodule, (void) name, (void) mode, (void) show, + (void) show_header, (void) clear; + mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL); + list_create(&procfs_list->pl_list, + procfs_list_node_off + sizeof (procfs_list_node_t), + procfs_list_node_off + offsetof(procfs_list_node_t, pln_link)); + procfs_list->pl_next_id = 1; + procfs_list->pl_node_offset = procfs_list_node_off; +} + +void +procfs_list_uninstall(procfs_list_t *procfs_list) +{ + (void) procfs_list; +} + +void +procfs_list_destroy(procfs_list_t *procfs_list) +{ + ASSERT(list_is_empty(&procfs_list->pl_list)); + list_destroy(&procfs_list->pl_list); + mutex_destroy(&procfs_list->pl_lock); +} + +#define NODE_ID(procfs_list, obj) \ + (((procfs_list_node_t *)(((char *)obj) + \ + (procfs_list)->pl_node_offset))->pln_id) + +void +procfs_list_add(procfs_list_t *procfs_list, void *p) +{ + ASSERT(MUTEX_HELD(&procfs_list->pl_lock)); + NODE_ID(procfs_list, p) = procfs_list->pl_next_id++; + list_insert_tail(&procfs_list->pl_list, p); +} diff --git a/sys/contrib/openzfs/lib/libspl/random.c b/sys/contrib/openzfs/lib/libspl/random.c new file mode 100644 index 000000000000..c6f0ee7ae0f7 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/random.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc. + */ + +#include <stdint.h> +#include <fcntl.h> +#include <assert.h> +#include <sys/random.h> +#include "libspl_impl.h" + +#define RANDOM_PATH "/dev/random" +#define URANDOM_PATH "/dev/urandom" + +static int random_fd = -1, urandom_fd = -1; + +static boolean_t force_pseudo = B_FALSE; + +void +random_init(void) +{ + /* Handle multiple calls. */ + if (random_fd != -1) { + ASSERT3U(urandom_fd, !=, -1); + return; + } + + VERIFY((random_fd = open(RANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1); + VERIFY((urandom_fd = open(URANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1); +} + +void +random_fini(void) +{ + close(random_fd); + close(urandom_fd); + + random_fd = -1; + urandom_fd = -1; +} + +void +random_force_pseudo(boolean_t onoff) +{ + force_pseudo = onoff; +} + +static int +random_get_bytes_common(uint8_t *ptr, size_t len, int fd) +{ + size_t resid = len; + ssize_t bytes; + + ASSERT(fd != -1); + + while (resid != 0) { + bytes = read(fd, ptr, resid); + ASSERT3S(bytes, >=, 0); + ptr += bytes; + resid -= bytes; + } + + return (0); +} + +int +random_get_bytes(uint8_t *ptr, size_t len) +{ + if (force_pseudo) + return (random_get_pseudo_bytes(ptr, len)); + return (random_get_bytes_common(ptr, len, random_fd)); +} + +int +random_get_pseudo_bytes(uint8_t *ptr, size_t len) +{ + return (random_get_bytes_common(ptr, len, urandom_fd)); +} diff --git a/sys/contrib/openzfs/lib/libspl/rwlock.c b/sys/contrib/openzfs/lib/libspl/rwlock.c new file mode 100644 index 000000000000..3712829ef594 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/rwlock.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc. + */ + +#include <assert.h> +#include <pthread.h> +#include <errno.h> +#include <atomic.h> +#include <sys/rwlock.h> + +/* + * ========================================================================= + * rwlocks + * ========================================================================= + */ + +void +rw_init(krwlock_t *rwlp, char *name, int type, void *arg) +{ + (void) name, (void) type, (void) arg; + VERIFY0(pthread_rwlock_init(&rwlp->rw_lock, NULL)); + rwlp->rw_readers = 0; + rwlp->rw_owner = 0; +} + +void +rw_destroy(krwlock_t *rwlp) +{ + VERIFY0(pthread_rwlock_destroy(&rwlp->rw_lock)); +} + +void +rw_enter(krwlock_t *rwlp, krw_t rw) +{ + if (rw == RW_READER) { + VERIFY0(pthread_rwlock_rdlock(&rwlp->rw_lock)); + atomic_inc_uint(&rwlp->rw_readers); + } else { + VERIFY0(pthread_rwlock_wrlock(&rwlp->rw_lock)); + rwlp->rw_owner = pthread_self(); + } +} + +void +rw_exit(krwlock_t *rwlp) +{ + if (RW_READ_HELD(rwlp)) + atomic_dec_uint(&rwlp->rw_readers); + else + rwlp->rw_owner = 0; + + VERIFY0(pthread_rwlock_unlock(&rwlp->rw_lock)); +} + +int +rw_tryenter(krwlock_t *rwlp, krw_t rw) +{ + int error; + + if (rw == RW_READER) + error = pthread_rwlock_tryrdlock(&rwlp->rw_lock); + else + error = pthread_rwlock_trywrlock(&rwlp->rw_lock); + + if (error == 0) { + if (rw == RW_READER) + atomic_inc_uint(&rwlp->rw_readers); + else + rwlp->rw_owner = pthread_self(); + + return (1); + } + + VERIFY3S(error, ==, EBUSY); + + return (0); +} + +int +rw_tryupgrade(krwlock_t *rwlp) +{ + (void) rwlp; + return (0); +} diff --git a/sys/contrib/openzfs/lib/libspl/sid.c b/sys/contrib/openzfs/lib/libspl/sid.c new file mode 100644 index 000000000000..b7d5b5f2e778 --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/sid.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc. + */ + +#include <sys/sid.h> +#include <umem.h> + +ksiddomain_t * +ksid_lookupdomain(const char *dom) +{ + ksiddomain_t *kd; + + kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL); + kd->kd_name = strdup(dom); + return (kd); +} + +void +ksiddomain_rele(ksiddomain_t *ksid) +{ + free(ksid->kd_name); + umem_free(ksid, sizeof (ksiddomain_t)); +} diff --git a/sys/contrib/openzfs/lib/libzpool/taskq.c b/sys/contrib/openzfs/lib/libspl/taskq.c index 0457de21fa18..043f70225551 100644 --- a/sys/contrib/openzfs/lib/libzpool/taskq.c +++ b/sys/contrib/openzfs/lib/libspl/taskq.c @@ -29,11 +29,27 @@ * Copyright (c) 2014 by Delphix. All rights reserved. */ -#include <sys/zfs_context.h> +#include <sys/sysmacros.h> +#include <sys/timer.h> +#include <sys/types.h> +#include <sys/thread.h> +#include <sys/taskq.h> +#include <sys/kmem.h> + +static taskq_t *__system_taskq = NULL; +static taskq_t *__system_delay_taskq = NULL; + +taskq_t +*_system_taskq(void) +{ + return (__system_taskq); +} -int taskq_now; -taskq_t *system_taskq; -taskq_t *system_delay_taskq; +taskq_t +*_system_delay_taskq(void) +{ + return (__system_delay_taskq); +} static pthread_key_t taskq_tsd; @@ -106,11 +122,6 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags) { taskq_ent_t *t; - if (taskq_now) { - func(arg); - return (1); - } - mutex_enter(&tq->tq_lock); ASSERT(tq->tq_flags & TASKQ_ACTIVE); if ((t = task_alloc(tq, tqflags)) == NULL) { @@ -373,9 +384,6 @@ taskq_member(taskq_t *tq, kthread_t *t) { int i; - if (taskq_now) - return (1); - for (i = 0; i < tq->tq_nthreads; i++) if (tq->tq_threadlist[i] == t) return (1); @@ -400,18 +408,18 @@ void system_taskq_init(void) { VERIFY0(pthread_key_create(&taskq_tsd, NULL)); - system_taskq = taskq_create("system_taskq", 64, maxclsyspri, 4, 512, + __system_taskq = taskq_create("system_taskq", 64, maxclsyspri, 4, 512, TASKQ_DYNAMIC | TASKQ_PREPOPULATE); - system_delay_taskq = taskq_create("delay_taskq", 4, maxclsyspri, 4, + __system_delay_taskq = taskq_create("delay_taskq", 4, maxclsyspri, 4, 512, TASKQ_DYNAMIC | TASKQ_PREPOPULATE); } void system_taskq_fini(void) { - taskq_destroy(system_taskq); - system_taskq = NULL; /* defensive */ - taskq_destroy(system_delay_taskq); - system_delay_taskq = NULL; + taskq_destroy(__system_taskq); + __system_taskq = NULL; /* defensive */ + taskq_destroy(__system_delay_taskq); + __system_delay_taskq = NULL; VERIFY0(pthread_key_delete(taskq_tsd)); } diff --git a/sys/contrib/openzfs/lib/libspl/thread.c b/sys/contrib/openzfs/lib/libspl/thread.c new file mode 100644 index 000000000000..f00e0a01a06b --- /dev/null +++ b/sys/contrib/openzfs/lib/libspl/thread.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. + * Copyright (c) 2025, Klara, Inc. + */ + +#include <assert.h> +#include <pthread.h> +#include <string.h> +#include <sys/thread.h> + +/* this only exists to have its address taken */ +void p0(void) {} + +/* + * ========================================================================= + * threads + * ========================================================================= + * + * TS_STACK_MIN is dictated by the minimum allowed pthread stack size. While + * TS_STACK_MAX is somewhat arbitrary, it was selected to be large enough for + * the expected stack depth while small enough to avoid exhausting address + * space with high thread counts. + */ +#define TS_STACK_MIN MAX(PTHREAD_STACK_MIN, 32768) +#define TS_STACK_MAX (256 * 1024) + +struct zk_thread_wrapper { + void (*func)(void *); + void *arg; +}; + +static void * +zk_thread_wrapper(void *arg) +{ + struct zk_thread_wrapper ztw; + memcpy(&ztw, arg, sizeof (ztw)); + free(arg); + ztw.func(ztw.arg); + return (NULL); +} + +kthread_t * +zk_thread_create(const char *name, void (*func)(void *), void *arg, + size_t stksize, int state) +{ + pthread_attr_t attr; + pthread_t tid; + char *stkstr; + struct zk_thread_wrapper *ztw; + int detachstate = PTHREAD_CREATE_DETACHED; + + VERIFY0(pthread_attr_init(&attr)); + + if (state & TS_JOINABLE) + detachstate = PTHREAD_CREATE_JOINABLE; + + VERIFY0(pthread_attr_setdetachstate(&attr, detachstate)); + + /* + * We allow the default stack size in user space to be specified by + * setting the ZFS_STACK_SIZE environment variable. This allows us + * the convenience of observing and debugging stack overruns in + * user space. Explicitly specified stack sizes will be honored. + * The usage of ZFS_STACK_SIZE is discussed further in the + * ENVIRONMENT VARIABLES sections of the ztest(1) man page. + */ + if (stksize == 0) { + stkstr = getenv("ZFS_STACK_SIZE"); + + if (stkstr == NULL) + stksize = TS_STACK_MAX; + else + stksize = MAX(atoi(stkstr), TS_STACK_MIN); + } + + VERIFY3S(stksize, >, 0); + stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE); + + /* + * If this ever fails, it may be because the stack size is not a + * multiple of system page size. + */ + VERIFY0(pthread_attr_setstacksize(&attr, stksize)); + VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE)); + + VERIFY(ztw = malloc(sizeof (*ztw))); + ztw->func = func; + ztw->arg = arg; + VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw)); + VERIFY0(pthread_attr_destroy(&attr)); + + pthread_setname_np(tid, name); + + return ((void *)(uintptr_t)tid); +} diff --git a/sys/contrib/openzfs/lib/libuutil/libuutil.abi b/sys/contrib/openzfs/lib/libuutil/libuutil.abi index 2a740afa07ca..ca2bcdb57dbf 100644 --- a/sys/contrib/openzfs/lib/libuutil/libuutil.abi +++ b/sys/contrib/openzfs/lib/libuutil/libuutil.abi @@ -6,6 +6,8 @@ </elf-needed> <elf-function-symbols> <elf-symbol name='_sol_getmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_system_delay_taskq' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_system_taskq' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_add_16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_add_16_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_add_32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -144,6 +146,19 @@ <elf-symbol name='avl_update_gt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='avl_update_lt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='avl_walk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetgid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetgroups' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetngroups' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetruid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetuid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_broadcast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_signal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_timedwait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_timedwait_hires' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_wait_sig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='format_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='get_system_hostid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='get_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -151,8 +166,21 @@ <elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getzoneid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_asprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_cache_reap_active' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_scnprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_vasprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='ksid_lookupdomain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='ksiddomain_rele' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_delete' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_install' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_set_raw_ops' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libspl_assertf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libspl_backtrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='libspl_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='libspl_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='libspl_physmem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libspl_set_assert_ok' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='list_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='list_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -178,10 +206,52 @@ <elf-symbol name='membar_producer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='membar_sync' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='mkdirp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_enter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_enter_check_return' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_tryenter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='p0' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='print_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_install' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_uninstall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_force_pseudo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_get_bytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_get_pseudo_bytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_enter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_tryenter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_tryupgrade' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='seq_printf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='spl_fstrans_mark' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='spl_fstrans_unmark' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='spl_pagesize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='strlcat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='strlcpy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='system_taskq_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='system_taskq_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_cancel_id' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_create_synced' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_dispatch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_dispatch_delay' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_dispatch_ent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_empty_ent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_init_ent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_member' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_of_curthread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_wait_id' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_wait_outstanding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='utsname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='uu_avl_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='uu_avl_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='uu_avl_find' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -244,10 +314,7 @@ <elf-symbol name='uu_strerror' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='uu_strndup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='uu_zalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='zk_thread_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> </elf-function-symbols> <abi-instr address-size='64' path='lib/libspl/assert.c' language='LANG_C99'> <typedef-decl name='__pid_t' type-id='95e97e5e' id='3629bad8'/> @@ -616,7 +683,6 @@ <array-type-def dimensions='1' type-id='de572c22' size-in-bits='1472' id='6d3c2f42'> <subrange length='23' type-id='7359adad' id='fdd0f594'/> </array-type-def> - <type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/> <array-type-def dimensions='1' type-id='3a47d82b' size-in-bits='256' id='a133ec23'> <subrange length='4' type-id='7359adad' id='16fe7105'/> </array-type-def> @@ -635,8 +701,6 @@ <array-type-def dimensions='1' type-id='73d941c6' size-in-bits='8128' id='dc70ec0b'> <subrange length='127' type-id='7359adad' id='5ed08de5'/> </array-type-def> - <typedef-decl name='uint64_t' type-id='8910171f' id='9c313c2d'/> - <typedef-decl name='__uint64_t' type-id='7359adad' id='8910171f'/> <class-decl name='__sigset_t' size-in-bits='1024' is-struct='yes' naming-typedef-id='b9c97942' visibility='default' id='2616147f'> <data-member access='public' layout-offset-in-bits='0'> <var-decl name='__val' type-id='d2baa450' visibility='default'/> @@ -800,6 +864,230 @@ </function-decl> <type-decl name='unsigned long int' size-in-bits='64' id='7359adad'/> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/condvar.c' language='LANG_C99'> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='384' id='36d7f119'> + <subrange length='48' type-id='7359adad' id='8f6d2a81'/> + </array-type-def> + <type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/> + <type-decl name='long long unsigned int' size-in-bits='64' id='3a47d82b'/> + <array-type-def dimensions='1' type-id='f0981eeb' size-in-bits='64' id='0d532ec1'> + <subrange length='2' type-id='7359adad' id='52efc4ef'/> + </array-type-def> + <typedef-decl name='kcondvar_t' type-id='62fab762' id='29dbc0dd'/> + <class-decl name='kmutex' size-in-bits='384' is-struct='yes' visibility='default' id='f1cacfe1'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='m_lock' type-id='7a6844eb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='m_owner' type-id='4051f5e7' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='kmutex_t' type-id='f1cacfe1' id='b9eccc8f'/> + <typedef-decl name='hrtime_t' type-id='1eb56b1e' id='cebdd548'/> + <union-decl name='__atomic_wide_counter' size-in-bits='64' naming-typedef-id='f3b40860' visibility='default' id='613ce450'> + <data-member access='public'> + <var-decl name='__value64' type-id='3a47d82b' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__value32' type-id='e7f43f72' visibility='default'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f72'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__low' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='__high' type-id='f0981eeb' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='__atomic_wide_counter' type-id='613ce450' id='f3b40860'/> + <union-decl name='pthread_condattr_t' size-in-bits='32' naming-typedef-id='836265dd' visibility='default' id='33dd3aad'> + <data-member access='public'> + <var-decl name='__size' type-id='8e0573fd' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='95e97e5e' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_condattr_t' type-id='33dd3aad' id='836265dd'/> + <union-decl name='pthread_cond_t' size-in-bits='384' naming-typedef-id='62fab762' visibility='default' id='cbb12c12'> + <data-member access='public'> + <var-decl name='__data' type-id='c987b47c' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__size' type-id='36d7f119' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='1eb56b1e' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_cond_t' type-id='cbb12c12' id='62fab762'/> + <class-decl name='__pthread_cond_s' size-in-bits='384' is-struct='yes' visibility='default' id='c987b47c'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__wseq' type-id='f3b40860' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='__g1_start' type-id='f3b40860' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='__g_refs' type-id='0d532ec1' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='__g_size' type-id='0d532ec1' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='__g1_orig_size' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='__wrefs' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='__g_signals' type-id='0d532ec1' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='__clock_t' type-id='bd54fe1a' id='4d66c6d7'/> + <typedef-decl name='__time_t' type-id='bd54fe1a' id='65eda9c0'/> + <typedef-decl name='__suseconds_t' type-id='bd54fe1a' id='5b102a54'/> + <typedef-decl name='__clockid_t' type-id='95e97e5e' id='08f9a87a'/> + <typedef-decl name='__syscall_slong_t' type-id='bd54fe1a' id='03085adc'/> + <typedef-decl name='clock_t' type-id='4d66c6d7' id='4c3a2c61'/> + <typedef-decl name='clockid_t' type-id='08f9a87a' id='a1c3b834'/> + <class-decl name='timespec' size-in-bits='128' is-struct='yes' visibility='default' id='a9c79a1f'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tv_sec' type-id='65eda9c0' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tv_nsec' type-id='03085adc' visibility='default'/> + </data-member> + </class-decl> + <class-decl name='timeval' size-in-bits='128' is-struct='yes' visibility='default' id='2a693ac3'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tv_sec' type-id='65eda9c0' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tv_usec' type-id='5b102a54' visibility='default'/> + </data-member> + </class-decl> + <qualified-type-def type-id='836265dd' const='yes' id='7d24c58d'/> + <pointer-type-def type-id='7d24c58d' size-in-bits='64' id='a7e325e5'/> + <qualified-type-def type-id='a7e325e5' restrict='yes' id='4c428e67'/> + <qualified-type-def type-id='a9c79a1f' const='yes' id='cd087e36'/> + <pointer-type-def type-id='cd087e36' size-in-bits='64' id='e05e8614'/> + <qualified-type-def type-id='e05e8614' restrict='yes' id='0be2e71c'/> + <pointer-type-def type-id='29dbc0dd' size-in-bits='64' id='068c4f7e'/> + <pointer-type-def type-id='b9eccc8f' size-in-bits='64' id='78830f38'/> + <pointer-type-def type-id='62fab762' size-in-bits='64' id='db285b03'/> + <qualified-type-def type-id='db285b03' restrict='yes' id='2a468b41'/> + <qualified-type-def type-id='18c91f9e' restrict='yes' id='6e745582'/> + <pointer-type-def type-id='a9c79a1f' size-in-bits='64' id='3d83ba87'/> + <pointer-type-def type-id='2a693ac3' size-in-bits='64' id='896f1b83'/> + <qualified-type-def type-id='896f1b83' restrict='yes' id='4bcf44c1'/> + <qualified-type-def type-id='eaa32e2f' restrict='yes' id='1b7446cd'/> + <function-decl name='pthread_cond_init' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2a468b41'/> + <parameter type-id='4c428e67'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_cond_destroy' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='db285b03'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_cond_signal' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='db285b03'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_cond_broadcast' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='db285b03'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_cond_wait' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2a468b41'/> + <parameter type-id='6e745582'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_cond_timedwait' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2a468b41'/> + <parameter type-id='6e745582'/> + <parameter type-id='0be2e71c'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='clock_gettime' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a1c3b834'/> + <parameter type-id='3d83ba87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='gettimeofday' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='4bcf44c1'/> + <parameter type-id='1b7446cd'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_init' mangled-name='cv_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_init'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='26a90f95' name='name'/> + <parameter type-id='95e97e5e' name='type'/> + <parameter type-id='eaa32e2f' name='arg'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_destroy' mangled-name='cv_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_destroy'> + <parameter type-id='068c4f7e' name='cv'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_wait' mangled-name='cv_wait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_wait'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_wait_sig' mangled-name='cv_wait_sig' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_wait_sig'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_timedwait' mangled-name='cv_timedwait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_timedwait'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <parameter type-id='4c3a2c61' name='abstime'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_timedwait_hires' mangled-name='cv_timedwait_hires' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_timedwait_hires'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <parameter type-id='cebdd548' name='tim'/> + <parameter type-id='cebdd548' name='res'/> + <parameter type-id='95e97e5e' name='flag'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_signal' mangled-name='cv_signal' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_signal'> + <parameter type-id='068c4f7e' name='cv'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_broadcast' mangled-name='cv_broadcast' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_broadcast'> + <parameter type-id='068c4f7e' name='cv'/> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/cred.c' language='LANG_C99'> + <class-decl name='cred' is-struct='yes' visibility='default' is-declaration-only='yes' id='6739dd09'/> + <typedef-decl name='cred_t' type-id='6739dd09' id='a42f1a8f'/> + <typedef-decl name='__uid_t' type-id='f0981eeb' id='cc5fcceb'/> + <typedef-decl name='__gid_t' type-id='f0981eeb' id='d94ec6d9'/> + <typedef-decl name='gid_t' type-id='d94ec6d9' id='2bb2b96f'/> + <typedef-decl name='uid_t' type-id='cc5fcceb' id='354978ed'/> + <pointer-type-def type-id='a42f1a8f' size-in-bits='64' id='f89fcf80'/> + <pointer-type-def type-id='2bb2b96f' size-in-bits='64' id='b52814e6'/> + <class-decl name='cred' is-struct='yes' visibility='default' is-declaration-only='yes' id='6739dd09'/> + <function-decl name='crgetuid' mangled-name='crgetuid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crgetuid'> + <parameter type-id='f89fcf80' name='cr'/> + <return type-id='354978ed'/> + </function-decl> + <function-decl name='crgetngroups' mangled-name='crgetngroups' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crgetngroups'> + <parameter type-id='f89fcf80' name='cr'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='crgetgroups' mangled-name='crgetgroups' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crgetgroups'> + <parameter type-id='f89fcf80' name='cr'/> + <return type-id='b52814e6'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/getexecname.c' language='LANG_C99'> <function-decl name='getexecname' mangled-name='getexecname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getexecname'> <return type-id='80f4b756'/> @@ -809,6 +1097,176 @@ <return type-id='79a0948f'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/kmem.c' language='LANG_C99'> + <typedef-decl name='fstrans_cookie_t' type-id='95e97e5e' id='059934c1'/> + <qualified-type-def type-id='26a90f95' restrict='yes' id='266fe297'/> + <pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/> + <qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/> + <function-decl name='__vasprintf_chk' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='8c85230f'/> + <parameter type-id='95e97e5e'/> + <parameter type-id='9d26089a'/> + <parameter type-id='b7f2d5e6'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='kmem_vasprintf' mangled-name='kmem_vasprintf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_vasprintf'> + <parameter type-id='80f4b756' name='fmt'/> + <parameter type-id='b7f2d5e6' name='adx'/> + <return type-id='26a90f95'/> + </function-decl> + <function-decl name='kmem_asprintf' mangled-name='kmem_asprintf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_asprintf'> + <parameter type-id='80f4b756' name='fmt'/> + <parameter is-variadic='yes'/> + <return type-id='26a90f95'/> + </function-decl> + <function-decl name='kmem_scnprintf' mangled-name='kmem_scnprintf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_scnprintf'> + <parameter type-id='266fe297' name='str'/> + <parameter type-id='b59d7dce' name='size'/> + <parameter type-id='9d26089a' name='fmt'/> + <parameter is-variadic='yes'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='spl_fstrans_unmark' mangled-name='spl_fstrans_unmark' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spl_fstrans_unmark'> + <parameter type-id='059934c1' name='cookie'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='kmem_cache_reap_active' mangled-name='kmem_cache_reap_active' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_cache_reap_active'> + <return type-id='95e97e5e'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/kstat.c' language='LANG_C99'> + <class-decl name='kstat' size-in-bits='448' is-struct='yes' visibility='default' id='5f5c9d88'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ks_flags' type-id='d8bf0010' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ks_data' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ks_ndata' type-id='3502e3ff' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ks_data_size' type-id='b59d7dce' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='ks_update' type-id='8cf7b7e1' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='ks_private' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='ks_lock' type-id='eaa32e2f' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='kstat_t' type-id='5f5c9d88' id='dd12e024'/> + <typedef-decl name='uchar_t' type-id='002ac4a6' id='d8bf0010'/> + <typedef-decl name='__loff_t' type-id='724e4de6' id='00c9d214'/> + <typedef-decl name='loff_t' type-id='00c9d214' id='69bf7bee'/> + <pointer-type-def type-id='9d5d322a' size-in-bits='64' id='bbe97414'/> + <pointer-type-def type-id='05b3c714' size-in-bits='64' id='27cc5c36'/> + <pointer-type-def type-id='7a9ace65' size-in-bits='64' id='8cf7b7e1'/> + <pointer-type-def type-id='5f5c9d88' size-in-bits='64' id='0e87f9be'/> + <pointer-type-def type-id='dd12e024' size-in-bits='64' id='46e5e463'/> + <pointer-type-def type-id='527a97c5' size-in-bits='64' id='673f2af9'/> + <function-decl name='kstat_create' mangled-name='kstat_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_create'> + <parameter type-id='80f4b756' name='module'/> + <parameter type-id='95e97e5e' name='instance'/> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='80f4b756' name='class'/> + <parameter type-id='d8bf0010' name='type'/> + <parameter type-id='ee1f298e' name='ndata'/> + <parameter type-id='d8bf0010' name='ks_flag'/> + <return type-id='46e5e463'/> + </function-decl> + <function-decl name='kstat_install' mangled-name='kstat_install' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_install'> + <parameter type-id='46e5e463' name='ksp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='kstat_set_raw_ops' mangled-name='kstat_set_raw_ops' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_set_raw_ops'> + <parameter type-id='46e5e463' name='ksp'/> + <parameter type-id='bbe97414' name='headers'/> + <parameter type-id='27cc5c36' name='data'/> + <parameter type-id='673f2af9' name='addr'/> + <return type-id='48b5725f'/> + </function-decl> + <function-type size-in-bits='64' id='9d5d322a'> + <parameter type-id='26a90f95'/> + <parameter type-id='b59d7dce'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='05b3c714'> + <parameter type-id='26a90f95'/> + <parameter type-id='b59d7dce'/> + <parameter type-id='eaa32e2f'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='7a9ace65'> + <parameter type-id='0e87f9be'/> + <parameter type-id='95e97e5e'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='527a97c5'> + <parameter type-id='46e5e463'/> + <parameter type-id='69bf7bee'/> + <return type-id='eaa32e2f'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/libspl.c' language='LANG_C99'> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='520' id='5ddd38d2'> + <subrange length='65' type-id='7359adad' id='b50e2e4a'/> + </array-type-def> + <typedef-decl name='utsname_t' type-id='414a2ac6' id='5278297a'/> + <typedef-decl name='uint64_t' type-id='8910171f' id='9c313c2d'/> + <typedef-decl name='__uint64_t' type-id='7359adad' id='8910171f'/> + <class-decl name='utsname' size-in-bits='3120' is-struct='yes' visibility='default' id='414a2ac6'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='sysname' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='520'> + <var-decl name='nodename' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1040'> + <var-decl name='release' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1560'> + <var-decl name='version' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2080'> + <var-decl name='machine' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2600'> + <var-decl name='domainname' type-id='5ddd38d2' visibility='default'/> + </data-member> + </class-decl> + <pointer-type-def type-id='414a2ac6' size-in-bits='64' id='a6724cec'/> + <pointer-type-def type-id='5278297a' size-in-bits='64' id='5c7868ad'/> + <function-decl name='sysconf' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='95e97e5e'/> + <return type-id='bd54fe1a'/> + </function-decl> + <function-decl name='uname' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6724cec'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='libspl_physmem' mangled-name='libspl_physmem' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_physmem'> + <return type-id='9c313c2d'/> + </function-decl> + <function-decl name='utsname' mangled-name='utsname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='utsname'> + <return type-id='5c7868ad'/> + </function-decl> + <function-decl name='libspl_init' mangled-name='libspl_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_init'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='libspl_fini' mangled-name='libspl_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_fini'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='random_init' mangled-name='random_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_init'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='random_fini' mangled-name='random_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_fini'> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/list.c' language='LANG_C99'> <typedef-decl name='list_node_t' type-id='b0b5e45e' id='b21843b2'/> <typedef-decl name='list_t' type-id='e824dae9' id='0899125f'/> @@ -921,7 +1379,6 @@ <typedef-decl name='__mode_t' type-id='f0981eeb' id='e1c52942'/> <typedef-decl name='mode_t' type-id='e1c52942' id='d50d396c'/> <typedef-decl name='wchar_t' type-id='95e97e5e' id='928221d2'/> - <qualified-type-def type-id='26a90f95' restrict='yes' id='266fe297'/> <qualified-type-def type-id='928221d2' const='yes' id='effb3702'/> <pointer-type-def type-id='effb3702' size-in-bits='64' id='f077d3f8'/> <qualified-type-def type-id='f077d3f8' restrict='yes' id='598aab80'/> @@ -971,6 +1428,39 @@ <return type-id='95e97e5e'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/mutex.c' language='LANG_C99'> + <function-decl name='pthread_mutex_trylock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='18c91f9e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='mutex_init' mangled-name='mutex_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_init'> + <parameter type-id='78830f38' name='mp'/> + <parameter type-id='26a90f95' name='name'/> + <parameter type-id='95e97e5e' name='type'/> + <parameter type-id='eaa32e2f' name='cookie'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='mutex_destroy' mangled-name='mutex_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_destroy'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='mutex_enter' mangled-name='mutex_enter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_enter'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='mutex_enter_check_return' mangled-name='mutex_enter_check_return' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_enter_check_return'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='mutex_tryenter' mangled-name='mutex_tryenter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_tryenter'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='mutex_exit' mangled-name='mutex_exit' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_exit'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/os/linux/getexecname.c' language='LANG_C99'> <function-decl name='__readlink_chk' visibility='default' binding='global' size-in-bits='64'> <parameter type-id='9d26089a'/> @@ -981,7 +1471,6 @@ </function-decl> </abi-instr> <abi-instr address-size='64' path='lib/libspl/os/linux/gethostid.c' language='LANG_C99'> - <type-decl name='long long unsigned int' size-in-bits='64' id='3a47d82b'/> <function-decl name='fclose' visibility='default' binding='global' size-in-bits='64'> <parameter type-id='822cd80b'/> <return type-id='95e97e5e'/> @@ -992,27 +1481,6 @@ <parameter type-id='95e97e5e'/> <return type-id='3a47d82b'/> </function-decl> - <function-decl name='getenv' visibility='default' binding='global' size-in-bits='64'> - <parameter type-id='80f4b756'/> - <return type-id='26a90f95'/> - </function-decl> - <function-decl name='close' visibility='default' binding='global' size-in-bits='64'> - <parameter type-id='95e97e5e'/> - <return type-id='95e97e5e'/> - </function-decl> - <function-decl name='__open_too_many_args' visibility='default' binding='global' size-in-bits='64'> - <return type-id='48b5725f'/> - </function-decl> - <function-decl name='__open_missing_mode' visibility='default' binding='global' size-in-bits='64'> - <return type-id='48b5725f'/> - </function-decl> - <function-decl name='__read_chk' visibility='default' binding='global' size-in-bits='64'> - <parameter type-id='95e97e5e'/> - <parameter type-id='eaa32e2f'/> - <parameter type-id='b59d7dce'/> - <parameter type-id='b59d7dce'/> - <return type-id='79a0948f'/> - </function-decl> <function-decl name='get_system_hostid' mangled-name='get_system_hostid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_system_hostid'> <return type-id='7359adad'/> </function-decl> @@ -1123,21 +1591,10 @@ </data-member> </class-decl> <typedef-decl name='__dev_t' type-id='7359adad' id='35ed8932'/> - <typedef-decl name='__uid_t' type-id='f0981eeb' id='cc5fcceb'/> - <typedef-decl name='__gid_t' type-id='f0981eeb' id='d94ec6d9'/> <typedef-decl name='__ino64_t' type-id='7359adad' id='71288a47'/> <typedef-decl name='__nlink_t' type-id='7359adad' id='80f0b9df'/> <typedef-decl name='__blksize_t' type-id='bd54fe1a' id='d3f10a7f'/> <typedef-decl name='__blkcnt64_t' type-id='bd54fe1a' id='4e711bf1'/> - <typedef-decl name='__syscall_slong_t' type-id='bd54fe1a' id='03085adc'/> - <class-decl name='timespec' size-in-bits='128' is-struct='yes' visibility='default' id='a9c79a1f'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='tv_sec' type-id='65eda9c0' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='tv_nsec' type-id='03085adc' visibility='default'/> - </data-member> - </class-decl> <pointer-type-def type-id='0c544dc0' size-in-bits='64' id='394fc496'/> <pointer-type-def type-id='56fe4a37' size-in-bits='64' id='b6b61d2f'/> <qualified-type-def type-id='b6b61d2f' restrict='yes' id='3cad23cd'/> @@ -1202,14 +1659,294 @@ </function-decl> </abi-instr> <abi-instr address-size='64' path='lib/libspl/page.c' language='LANG_C99'> - <function-decl name='sysconf' visibility='default' binding='global' size-in-bits='64'> - <parameter type-id='95e97e5e'/> - <return type-id='bd54fe1a'/> - </function-decl> <function-decl name='spl_pagesize' mangled-name='spl_pagesize' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spl_pagesize'> <return type-id='b59d7dce'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/procfs_list.c' language='LANG_C99'> + <class-decl name='procfs_list' size-in-bits='768' is-struct='yes' visibility='default' id='0f4d3b87'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='pl_private' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='pl_lock' type-id='b9eccc8f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='pl_list' type-id='0899125f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='pl_next_id' type-id='9c313c2d' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='pl_node_offset' type-id='b59d7dce' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='procfs_list_t' type-id='0f4d3b87' id='e5b5a21b'/> + <class-decl name='seq_file' is-struct='yes' visibility='default' id='f3415517'/> + <pointer-type-def type-id='be39c944' size-in-bits='64' id='b5c3ae96'/> + <pointer-type-def type-id='86932239' size-in-bits='64' id='6255c89d'/> + <pointer-type-def type-id='cf9ec29d' size-in-bits='64' id='0131eb61'/> + <pointer-type-def type-id='e5b5a21b' size-in-bits='64' id='7f432372'/> + <pointer-type-def type-id='f3415517' size-in-bits='64' id='f8dc9def'/> + <function-decl name='seq_printf' mangled-name='seq_printf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='seq_printf'> + <parameter type-id='f8dc9def' name='m'/> + <parameter type-id='80f4b756' name='fmt'/> + <parameter is-variadic='yes'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_install' mangled-name='procfs_list_install' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_install'> + <parameter type-id='80f4b756' name='module'/> + <parameter type-id='80f4b756' name='submodule'/> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='d50d396c' name='mode'/> + <parameter type-id='7f432372' name='procfs_list'/> + <parameter type-id='0131eb61' name='show'/> + <parameter type-id='6255c89d' name='show_header'/> + <parameter type-id='b5c3ae96' name='clear'/> + <parameter type-id='b59d7dce' name='procfs_list_node_off'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_uninstall' mangled-name='procfs_list_uninstall' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_uninstall'> + <parameter type-id='7f432372' name='procfs_list'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_destroy' mangled-name='procfs_list_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_destroy'> + <parameter type-id='7f432372' name='procfs_list'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_add' mangled-name='procfs_list_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_add'> + <parameter type-id='7f432372' name='procfs_list'/> + <parameter type-id='eaa32e2f' name='p'/> + <return type-id='48b5725f'/> + </function-decl> + <function-type size-in-bits='64' id='be39c944'> + <parameter type-id='7f432372'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='86932239'> + <parameter type-id='f8dc9def'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='cf9ec29d'> + <parameter type-id='f8dc9def'/> + <parameter type-id='eaa32e2f'/> + <return type-id='95e97e5e'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/random.c' language='LANG_C99'> + <pointer-type-def type-id='b96825af' size-in-bits='64' id='ae3e8ca6'/> + <function-decl name='close' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='95e97e5e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='__open_too_many_args' visibility='default' binding='global' size-in-bits='64'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='__open_missing_mode' visibility='default' binding='global' size-in-bits='64'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='__read_chk' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='95e97e5e'/> + <parameter type-id='eaa32e2f'/> + <parameter type-id='b59d7dce'/> + <parameter type-id='b59d7dce'/> + <return type-id='79a0948f'/> + </function-decl> + <function-decl name='random_force_pseudo' mangled-name='random_force_pseudo' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_force_pseudo'> + <parameter type-id='c19b74c3' name='onoff'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='random_get_bytes' mangled-name='random_get_bytes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_get_bytes'> + <parameter type-id='ae3e8ca6' name='ptr'/> + <parameter type-id='b59d7dce' name='len'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='random_get_pseudo_bytes' mangled-name='random_get_pseudo_bytes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_get_pseudo_bytes'> + <parameter type-id='ae3e8ca6' name='ptr'/> + <parameter type-id='b59d7dce' name='len'/> + <return type-id='95e97e5e'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/rwlock.c' language='LANG_C99'> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='448' id='6093ff7c'> + <subrange length='56' type-id='7359adad' id='f8137894'/> + </array-type-def> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='64' id='8e100159'> + <subrange length='8' type-id='7359adad' id='56e0c0b1'/> + </array-type-def> + <array-type-def dimensions='1' type-id='002ac4a6' size-in-bits='56' id='08f7ce77'> + <subrange length='7' type-id='7359adad' id='16fc326e'/> + </array-type-def> + <class-decl name='krwlock' size-in-bits='576' is-struct='yes' visibility='default' id='4361e3b2'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='rw_lock' type-id='3f680bc6' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='rw_owner' type-id='4051f5e7' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='rw_readers' type-id='3502e3ff' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='krwlock_t' type-id='4361e3b2' id='477df69a'/> + <typedef-decl name='krw_t' type-id='95e97e5e' id='932eed5d'/> + <union-decl name='pthread_rwlock_t' size-in-bits='448' naming-typedef-id='3f680bc6' visibility='default' id='981886f6'> + <data-member access='public'> + <var-decl name='__data' type-id='afe414a4' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__size' type-id='6093ff7c' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='bd54fe1a' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_rwlock_t' type-id='981886f6' id='3f680bc6'/> + <union-decl name='pthread_rwlockattr_t' size-in-bits='64' naming-typedef-id='1b1c4591' visibility='default' id='b8e57521'> + <data-member access='public'> + <var-decl name='__size' type-id='8e100159' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='bd54fe1a' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_rwlockattr_t' type-id='b8e57521' id='1b1c4591'/> + <class-decl name='__pthread_rwlock_arch_t' size-in-bits='448' is-struct='yes' visibility='default' id='afe414a4'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__readers' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='__writers' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='__wrphase_futex' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='__writers_futex' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='__pad3' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='__pad4' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='__cur_writer' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='__shared' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='__rwelision' type-id='28577a57' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='264'> + <var-decl name='__pad1' type-id='08f7ce77' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='__pad2' type-id='7359adad' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='__flags' type-id='f0981eeb' visibility='default'/> + </data-member> + </class-decl> + <qualified-type-def type-id='1b1c4591' const='yes' id='52c85581'/> + <pointer-type-def type-id='52c85581' size-in-bits='64' id='fc5edc31'/> + <qualified-type-def type-id='fc5edc31' restrict='yes' id='295e8f33'/> + <pointer-type-def type-id='477df69a' size-in-bits='64' id='0126db61'/> + <pointer-type-def type-id='3f680bc6' size-in-bits='64' id='a6210c87'/> + <qualified-type-def type-id='a6210c87' restrict='yes' id='27210b05'/> + <qualified-type-def type-id='3502e3ff' volatile='yes' id='d0290e74'/> + <pointer-type-def type-id='d0290e74' size-in-bits='64' id='0ea19dfa'/> + <function-decl name='atomic_inc_uint' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='0ea19dfa'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='atomic_dec_uint' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='0ea19dfa'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='pthread_rwlock_init' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='27210b05'/> + <parameter type-id='295e8f33'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_destroy' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_rdlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_tryrdlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_wrlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_trywrlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_unlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='rw_init' mangled-name='rw_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_init'> + <parameter type-id='0126db61' name='rwlp'/> + <parameter type-id='26a90f95' name='name'/> + <parameter type-id='95e97e5e' name='type'/> + <parameter type-id='eaa32e2f' name='arg'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_destroy' mangled-name='rw_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_destroy'> + <parameter type-id='0126db61' name='rwlp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_enter' mangled-name='rw_enter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_enter'> + <parameter type-id='0126db61' name='rwlp'/> + <parameter type-id='932eed5d' name='rw'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_exit' mangled-name='rw_exit' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_exit'> + <parameter type-id='0126db61' name='rwlp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_tryenter' mangled-name='rw_tryenter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_tryenter'> + <parameter type-id='0126db61' name='rwlp'/> + <parameter type-id='932eed5d' name='rw'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='rw_tryupgrade' mangled-name='rw_tryupgrade' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_tryupgrade'> + <parameter type-id='0126db61' name='rwlp'/> + <return type-id='95e97e5e'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/sid.c' language='LANG_C99'> + <class-decl name='ksiddomain' size-in-bits='128' is-struct='yes' visibility='default' id='b3a38f42'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kd_ref' type-id='3502e3ff' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='kd_len' type-id='3502e3ff' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='kd_name' type-id='26a90f95' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='ksiddomain_t' type-id='b3a38f42' id='db2eb030'/> + <pointer-type-def type-id='db2eb030' size-in-bits='64' id='3b684881'/> + <function-decl name='ksid_lookupdomain' mangled-name='ksid_lookupdomain' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ksid_lookupdomain'> + <parameter type-id='80f4b756' name='dom'/> + <return type-id='3b684881'/> + </function-decl> + <function-decl name='ksiddomain_rele' mangled-name='ksiddomain_rele' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ksiddomain_rele'> + <parameter type-id='3b684881' name='ksid'/> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/strlcat.c' language='LANG_C99'> <function-decl name='strlcat' mangled-name='strlcat' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='strlcat'> <parameter type-id='26a90f95' name='dst'/> @@ -1218,9 +1955,275 @@ <return type-id='b59d7dce'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/taskq.c' language='LANG_C99'> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='256' id='16dc656a'> + <subrange length='32' type-id='7359adad' id='ae5bde82'/> + </array-type-def> + <typedef-decl name='pri_t' type-id='a2185560' id='c497180a'/> + <typedef-decl name='taskqid_t' type-id='e475ab95' id='de0ea20e'/> + <typedef-decl name='task_func_t' type-id='c5c76c9c' id='d8481e1f'/> + <class-decl name='taskq_ent' size-in-bits='320' is-struct='yes' visibility='default' id='cfda1b05'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tqent_next' type-id='67918d75' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tqent_prev' type-id='67918d75' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='tqent_func' type-id='41cce5ce' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='tqent_arg' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='tqent_flags' type-id='e475ab95' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='taskq_ent_t' type-id='cfda1b05' id='65d297d1'/> + <class-decl name='taskq' size-in-bits='3072' is-struct='yes' visibility='default' id='1804594f'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tq_name' type-id='16dc656a' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='tq_lock' type-id='b9eccc8f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='tq_threadlock' type-id='477df69a' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='tq_dispatch_cv' type-id='29dbc0dd' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1600'> + <var-decl name='tq_wait_cv' type-id='29dbc0dd' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1984'> + <var-decl name='tq_threadlist' type-id='6e87b565' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2048'> + <var-decl name='tq_flags' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2080'> + <var-decl name='tq_active' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2112'> + <var-decl name='tq_nthreads' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2144'> + <var-decl name='tq_nalloc' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2176'> + <var-decl name='tq_minalloc' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2208'> + <var-decl name='tq_maxalloc' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2240'> + <var-decl name='tq_maxalloc_cv' type-id='29dbc0dd' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2624'> + <var-decl name='tq_maxalloc_wait' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2688'> + <var-decl name='tq_freelist' type-id='3a4f23d4' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2752'> + <var-decl name='tq_task' type-id='65d297d1' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='taskq_t' type-id='1804594f' id='ef507f03'/> + <typedef-decl name='kthread_t' type-id='4051f5e7' id='9bccee1a'/> + <pointer-type-def type-id='9bccee1a' size-in-bits='64' id='6ae5a80d'/> + <pointer-type-def type-id='6ae5a80d' size-in-bits='64' id='6e87b565'/> + <pointer-type-def type-id='6e87b565' size-in-bits='64' id='4ea26b5d'/> + <pointer-type-def type-id='d8481e1f' size-in-bits='64' id='41cce5ce'/> + <pointer-type-def type-id='cfda1b05' size-in-bits='64' id='67918d75'/> + <pointer-type-def type-id='65d297d1' size-in-bits='64' id='3a4f23d4'/> + <pointer-type-def type-id='ef507f03' size-in-bits='64' id='4f8ed29a'/> + <function-decl name='zk_thread_create' mangled-name='zk_thread_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zk_thread_create'> + <parameter type-id='80f4b756'/> + <parameter type-id='b7f9d8e6'/> + <parameter type-id='eaa32e2f'/> + <parameter type-id='b59d7dce'/> + <parameter type-id='95e97e5e'/> + <return type-id='6ae5a80d'/> + </function-decl> + <function-decl name='pthread_exit' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='eaa32e2f'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='pthread_key_delete' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2de5383b'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='_system_taskq' mangled-name='_system_taskq' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_system_taskq'> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='_system_delay_taskq' mangled-name='_system_delay_taskq' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_system_delay_taskq'> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_dispatch' mangled-name='taskq_dispatch' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_dispatch'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='41cce5ce' name='func'/> + <parameter type-id='eaa32e2f' name='arg'/> + <parameter type-id='3502e3ff' name='tqflags'/> + <return type-id='de0ea20e'/> + </function-decl> + <function-decl name='taskq_dispatch_delay' mangled-name='taskq_dispatch_delay' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_dispatch_delay'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='41cce5ce' name='func'/> + <parameter type-id='eaa32e2f' name='arg'/> + <parameter type-id='3502e3ff' name='tqflags'/> + <parameter type-id='4c3a2c61' name='expire_time'/> + <return type-id='de0ea20e'/> + </function-decl> + <function-decl name='taskq_empty_ent' mangled-name='taskq_empty_ent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_empty_ent'> + <parameter type-id='3a4f23d4' name='t'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='taskq_init_ent' mangled-name='taskq_init_ent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_init_ent'> + <parameter type-id='3a4f23d4' name='t'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_dispatch_ent' mangled-name='taskq_dispatch_ent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_dispatch_ent'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='41cce5ce' name='func'/> + <parameter type-id='eaa32e2f' name='arg'/> + <parameter type-id='3502e3ff' name='flags'/> + <parameter type-id='3a4f23d4' name='t'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_wait' mangled-name='taskq_wait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_wait'> + <parameter type-id='4f8ed29a' name='tq'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_wait_id' mangled-name='taskq_wait_id' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_wait_id'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='de0ea20e' name='id'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_create' mangled-name='taskq_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_create'> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='95e97e5e' name='nthreads'/> + <parameter type-id='c497180a' name='pri'/> + <parameter type-id='95e97e5e' name='minalloc'/> + <parameter type-id='95e97e5e' name='maxalloc'/> + <parameter type-id='3502e3ff' name='flags'/> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_destroy' mangled-name='taskq_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_destroy'> + <parameter type-id='4f8ed29a' name='tq'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_create_synced' mangled-name='taskq_create_synced' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_create_synced'> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='95e97e5e' name='nthreads'/> + <parameter type-id='c497180a' name='pri'/> + <parameter type-id='95e97e5e' name='minalloc'/> + <parameter type-id='95e97e5e' name='maxalloc'/> + <parameter type-id='3502e3ff' name='flags'/> + <parameter type-id='4ea26b5d' name='ktpp'/> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_member' mangled-name='taskq_member' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_member'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='6ae5a80d' name='t'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='taskq_of_curthread' mangled-name='taskq_of_curthread' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_of_curthread'> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_cancel_id' mangled-name='taskq_cancel_id' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_cancel_id'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='de0ea20e' name='id'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='system_taskq_init' mangled-name='system_taskq_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='system_taskq_init'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='system_taskq_fini' mangled-name='system_taskq_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='system_taskq_fini'> + <return type-id='48b5725f'/> + </function-decl> + <function-type size-in-bits='64' id='c5c76c9c'> + <parameter type-id='eaa32e2f'/> + <return type-id='48b5725f'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/thread.c' language='LANG_C99'> + <union-decl name='pthread_attr_t' size-in-bits='448' visibility='default' id='b63afacd'> + <data-member access='public'> + <var-decl name='__size' type-id='6093ff7c' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='bd54fe1a' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_attr_t' type-id='b63afacd' id='7d8569fd'/> + <qualified-type-def type-id='7d8569fd' const='yes' id='e06dee2d'/> + <pointer-type-def type-id='e06dee2d' size-in-bits='64' id='540db505'/> + <qualified-type-def type-id='540db505' restrict='yes' id='e1815e87'/> + <pointer-type-def type-id='7d8569fd' size-in-bits='64' id='7347a39e'/> + <pointer-type-def type-id='4051f5e7' size-in-bits='64' id='e01b5462'/> + <qualified-type-def type-id='e01b5462' restrict='yes' id='cc338b26'/> + <pointer-type-def type-id='cd5d79f4' size-in-bits='64' id='5ad9edb6'/> + <function-decl name='pthread_create' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='cc338b26'/> + <parameter type-id='e1815e87'/> + <parameter type-id='5ad9edb6'/> + <parameter type-id='1b7446cd'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_attr_init' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='7347a39e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_attr_destroy' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='7347a39e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_attr_setdetachstate' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='7347a39e'/> + <parameter type-id='95e97e5e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_attr_setguardsize' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='7347a39e'/> + <parameter type-id='b59d7dce'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_attr_setstacksize' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='7347a39e'/> + <parameter type-id='b59d7dce'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_setname_np' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='4051f5e7'/> + <parameter type-id='80f4b756'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='strtol' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='9d26089a'/> + <parameter type-id='8c85230f'/> + <parameter type-id='95e97e5e'/> + <return type-id='bd54fe1a'/> + </function-decl> + <function-decl name='getenv' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='80f4b756'/> + <return type-id='26a90f95'/> + </function-decl> + <function-decl name='__sysconf' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='95e97e5e'/> + <return type-id='bd54fe1a'/> + </function-decl> + <function-decl name='p0' mangled-name='p0' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='p0'> + <return type-id='48b5725f'/> + </function-decl> + <function-type size-in-bits='64' id='cd5d79f4'> + <parameter type-id='eaa32e2f'/> + <return type-id='eaa32e2f'/> + </function-type> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/timestamp.c' language='LANG_C99'> <typedef-decl name='nl_item' type-id='95e97e5e' id='03b79a94'/> - <typedef-decl name='__time_t' type-id='bd54fe1a' id='65eda9c0'/> <class-decl name='tm' size-in-bits='448' is-struct='yes' visibility='default' id='dddf6ca2'> <data-member access='public' layout-offset-in-bits='0'> <var-decl name='tm_sec' type-id='95e97e5e' visibility='default'/> @@ -1310,52 +2313,10 @@ </function-decl> </abi-instr> <abi-instr address-size='64' path='lib/libspl/tunables.c' language='LANG_C99'> - <enum-decl name='zfs_tunable_type_t' naming-typedef-id='f50b1525' id='56905369'> - <underlying-type type-id='9cac1fee'/> - <enumerator name='ZFS_TUNABLE_TYPE_INT' value='0'/> - <enumerator name='ZFS_TUNABLE_TYPE_UINT' value='1'/> - <enumerator name='ZFS_TUNABLE_TYPE_ULONG' value='2'/> - <enumerator name='ZFS_TUNABLE_TYPE_U64' value='3'/> - <enumerator name='ZFS_TUNABLE_TYPE_STRING' value='4'/> - </enum-decl> - <typedef-decl name='zfs_tunable_type_t' type-id='56905369' id='f50b1525'/> - <enum-decl name='zfs_tunable_perm_t' naming-typedef-id='ada7336b' id='e80e6ebf'> - <underlying-type type-id='9cac1fee'/> - <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RW' value='0'/> - <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RD' value='1'/> - </enum-decl> - <typedef-decl name='zfs_tunable_perm_t' type-id='e80e6ebf' id='ada7336b'/> - <class-decl name='zfs_tunable' size-in-bits='320' is-struct='yes' visibility='default' id='1a97ee0e'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='zt_name' type-id='80f4b756' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='zt_varp' type-id='eaa32e2f' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='zt_varsz' type-id='b59d7dce' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='zt_type' type-id='f50b1525' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='zt_perm' type-id='ada7336b' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='zt_desc' type-id='80f4b756' visibility='default'/> - </data-member> - </class-decl> - <typedef-decl name='zfs_tunable_t' type-id='1a97ee0e' id='12bf5c5e'/> - <typedef-decl name='zfs_tunable_iter_t' type-id='7ef33f92' id='d8d5f4ab'/> <typedef-decl name='intmax_t' type-id='5b475db0' id='e104d842'/> <typedef-decl name='uintmax_t' type-id='04d82f4b' id='f8b828c9'/> <typedef-decl name='__intmax_t' type-id='bd54fe1a' id='5b475db0'/> <typedef-decl name='__uintmax_t' type-id='7359adad' id='04d82f4b'/> - <pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/> - <qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/> - <qualified-type-def type-id='12bf5c5e' const='yes' id='180e47ee'/> - <pointer-type-def type-id='180e47ee' size-in-bits='64' id='a27af98c'/> - <pointer-type-def type-id='92f86508' size-in-bits='64' id='7ef33f92'/> <function-decl name='strtoimax' visibility='default' binding='global' size-in-bits='64'> <parameter type-id='9d26089a'/> <parameter type-id='8c85230f'/> @@ -1368,31 +2329,6 @@ <parameter type-id='95e97e5e'/> <return type-id='f8b828c9'/> </function-decl> - <function-decl name='zfs_tunable_lookup' mangled-name='zfs_tunable_lookup' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_lookup'> - <parameter type-id='80f4b756' name='name'/> - <return type-id='a27af98c'/> - </function-decl> - <function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'> - <parameter type-id='d8d5f4ab' name='cb'/> - <parameter type-id='eaa32e2f' name='arg'/> - <return type-id='48b5725f'/> - </function-decl> - <function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'> - <parameter type-id='a27af98c' name='zt'/> - <parameter type-id='80f4b756' name='val'/> - <return type-id='95e97e5e'/> - </function-decl> - <function-decl name='zfs_tunable_get' mangled-name='zfs_tunable_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_get'> - <parameter type-id='a27af98c' name='zt'/> - <parameter type-id='26a90f95' name='val'/> - <parameter type-id='b59d7dce' name='valsz'/> - <return type-id='95e97e5e'/> - </function-decl> - <function-type size-in-bits='64' id='92f86508'> - <parameter type-id='a27af98c'/> - <parameter type-id='eaa32e2f'/> - <return type-id='95e97e5e'/> - </function-type> </abi-instr> <abi-instr address-size='64' path='lib/libuutil/uu_alloc.c' language='LANG_C99'> <type-decl name='char' size-in-bits='8' id='a84c031d'/> @@ -2334,10 +3270,6 @@ <function-type size-in-bits='64' id='ee076206'> <return type-id='48b5725f'/> </function-type> - <function-type size-in-bits='64' id='c5c76c9c'> - <parameter type-id='eaa32e2f'/> - <return type-id='48b5725f'/> - </function-type> </abi-instr> <abi-instr address-size='64' path='lib/libuutil/uu_string.c' language='LANG_C99'> <type-decl name='unnamed-enum-underlying-type-32' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='9cac1fee'/> diff --git a/sys/contrib/openzfs/lib/libzfs/Makefile.am b/sys/contrib/openzfs/lib/libzfs/Makefile.am index 5f8963dccd1a..e2cbca47b9a3 100644 --- a/sys/contrib/openzfs/lib/libzfs/Makefile.am +++ b/sys/contrib/openzfs/lib/libzfs/Makefile.am @@ -70,7 +70,7 @@ if BUILD_FREEBSD libzfs_la_LIBADD += -lutil -lgeom endif -libzfs_la_LDFLAGS += -version-info 6:0:0 +libzfs_la_LDFLAGS += -version-info 7:0:0 pkgconfig_DATA += %D%/libzfs.pc diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs.abi b/sys/contrib/openzfs/lib/libzfs/libzfs.abi index f988d27a286a..f481b6221e4d 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs.abi +++ b/sys/contrib/openzfs/lib/libzfs/libzfs.abi @@ -1,4 +1,4 @@ -<abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfs.so.6'> +<abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfs.so.7'> <elf-needed> <dependency name='libzfs_core.so.3'/> <dependency name='libnvpair.so.3'/> @@ -15,6 +15,8 @@ </elf-needed> <elf-function-symbols> <elf-symbol name='_sol_getmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_system_delay_taskq' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_system_taskq' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_add_16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_add_16_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_add_32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -160,6 +162,19 @@ <elf-symbol name='cityhash4' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='color_end' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='color_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetgid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetgroups' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetngroups' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetruid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetuid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_broadcast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_signal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_timedwait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_timedwait_hires' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_wait_sig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='dataset_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='dataset_nestcheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='efi_alloc_and_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -195,9 +210,22 @@ <elf-symbol name='getzoneid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='is_mounted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='is_mpath_whole_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_asprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_cache_reap_active' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_scnprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_vasprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='ksid_lookupdomain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='ksiddomain_rele' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_delete' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_install' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_set_raw_ops' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libpc_error_description' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libspl_assertf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libspl_backtrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='libspl_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='libspl_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='libspl_physmem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libspl_set_assert_ok' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libzfs_add_handle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libzfs_envvar_is_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -243,10 +271,32 @@ <elf-symbol name='membar_sync' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='mkdirp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='mountpoint_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_enter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_enter_check_return' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_tryenter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='p0' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='permset_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='pool_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='print_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='printf_color' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_install' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_uninstall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_force_pseudo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_get_bytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_get_pseudo_bytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_enter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_tryenter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_tryupgrade' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='sa_commit_shares' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='sa_disable_share' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='sa_enable_share' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -254,10 +304,29 @@ <elf-symbol name='sa_is_shared' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='sa_truncate_shares' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='sa_validate_shareopts' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='seq_printf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='snapshot_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='spl_fstrans_mark' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='spl_fstrans_unmark' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='spl_pagesize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='strlcat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='strlcpy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='system_taskq_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='system_taskq_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_cancel_id' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_create_synced' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_dispatch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_dispatch_delay' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_dispatch_ent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_empty_ent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_init_ent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_member' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_of_curthread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_wait_id' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_wait_outstanding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='tpool_abandon' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='tpool_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='tpool_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -270,6 +339,7 @@ <elf-symbol name='update_vdev_config_dev_strs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='update_vdev_config_dev_sysfs_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='use_color' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='utsname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='vdev_expand_proplist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='vdev_name_to_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='vdev_prop_align_right' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -451,10 +521,6 @@ <elf-symbol name='zfs_strip_partition' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_strip_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_truncate_shares' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_type_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_unmount' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_unmountall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -477,6 +543,7 @@ <elf-symbol name='zfs_version_userland' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_wait_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_zpl_version_map' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='zk_thread_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_add_propname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_checkpoint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -1319,6 +1386,106 @@ </function-decl> <type-decl name='unsigned short int' size-in-bits='16' id='8efea9e5'/> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/condvar.c' language='LANG_C99'> + <typedef-decl name='kcondvar_t' type-id='62fab762' id='29dbc0dd'/> + <class-decl name='kmutex' size-in-bits='384' is-struct='yes' visibility='default' id='f1cacfe1'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='m_lock' type-id='7a6844eb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='m_owner' type-id='4051f5e7' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='kmutex_t' type-id='f1cacfe1' id='b9eccc8f'/> + <typedef-decl name='hrtime_t' type-id='1eb56b1e' id='cebdd548'/> + <typedef-decl name='__suseconds_t' type-id='bd54fe1a' id='5b102a54'/> + <typedef-decl name='clock_t' type-id='4d66c6d7' id='4c3a2c61'/> + <class-decl name='timeval' size-in-bits='128' is-struct='yes' visibility='default' id='2a693ac3'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tv_sec' type-id='65eda9c0' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tv_usec' type-id='5b102a54' visibility='default'/> + </data-member> + </class-decl> + <pointer-type-def type-id='29dbc0dd' size-in-bits='64' id='068c4f7e'/> + <pointer-type-def type-id='b9eccc8f' size-in-bits='64' id='78830f38'/> + <pointer-type-def type-id='2a693ac3' size-in-bits='64' id='896f1b83'/> + <qualified-type-def type-id='896f1b83' restrict='yes' id='4bcf44c1'/> + <function-decl name='pthread_cond_destroy' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='db285b03'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='gettimeofday' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='4bcf44c1'/> + <parameter type-id='1b7446cd'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_init' mangled-name='cv_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_init'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='26a90f95' name='name'/> + <parameter type-id='95e97e5e' name='type'/> + <parameter type-id='eaa32e2f' name='arg'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_destroy' mangled-name='cv_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_destroy'> + <parameter type-id='068c4f7e' name='cv'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_wait' mangled-name='cv_wait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_wait'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_wait_sig' mangled-name='cv_wait_sig' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_wait_sig'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_timedwait' mangled-name='cv_timedwait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_timedwait'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <parameter type-id='4c3a2c61' name='abstime'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_timedwait_hires' mangled-name='cv_timedwait_hires' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_timedwait_hires'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <parameter type-id='cebdd548' name='tim'/> + <parameter type-id='cebdd548' name='res'/> + <parameter type-id='95e97e5e' name='flag'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_signal' mangled-name='cv_signal' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_signal'> + <parameter type-id='068c4f7e' name='cv'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_broadcast' mangled-name='cv_broadcast' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_broadcast'> + <parameter type-id='068c4f7e' name='cv'/> + <return type-id='48b5725f'/> + </function-decl> + <qualified-type-def type-id='eaa32e2f' restrict='yes' id='1b7446cd'/> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/cred.c' language='LANG_C99'> + <class-decl name='cred' is-struct='yes' visibility='default' is-declaration-only='yes' id='6739dd09'/> + <typedef-decl name='cred_t' type-id='6739dd09' id='a42f1a8f'/> + <typedef-decl name='gid_t' type-id='d94ec6d9' id='2bb2b96f'/> + <pointer-type-def type-id='a42f1a8f' size-in-bits='64' id='f89fcf80'/> + <pointer-type-def type-id='2bb2b96f' size-in-bits='64' id='b52814e6'/> + <class-decl name='cred' is-struct='yes' visibility='default' is-declaration-only='yes' id='6739dd09'/> + <function-decl name='crgetuid' mangled-name='crgetuid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crgetuid'> + <parameter type-id='f89fcf80' name='cr'/> + <return type-id='354978ed'/> + </function-decl> + <function-decl name='crgetngroups' mangled-name='crgetngroups' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crgetngroups'> + <parameter type-id='f89fcf80' name='cr'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='crgetgroups' mangled-name='crgetgroups' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crgetgroups'> + <parameter type-id='f89fcf80' name='cr'/> + <return type-id='b52814e6'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/getexecname.c' language='LANG_C99'> <function-decl name='getexecname' mangled-name='getexecname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getexecname'> <return type-id='80f4b756'/> @@ -1328,6 +1495,160 @@ <return type-id='79a0948f'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/kmem.c' language='LANG_C99'> + <typedef-decl name='fstrans_cookie_t' type-id='95e97e5e' id='059934c1'/> + <function-decl name='kmem_vasprintf' mangled-name='kmem_vasprintf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_vasprintf'> + <parameter type-id='80f4b756' name='fmt'/> + <parameter type-id='b7f2d5e6' name='adx'/> + <return type-id='26a90f95'/> + </function-decl> + <function-decl name='kmem_asprintf' mangled-name='kmem_asprintf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_asprintf'> + <parameter type-id='80f4b756' name='fmt'/> + <parameter is-variadic='yes'/> + <return type-id='26a90f95'/> + </function-decl> + <function-decl name='kmem_scnprintf' mangled-name='kmem_scnprintf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_scnprintf'> + <parameter type-id='266fe297' name='str'/> + <parameter type-id='b59d7dce' name='size'/> + <parameter type-id='9d26089a' name='fmt'/> + <parameter is-variadic='yes'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='spl_fstrans_unmark' mangled-name='spl_fstrans_unmark' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spl_fstrans_unmark'> + <parameter type-id='059934c1' name='cookie'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='kmem_cache_reap_active' mangled-name='kmem_cache_reap_active' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_cache_reap_active'> + <return type-id='95e97e5e'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/kstat.c' language='LANG_C99'> + <class-decl name='kstat' size-in-bits='448' is-struct='yes' visibility='default' id='5f5c9d88'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ks_flags' type-id='d8bf0010' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ks_data' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ks_ndata' type-id='3502e3ff' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ks_data_size' type-id='b59d7dce' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='ks_update' type-id='8cf7b7e1' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='ks_private' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='ks_lock' type-id='eaa32e2f' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='kstat_t' type-id='5f5c9d88' id='dd12e024'/> + <typedef-decl name='uchar_t' type-id='002ac4a6' id='d8bf0010'/> + <typedef-decl name='__loff_t' type-id='724e4de6' id='00c9d214'/> + <typedef-decl name='loff_t' type-id='00c9d214' id='69bf7bee'/> + <pointer-type-def type-id='9d5d322a' size-in-bits='64' id='bbe97414'/> + <pointer-type-def type-id='05b3c714' size-in-bits='64' id='27cc5c36'/> + <pointer-type-def type-id='7a9ace65' size-in-bits='64' id='8cf7b7e1'/> + <pointer-type-def type-id='5f5c9d88' size-in-bits='64' id='0e87f9be'/> + <pointer-type-def type-id='dd12e024' size-in-bits='64' id='46e5e463'/> + <pointer-type-def type-id='527a97c5' size-in-bits='64' id='673f2af9'/> + <function-decl name='kstat_create' mangled-name='kstat_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_create'> + <parameter type-id='80f4b756' name='module'/> + <parameter type-id='95e97e5e' name='instance'/> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='80f4b756' name='class'/> + <parameter type-id='d8bf0010' name='type'/> + <parameter type-id='ee1f298e' name='ndata'/> + <parameter type-id='d8bf0010' name='ks_flag'/> + <return type-id='46e5e463'/> + </function-decl> + <function-decl name='kstat_install' mangled-name='kstat_install' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_install'> + <parameter type-id='46e5e463' name='ksp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='kstat_set_raw_ops' mangled-name='kstat_set_raw_ops' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_set_raw_ops'> + <parameter type-id='46e5e463' name='ksp'/> + <parameter type-id='bbe97414' name='headers'/> + <parameter type-id='27cc5c36' name='data'/> + <parameter type-id='673f2af9' name='addr'/> + <return type-id='48b5725f'/> + </function-decl> + <function-type size-in-bits='64' id='9d5d322a'> + <parameter type-id='26a90f95'/> + <parameter type-id='b59d7dce'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='05b3c714'> + <parameter type-id='26a90f95'/> + <parameter type-id='b59d7dce'/> + <parameter type-id='eaa32e2f'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='7a9ace65'> + <parameter type-id='0e87f9be'/> + <parameter type-id='95e97e5e'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='527a97c5'> + <parameter type-id='46e5e463'/> + <parameter type-id='69bf7bee'/> + <return type-id='eaa32e2f'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/libspl.c' language='LANG_C99'> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='520' id='5ddd38d2'> + <subrange length='65' type-id='7359adad' id='b50e2e4a'/> + </array-type-def> + <typedef-decl name='utsname_t' type-id='414a2ac6' id='5278297a'/> + <class-decl name='utsname' size-in-bits='3120' is-struct='yes' visibility='default' id='414a2ac6'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='sysname' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='520'> + <var-decl name='nodename' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1040'> + <var-decl name='release' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1560'> + <var-decl name='version' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2080'> + <var-decl name='machine' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2600'> + <var-decl name='domainname' type-id='5ddd38d2' visibility='default'/> + </data-member> + </class-decl> + <pointer-type-def type-id='414a2ac6' size-in-bits='64' id='a6724cec'/> + <pointer-type-def type-id='5278297a' size-in-bits='64' id='5c7868ad'/> + <function-decl name='uname' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6724cec'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='libspl_physmem' mangled-name='libspl_physmem' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_physmem'> + <return type-id='9c313c2d'/> + </function-decl> + <function-decl name='utsname' mangled-name='utsname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='utsname'> + <return type-id='5c7868ad'/> + </function-decl> + <function-decl name='libspl_init' mangled-name='libspl_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_init'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='libspl_fini' mangled-name='libspl_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_fini'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='random_init' mangled-name='random_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_init'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='random_fini' mangled-name='random_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_fini'> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/list.c' language='LANG_C99'> <typedef-decl name='list_node_t' type-id='b0b5e45e' id='b21843b2'/> <typedef-decl name='list_t' type-id='e824dae9' id='0899125f'/> @@ -1458,6 +1779,39 @@ <return type-id='b59d7dce'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/mutex.c' language='LANG_C99'> + <function-decl name='pthread_mutex_trylock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='18c91f9e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='mutex_init' mangled-name='mutex_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_init'> + <parameter type-id='78830f38' name='mp'/> + <parameter type-id='26a90f95' name='name'/> + <parameter type-id='95e97e5e' name='type'/> + <parameter type-id='eaa32e2f' name='cookie'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='mutex_destroy' mangled-name='mutex_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_destroy'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='mutex_enter' mangled-name='mutex_enter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_enter'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='mutex_enter_check_return' mangled-name='mutex_enter_check_return' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_enter_check_return'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='mutex_tryenter' mangled-name='mutex_tryenter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_tryenter'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='mutex_exit' mangled-name='mutex_exit' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_exit'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/os/linux/getmntany.c' language='LANG_C99'> <pointer-type-def type-id='56fe4a37' size-in-bits='64' id='b6b61d2f'/> <qualified-type-def type-id='b6b61d2f' restrict='yes' id='3cad23cd'/> @@ -1473,6 +1827,486 @@ <return type-id='95e97e5e'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/procfs_list.c' language='LANG_C99'> + <class-decl name='procfs_list' size-in-bits='768' is-struct='yes' visibility='default' id='0f4d3b87'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='pl_private' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='pl_lock' type-id='b9eccc8f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='pl_list' type-id='0899125f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='pl_next_id' type-id='9c313c2d' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='pl_node_offset' type-id='b59d7dce' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='procfs_list_t' type-id='0f4d3b87' id='e5b5a21b'/> + <class-decl name='seq_file' is-struct='yes' visibility='default' id='f3415517'/> + <pointer-type-def type-id='be39c944' size-in-bits='64' id='b5c3ae96'/> + <pointer-type-def type-id='86932239' size-in-bits='64' id='6255c89d'/> + <pointer-type-def type-id='cf9ec29d' size-in-bits='64' id='0131eb61'/> + <pointer-type-def type-id='e5b5a21b' size-in-bits='64' id='7f432372'/> + <pointer-type-def type-id='f3415517' size-in-bits='64' id='f8dc9def'/> + <function-decl name='seq_printf' mangled-name='seq_printf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='seq_printf'> + <parameter type-id='f8dc9def' name='m'/> + <parameter type-id='80f4b756' name='fmt'/> + <parameter is-variadic='yes'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_install' mangled-name='procfs_list_install' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_install'> + <parameter type-id='80f4b756' name='module'/> + <parameter type-id='80f4b756' name='submodule'/> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='d50d396c' name='mode'/> + <parameter type-id='7f432372' name='procfs_list'/> + <parameter type-id='0131eb61' name='show'/> + <parameter type-id='6255c89d' name='show_header'/> + <parameter type-id='b5c3ae96' name='clear'/> + <parameter type-id='b59d7dce' name='procfs_list_node_off'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_uninstall' mangled-name='procfs_list_uninstall' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_uninstall'> + <parameter type-id='7f432372' name='procfs_list'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_destroy' mangled-name='procfs_list_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_destroy'> + <parameter type-id='7f432372' name='procfs_list'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_add' mangled-name='procfs_list_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_add'> + <parameter type-id='7f432372' name='procfs_list'/> + <parameter type-id='eaa32e2f' name='p'/> + <return type-id='48b5725f'/> + </function-decl> + <function-type size-in-bits='64' id='be39c944'> + <parameter type-id='7f432372'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='86932239'> + <parameter type-id='f8dc9def'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='cf9ec29d'> + <parameter type-id='f8dc9def'/> + <parameter type-id='eaa32e2f'/> + <return type-id='95e97e5e'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/random.c' language='LANG_C99'> + <function-decl name='random_force_pseudo' mangled-name='random_force_pseudo' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_force_pseudo'> + <parameter type-id='c19b74c3' name='onoff'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='random_get_bytes' mangled-name='random_get_bytes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_get_bytes'> + <parameter type-id='ae3e8ca6' name='ptr'/> + <parameter type-id='b59d7dce' name='len'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='random_get_pseudo_bytes' mangled-name='random_get_pseudo_bytes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_get_pseudo_bytes'> + <parameter type-id='ae3e8ca6' name='ptr'/> + <parameter type-id='b59d7dce' name='len'/> + <return type-id='95e97e5e'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/rwlock.c' language='LANG_C99'> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='64' id='8e100159'> + <subrange length='8' type-id='7359adad' id='56e0c0b1'/> + </array-type-def> + <array-type-def dimensions='1' type-id='002ac4a6' size-in-bits='56' id='08f7ce77'> + <subrange length='7' type-id='7359adad' id='16fc326e'/> + </array-type-def> + <class-decl name='krwlock' size-in-bits='576' is-struct='yes' visibility='default' id='4361e3b2'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='rw_lock' type-id='3f680bc6' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='rw_owner' type-id='4051f5e7' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='rw_readers' type-id='3502e3ff' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='krwlock_t' type-id='4361e3b2' id='477df69a'/> + <typedef-decl name='krw_t' type-id='95e97e5e' id='932eed5d'/> + <union-decl name='pthread_rwlock_t' size-in-bits='448' naming-typedef-id='3f680bc6' visibility='default' id='981886f6'> + <data-member access='public'> + <var-decl name='__data' type-id='afe414a4' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__size' type-id='6093ff7c' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='bd54fe1a' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_rwlock_t' type-id='981886f6' id='3f680bc6'/> + <union-decl name='pthread_rwlockattr_t' size-in-bits='64' naming-typedef-id='1b1c4591' visibility='default' id='b8e57521'> + <data-member access='public'> + <var-decl name='__size' type-id='8e100159' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='bd54fe1a' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_rwlockattr_t' type-id='b8e57521' id='1b1c4591'/> + <class-decl name='__pthread_rwlock_arch_t' size-in-bits='448' is-struct='yes' visibility='default' id='afe414a4'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__readers' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='__writers' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='__wrphase_futex' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='__writers_futex' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='__pad3' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='__pad4' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='__cur_writer' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='__shared' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='__rwelision' type-id='28577a57' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='264'> + <var-decl name='__pad1' type-id='08f7ce77' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='__pad2' type-id='7359adad' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='__flags' type-id='f0981eeb' visibility='default'/> + </data-member> + </class-decl> + <qualified-type-def type-id='1b1c4591' const='yes' id='52c85581'/> + <pointer-type-def type-id='52c85581' size-in-bits='64' id='fc5edc31'/> + <qualified-type-def type-id='fc5edc31' restrict='yes' id='295e8f33'/> + <pointer-type-def type-id='477df69a' size-in-bits='64' id='0126db61'/> + <pointer-type-def type-id='3f680bc6' size-in-bits='64' id='a6210c87'/> + <qualified-type-def type-id='a6210c87' restrict='yes' id='27210b05'/> + <qualified-type-def type-id='3502e3ff' volatile='yes' id='d0290e74'/> + <pointer-type-def type-id='d0290e74' size-in-bits='64' id='0ea19dfa'/> + <function-decl name='atomic_inc_uint' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='0ea19dfa'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='atomic_dec_uint' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='0ea19dfa'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='pthread_rwlock_init' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='27210b05'/> + <parameter type-id='295e8f33'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_destroy' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_rdlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_tryrdlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_wrlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_trywrlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_unlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='rw_init' mangled-name='rw_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_init'> + <parameter type-id='0126db61' name='rwlp'/> + <parameter type-id='26a90f95' name='name'/> + <parameter type-id='95e97e5e' name='type'/> + <parameter type-id='eaa32e2f' name='arg'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_destroy' mangled-name='rw_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_destroy'> + <parameter type-id='0126db61' name='rwlp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_enter' mangled-name='rw_enter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_enter'> + <parameter type-id='0126db61' name='rwlp'/> + <parameter type-id='932eed5d' name='rw'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_exit' mangled-name='rw_exit' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_exit'> + <parameter type-id='0126db61' name='rwlp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_tryenter' mangled-name='rw_tryenter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_tryenter'> + <parameter type-id='0126db61' name='rwlp'/> + <parameter type-id='932eed5d' name='rw'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='rw_tryupgrade' mangled-name='rw_tryupgrade' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_tryupgrade'> + <parameter type-id='0126db61' name='rwlp'/> + <return type-id='95e97e5e'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/sid.c' language='LANG_C99'> + <class-decl name='ksiddomain' size-in-bits='128' is-struct='yes' visibility='default' id='b3a38f42'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kd_ref' type-id='3502e3ff' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='kd_len' type-id='3502e3ff' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='kd_name' type-id='26a90f95' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='ksiddomain_t' type-id='b3a38f42' id='db2eb030'/> + <pointer-type-def type-id='db2eb030' size-in-bits='64' id='3b684881'/> + <function-decl name='ksid_lookupdomain' mangled-name='ksid_lookupdomain' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ksid_lookupdomain'> + <parameter type-id='80f4b756' name='dom'/> + <return type-id='3b684881'/> + </function-decl> + <function-decl name='ksiddomain_rele' mangled-name='ksiddomain_rele' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ksiddomain_rele'> + <parameter type-id='3b684881' name='ksid'/> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/taskq.c' language='LANG_C99'> + <typedef-decl name='pri_t' type-id='a2185560' id='c497180a'/> + <typedef-decl name='taskqid_t' type-id='e475ab95' id='de0ea20e'/> + <typedef-decl name='task_func_t' type-id='c5c76c9c' id='d8481e1f'/> + <class-decl name='taskq_ent' size-in-bits='320' is-struct='yes' visibility='default' id='cfda1b05'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tqent_next' type-id='67918d75' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tqent_prev' type-id='67918d75' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='tqent_func' type-id='41cce5ce' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='tqent_arg' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='tqent_flags' type-id='e475ab95' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='taskq_ent_t' type-id='cfda1b05' id='65d297d1'/> + <class-decl name='taskq' size-in-bits='3072' is-struct='yes' visibility='default' id='1804594f'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tq_name' type-id='16dc656a' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='tq_lock' type-id='b9eccc8f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='tq_threadlock' type-id='477df69a' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='tq_dispatch_cv' type-id='29dbc0dd' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1600'> + <var-decl name='tq_wait_cv' type-id='29dbc0dd' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1984'> + <var-decl name='tq_threadlist' type-id='6e87b565' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2048'> + <var-decl name='tq_flags' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2080'> + <var-decl name='tq_active' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2112'> + <var-decl name='tq_nthreads' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2144'> + <var-decl name='tq_nalloc' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2176'> + <var-decl name='tq_minalloc' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2208'> + <var-decl name='tq_maxalloc' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2240'> + <var-decl name='tq_maxalloc_cv' type-id='29dbc0dd' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2624'> + <var-decl name='tq_maxalloc_wait' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2688'> + <var-decl name='tq_freelist' type-id='3a4f23d4' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2752'> + <var-decl name='tq_task' type-id='65d297d1' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='taskq_t' type-id='1804594f' id='ef507f03'/> + <typedef-decl name='kthread_t' type-id='4051f5e7' id='9bccee1a'/> + <typedef-decl name='pthread_key_t' type-id='f0981eeb' id='2de5383b'/> + <pointer-type-def type-id='9bccee1a' size-in-bits='64' id='6ae5a80d'/> + <pointer-type-def type-id='6ae5a80d' size-in-bits='64' id='6e87b565'/> + <pointer-type-def type-id='6e87b565' size-in-bits='64' id='4ea26b5d'/> + <pointer-type-def type-id='2de5383b' size-in-bits='64' id='ce04b822'/> + <pointer-type-def type-id='d8481e1f' size-in-bits='64' id='41cce5ce'/> + <pointer-type-def type-id='cfda1b05' size-in-bits='64' id='67918d75'/> + <pointer-type-def type-id='65d297d1' size-in-bits='64' id='3a4f23d4'/> + <pointer-type-def type-id='ef507f03' size-in-bits='64' id='4f8ed29a'/> + <function-decl name='zk_thread_create' mangled-name='zk_thread_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zk_thread_create'> + <parameter type-id='80f4b756'/> + <parameter type-id='b7f9d8e6'/> + <parameter type-id='eaa32e2f'/> + <parameter type-id='b59d7dce'/> + <parameter type-id='95e97e5e'/> + <return type-id='6ae5a80d'/> + </function-decl> + <function-decl name='pthread_key_create' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='ce04b822'/> + <parameter type-id='b7f9d8e6'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_key_delete' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2de5383b'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_getspecific' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2de5383b'/> + <return type-id='eaa32e2f'/> + </function-decl> + <function-decl name='pthread_setspecific' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2de5383b'/> + <parameter type-id='eaa32e2f'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='_system_taskq' mangled-name='_system_taskq' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_system_taskq'> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='_system_delay_taskq' mangled-name='_system_delay_taskq' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_system_delay_taskq'> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_dispatch' mangled-name='taskq_dispatch' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_dispatch'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='41cce5ce' name='func'/> + <parameter type-id='eaa32e2f' name='arg'/> + <parameter type-id='3502e3ff' name='tqflags'/> + <return type-id='de0ea20e'/> + </function-decl> + <function-decl name='taskq_dispatch_delay' mangled-name='taskq_dispatch_delay' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_dispatch_delay'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='41cce5ce' name='func'/> + <parameter type-id='eaa32e2f' name='arg'/> + <parameter type-id='3502e3ff' name='tqflags'/> + <parameter type-id='4c3a2c61' name='expire_time'/> + <return type-id='de0ea20e'/> + </function-decl> + <function-decl name='taskq_empty_ent' mangled-name='taskq_empty_ent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_empty_ent'> + <parameter type-id='3a4f23d4' name='t'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='taskq_init_ent' mangled-name='taskq_init_ent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_init_ent'> + <parameter type-id='3a4f23d4' name='t'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_dispatch_ent' mangled-name='taskq_dispatch_ent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_dispatch_ent'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='41cce5ce' name='func'/> + <parameter type-id='eaa32e2f' name='arg'/> + <parameter type-id='3502e3ff' name='flags'/> + <parameter type-id='3a4f23d4' name='t'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_wait' mangled-name='taskq_wait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_wait'> + <parameter type-id='4f8ed29a' name='tq'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_wait_id' mangled-name='taskq_wait_id' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_wait_id'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='de0ea20e' name='id'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_create' mangled-name='taskq_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_create'> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='95e97e5e' name='nthreads'/> + <parameter type-id='c497180a' name='pri'/> + <parameter type-id='95e97e5e' name='minalloc'/> + <parameter type-id='95e97e5e' name='maxalloc'/> + <parameter type-id='3502e3ff' name='flags'/> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_destroy' mangled-name='taskq_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_destroy'> + <parameter type-id='4f8ed29a' name='tq'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_create_synced' mangled-name='taskq_create_synced' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_create_synced'> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='95e97e5e' name='nthreads'/> + <parameter type-id='c497180a' name='pri'/> + <parameter type-id='95e97e5e' name='minalloc'/> + <parameter type-id='95e97e5e' name='maxalloc'/> + <parameter type-id='3502e3ff' name='flags'/> + <parameter type-id='4ea26b5d' name='ktpp'/> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_member' mangled-name='taskq_member' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_member'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='6ae5a80d' name='t'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='taskq_of_curthread' mangled-name='taskq_of_curthread' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_of_curthread'> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_cancel_id' mangled-name='taskq_cancel_id' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_cancel_id'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='de0ea20e' name='id'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='system_taskq_init' mangled-name='system_taskq_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='system_taskq_init'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='system_taskq_fini' mangled-name='system_taskq_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='system_taskq_fini'> + <return type-id='48b5725f'/> + </function-decl> + <function-type size-in-bits='64' id='c5c76c9c'> + <parameter type-id='eaa32e2f'/> + <return type-id='48b5725f'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/thread.c' language='LANG_C99'> + <function-decl name='pthread_attr_setstacksize' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='7347a39e'/> + <parameter type-id='b59d7dce'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_setname_np' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='4051f5e7'/> + <parameter type-id='80f4b756'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='p0' mangled-name='p0' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='p0'> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/timestamp.c' language='LANG_C99'> <typedef-decl name='nl_item' type-id='95e97e5e' id='03b79a94'/> <function-decl name='nl_langinfo' visibility='default' binding='global' size-in-bits='64'> @@ -1497,50 +2331,10 @@ </function-decl> </abi-instr> <abi-instr address-size='64' path='lib/libspl/tunables.c' language='LANG_C99'> - <enum-decl name='zfs_tunable_type_t' naming-typedef-id='f50b1525' id='56905369'> - <underlying-type type-id='9cac1fee'/> - <enumerator name='ZFS_TUNABLE_TYPE_INT' value='0'/> - <enumerator name='ZFS_TUNABLE_TYPE_UINT' value='1'/> - <enumerator name='ZFS_TUNABLE_TYPE_ULONG' value='2'/> - <enumerator name='ZFS_TUNABLE_TYPE_U64' value='3'/> - <enumerator name='ZFS_TUNABLE_TYPE_STRING' value='4'/> - </enum-decl> - <typedef-decl name='zfs_tunable_type_t' type-id='56905369' id='f50b1525'/> - <enum-decl name='zfs_tunable_perm_t' naming-typedef-id='ada7336b' id='e80e6ebf'> - <underlying-type type-id='9cac1fee'/> - <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RW' value='0'/> - <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RD' value='1'/> - </enum-decl> - <typedef-decl name='zfs_tunable_perm_t' type-id='e80e6ebf' id='ada7336b'/> - <class-decl name='zfs_tunable' size-in-bits='320' is-struct='yes' visibility='default' id='1a97ee0e'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='zt_name' type-id='80f4b756' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='zt_varp' type-id='eaa32e2f' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='zt_varsz' type-id='b59d7dce' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='zt_type' type-id='f50b1525' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='zt_perm' type-id='ada7336b' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='zt_desc' type-id='80f4b756' visibility='default'/> - </data-member> - </class-decl> - <typedef-decl name='zfs_tunable_t' type-id='1a97ee0e' id='12bf5c5e'/> - <typedef-decl name='zfs_tunable_iter_t' type-id='7ef33f92' id='d8d5f4ab'/> <typedef-decl name='intmax_t' type-id='5b475db0' id='e104d842'/> <typedef-decl name='uintmax_t' type-id='04d82f4b' id='f8b828c9'/> <typedef-decl name='__intmax_t' type-id='bd54fe1a' id='5b475db0'/> <typedef-decl name='__uintmax_t' type-id='7359adad' id='04d82f4b'/> - <qualified-type-def type-id='12bf5c5e' const='yes' id='180e47ee'/> - <pointer-type-def type-id='180e47ee' size-in-bits='64' id='a27af98c'/> - <pointer-type-def type-id='92f86508' size-in-bits='64' id='7ef33f92'/> <function-decl name='strtoimax' visibility='default' binding='global' size-in-bits='64'> <parameter type-id='9d26089a'/> <parameter type-id='8c85230f'/> @@ -1553,31 +2347,6 @@ <parameter type-id='95e97e5e'/> <return type-id='f8b828c9'/> </function-decl> - <function-decl name='zfs_tunable_lookup' mangled-name='zfs_tunable_lookup' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_lookup'> - <parameter type-id='80f4b756' name='name'/> - <return type-id='a27af98c'/> - </function-decl> - <function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'> - <parameter type-id='d8d5f4ab' name='cb'/> - <parameter type-id='eaa32e2f' name='arg'/> - <return type-id='48b5725f'/> - </function-decl> - <function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'> - <parameter type-id='a27af98c' name='zt'/> - <parameter type-id='80f4b756' name='val'/> - <return type-id='95e97e5e'/> - </function-decl> - <function-decl name='zfs_tunable_get' mangled-name='zfs_tunable_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_get'> - <parameter type-id='a27af98c' name='zt'/> - <parameter type-id='26a90f95' name='val'/> - <parameter type-id='b59d7dce' name='valsz'/> - <return type-id='95e97e5e'/> - </function-decl> - <function-type size-in-bits='64' id='92f86508'> - <parameter type-id='a27af98c'/> - <parameter type-id='eaa32e2f'/> - <return type-id='95e97e5e'/> - </function-type> </abi-instr> <abi-instr address-size='64' path='lib/libtpool/thread_pool.c' language='LANG_C99'> <array-type-def dimensions='1' type-id='49ef3ffd' size-in-bits='1024' id='a14403f5'> @@ -1808,10 +2577,6 @@ <parameter type-id='7292109c'/> <return type-id='95e97e5e'/> </function-decl> - <function-decl name='__pthread_unregister_cancel' visibility='default' binding='global' size-in-bits='64'> - <parameter type-id='ba7c727c'/> - <return type-id='48b5725f'/> - </function-decl> <function-decl name='pthread_cond_init' visibility='default' binding='global' size-in-bits='64'> <parameter type-id='2a468b41'/> <parameter type-id='4c428e67'/> @@ -1915,10 +2680,6 @@ <var-decl name='tp_idle' type-id='95e97e5e' visibility='default'/> </data-member> </class-decl> - <function-type size-in-bits='64' id='c5c76c9c'> - <parameter type-id='eaa32e2f'/> - <return type-id='48b5725f'/> - </function-type> </abi-instr> <abi-instr address-size='64' path='lib/libzfs/libzfs_changelist.c' language='LANG_C99'> <array-type-def dimensions='1' type-id='bf311473' size-in-bits='128' id='f0f65199'> @@ -2639,9 +3400,6 @@ <parameter type-id='4567bbc9'/> <return type-id='48b5725f'/> </function-decl> - <function-decl name='getzoneid' mangled-name='getzoneid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getzoneid'> - <return type-id='4da03624'/> - </function-decl> <function-decl name='sa_commit_shares' mangled-name='sa_commit_shares' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sa_commit_shares'> <parameter type-id='9155d4b5'/> <return type-id='48b5725f'/> @@ -2658,6 +3416,9 @@ <parameter type-id='b59d7dce'/> <return type-id='b59d7dce'/> </function-decl> + <function-decl name='getzoneid' mangled-name='getzoneid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getzoneid'> + <return type-id='4da03624'/> + </function-decl> <function-decl name='free' visibility='default' binding='global' size-in-bits='64'> <parameter type-id='eaa32e2f'/> <return type-id='48b5725f'/> @@ -3286,7 +4047,6 @@ </class-decl> <typedef-decl name='regmatch_t' type-id='4f932615' id='1b941664'/> <typedef-decl name='__sighandler_t' type-id='03347643' id='8cdd9566'/> - <typedef-decl name='ssize_t' type-id='41060289' id='79a0948f'/> <class-decl name='sigaction' size-in-bits='1216' is-struct='yes' visibility='default' id='fe391c48'> <data-member access='public' layout-offset-in-bits='0'> <var-decl name='__sigaction_handler' type-id='ac5ab596' visibility='default'/> @@ -3588,6 +4348,7 @@ <var-decl name='_unused2' type-id='664ac0b7' visibility='default'/> </data-member> </class-decl> + <typedef-decl name='ssize_t' type-id='41060289' id='79a0948f'/> <pointer-type-def type-id='aa12d1ba' size-in-bits='64' id='822cd80b'/> <qualified-type-def type-id='822cd80b' restrict='yes' id='e75a27e9'/> <pointer-type-def type-id='ec1ed955' size-in-bits='64' id='dca988a5'/> @@ -6026,7 +6787,8 @@ <enumerator name='VDEV_PROP_SLOW_IOS' value='51'/> <enumerator name='VDEV_PROP_SIT_OUT' value='52'/> <enumerator name='VDEV_PROP_AUTOSIT' value='53'/> - <enumerator name='VDEV_NUM_PROPS' value='54'/> + <enumerator name='VDEV_PROP_SLOW_IO_EVENTS' value='54'/> + <enumerator name='VDEV_NUM_PROPS' value='55'/> </enum-decl> <typedef-decl name='vdev_prop_t' type-id='1573bec8' id='5aa5c90c'/> <class-decl name='zpool_load_policy' size-in-bits='256' is-struct='yes' visibility='default' id='2f65b36f'> @@ -6250,6 +7012,7 @@ <underlying-type type-id='9cac1fee'/> <enumerator name='ZPOOL_PREFETCH_NONE' value='0'/> <enumerator name='ZPOOL_PREFETCH_DDT' value='1'/> + <enumerator name='ZPOOL_PREFETCH_BRT' value='2'/> </enum-decl> <typedef-decl name='zpool_prefetch_type_t' type-id='0299ab50' id='e55ff6bc'/> <enum-decl name='zpool_ddt_prune_unit_t' naming-typedef-id='02e25ab0' id='509ae11c'> @@ -7988,6 +8751,10 @@ <parameter type-id='ba7c727c'/> <return type-id='48b5725f'/> </function-decl> + <function-decl name='__pthread_unregister_cancel' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='ba7c727c'/> + <return type-id='48b5725f'/> + </function-decl> <function-decl name='__pthread_unwind_next' visibility='default' binding='global' size-in-bits='64'> <parameter type-id='ba7c727c'/> <return type-id='48b5725f'/> diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c b/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c index b34a44c30eb4..f461ad41405b 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_crypto.c @@ -19,7 +19,6 @@ * Copyright 2020 Joyent, Inc. */ -#include <sys/zfs_context.h> #include <sys/fs/zfs.h> #include <sys/dsl_crypt.h> #include <libintl.h> @@ -613,7 +612,9 @@ get_key_material_https(libzfs_handle_t *hdl, const char *uri, (void) unlink(path); free(path); +#ifdef O_TMPFILE kfdok: +#endif if ((key = fdopen(kfd, "r+")) == NULL) { ret = errno; (void) close(kfd); diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c b/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c index ce154ae1a4cd..756d701e2d97 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_pool.c @@ -1745,9 +1745,13 @@ zpool_prefetch(zpool_handle_t *zhp, zpool_prefetch_type_t type) error = lzc_pool_prefetch(zhp->zpool_name, type); if (error != 0) { + const char *typename = "unknown"; + if (type == ZPOOL_PREFETCH_DDT) + typename = "ddt"; + else if (type == ZPOOL_PREFETCH_BRT) + typename = "brt"; (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, - "cannot prefetch %s in '%s'"), - type == ZPOOL_PREFETCH_DDT ? "ddt" : "", zhp->zpool_name); + "cannot prefetch %s in '%s'"), typename, zhp->zpool_name); (void) zpool_standard_error(hdl, error, msg); return (-1); } diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c index 77134d197904..0e5cecc6cca9 100644 --- a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c +++ b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c @@ -1013,7 +1013,8 @@ send_progress_thread(void *arg) &blocks)) != 0) { if (err == EINTR || err == ENOENT) err = 0; - pthread_exit(((void *)(uintptr_t)err)); + /* Use break to reach pthread_cleanup_pop() below. */ + break; } (void) time(&t); @@ -1055,7 +1056,7 @@ send_progress_thread(void *arg) } } pthread_cleanup_pop(B_TRUE); - return (NULL); + pthread_exit(((void *)(uintptr_t)err)); } static boolean_t diff --git a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c index 55dfdf3723bd..651d407b1884 100644 --- a/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c +++ b/sys/contrib/openzfs/lib/libzfs/os/linux/libzfs_util_os.c @@ -78,6 +78,38 @@ libzfs_error_init(int error) } } +static int +in_container(void) +{ + char buffer[4096]; + ssize_t count; + int fd; + + if (access("/run/systemd/container", R_OK) == 0) + return (1); + + fd = open("/proc/1/cgroup", O_RDONLY); + if (fd == -1) + return (0); + + count = read(fd, buffer, sizeof (buffer) - 1); + close(fd); + + if (count <= 0) + return (0); + + buffer[count] = '\0'; + + if (strstr(buffer, "docker") || + strstr(buffer, "containerd") || + strstr(buffer, "kubepods") || + strstr(buffer, "lxc")) { + return (1); + } + + return (0); +} + /* * zfs(4) is loaded by udev if there's a fstype=zfs device present, * but if there isn't, load them automatically; @@ -104,6 +136,11 @@ libzfs_load_module(void) const char *timeout_str = getenv("ZFS_MODULE_TIMEOUT"); int seconds = 10; + + /* Set timeout to zero if inside of a container */ + if (in_container()) + seconds = 0; + if (timeout_str) seconds = MIN(strtol(timeout_str, NULL, 0), 600); struct itimerspec timeout = {.it_value.tv_sec = MAX(seconds, 0)}; diff --git a/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi b/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi index 263cad045f7a..238151d432f1 100644 --- a/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi +++ b/sys/contrib/openzfs/lib/libzfs_core/libzfs_core.abi @@ -7,6 +7,8 @@ </elf-needed> <elf-function-symbols> <elf-symbol name='_sol_getmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_system_delay_taskq' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_system_taskq' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_add_16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_add_16_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_add_32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -127,6 +129,19 @@ <elf-symbol name='atomic_swap_uint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_swap_ulong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_swap_ushort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetgid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetgroups' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetngroups' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetruid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='crgetuid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_broadcast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_signal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_timedwait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_timedwait_hires' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='cv_wait_sig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='format_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='get_system_hostid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='get_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -134,8 +149,21 @@ <elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getzoneid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_asprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_cache_reap_active' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_scnprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kmem_vasprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='ksid_lookupdomain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='ksiddomain_rele' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_delete' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_install' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='kstat_set_raw_ops' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libspl_assertf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libspl_backtrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='libspl_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='libspl_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='libspl_physmem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libspl_set_assert_ok' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libzfs_core_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='libzfs_core_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -218,32 +246,56 @@ <elf-symbol name='membar_producer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='membar_sync' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='mkdirp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_enter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_enter_check_return' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='mutex_tryenter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='p0' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='print_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_install' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='procfs_list_uninstall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_force_pseudo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_get_bytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_get_pseudo_bytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='random_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_enter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_tryenter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='rw_tryupgrade' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='seq_printf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='spl_fstrans_mark' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='spl_fstrans_unmark' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='spl_pagesize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='strlcat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='strlcpy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='zfs_tunable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='system_taskq_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='system_taskq_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_cancel_id' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_create_synced' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_dispatch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_dispatch_delay' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_dispatch_ent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_empty_ent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_init_ent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_member' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_of_curthread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_wait_id' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='taskq_wait_outstanding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='utsname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='zk_thread_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> </elf-function-symbols> <abi-instr address-size='64' path='lib/libspl/assert.c' language='LANG_C99'> - <class-decl name='__va_list_tag' size-in-bits='192' is-struct='yes' visibility='default' id='d5027220'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='gp_offset' type-id='f0981eeb' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='fp_offset' type-id='f0981eeb' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='overflow_arg_area' type-id='eaa32e2f' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='reg_save_area' type-id='eaa32e2f' visibility='default'/> - </data-member> - </class-decl> <typedef-decl name='__pid_t' type-id='95e97e5e' id='3629bad8'/> - <pointer-type-def type-id='d5027220' size-in-bits='64' id='b7f2d5e6'/> <function-decl name='libspl_backtrace' mangled-name='libspl_backtrace' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_backtrace'> <parameter type-id='95e97e5e'/> <return type-id='48b5725f'/> @@ -617,7 +669,6 @@ <array-type-def dimensions='1' type-id='de572c22' size-in-bits='1472' id='6d3c2f42'> <subrange length='23' type-id='7359adad' id='fdd0f594'/> </array-type-def> - <type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/> <array-type-def dimensions='1' type-id='3a47d82b' size-in-bits='256' id='a133ec23'> <subrange length='4' type-id='7359adad' id='16fe7105'/> </array-type-def> @@ -798,6 +849,223 @@ <return type-id='95e97e5e'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/condvar.c' language='LANG_C99'> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='384' id='36d7f119'> + <subrange length='48' type-id='7359adad' id='8f6d2a81'/> + </array-type-def> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='32' id='8e0573fd'> + <subrange length='4' type-id='7359adad' id='16fe7105'/> + </array-type-def> + <type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/> + <type-decl name='long long unsigned int' size-in-bits='64' id='3a47d82b'/> + <array-type-def dimensions='1' type-id='f0981eeb' size-in-bits='64' id='0d532ec1'> + <subrange length='2' type-id='7359adad' id='52efc4ef'/> + </array-type-def> + <typedef-decl name='kcondvar_t' type-id='62fab762' id='29dbc0dd'/> + <class-decl name='kmutex' size-in-bits='384' is-struct='yes' visibility='default' id='f1cacfe1'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='m_lock' type-id='7a6844eb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='m_owner' type-id='4051f5e7' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='kmutex_t' type-id='f1cacfe1' id='b9eccc8f'/> + <typedef-decl name='hrtime_t' type-id='1eb56b1e' id='cebdd548'/> + <union-decl name='__atomic_wide_counter' size-in-bits='64' naming-typedef-id='f3b40860' visibility='default' id='613ce450'> + <data-member access='public'> + <var-decl name='__value64' type-id='3a47d82b' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__value32' type-id='e7f43f72' visibility='default'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f72'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__low' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='__high' type-id='f0981eeb' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='__atomic_wide_counter' type-id='613ce450' id='f3b40860'/> + <union-decl name='pthread_condattr_t' size-in-bits='32' naming-typedef-id='836265dd' visibility='default' id='33dd3aad'> + <data-member access='public'> + <var-decl name='__size' type-id='8e0573fd' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='95e97e5e' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_condattr_t' type-id='33dd3aad' id='836265dd'/> + <union-decl name='pthread_cond_t' size-in-bits='384' naming-typedef-id='62fab762' visibility='default' id='cbb12c12'> + <data-member access='public'> + <var-decl name='__data' type-id='c987b47c' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__size' type-id='36d7f119' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='1eb56b1e' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_cond_t' type-id='cbb12c12' id='62fab762'/> + <class-decl name='__pthread_cond_s' size-in-bits='384' is-struct='yes' visibility='default' id='c987b47c'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__wseq' type-id='f3b40860' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='__g1_start' type-id='f3b40860' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='__g_refs' type-id='0d532ec1' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='__g_size' type-id='0d532ec1' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='__g1_orig_size' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='__wrefs' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='__g_signals' type-id='0d532ec1' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='__clock_t' type-id='bd54fe1a' id='4d66c6d7'/> + <typedef-decl name='__suseconds_t' type-id='bd54fe1a' id='5b102a54'/> + <typedef-decl name='__clockid_t' type-id='95e97e5e' id='08f9a87a'/> + <typedef-decl name='clock_t' type-id='4d66c6d7' id='4c3a2c61'/> + <typedef-decl name='clockid_t' type-id='08f9a87a' id='a1c3b834'/> + <class-decl name='timeval' size-in-bits='128' is-struct='yes' visibility='default' id='2a693ac3'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tv_sec' type-id='65eda9c0' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tv_usec' type-id='5b102a54' visibility='default'/> + </data-member> + </class-decl> + <qualified-type-def type-id='836265dd' const='yes' id='7d24c58d'/> + <pointer-type-def type-id='7d24c58d' size-in-bits='64' id='a7e325e5'/> + <qualified-type-def type-id='a7e325e5' restrict='yes' id='4c428e67'/> + <qualified-type-def type-id='a9c79a1f' const='yes' id='cd087e36'/> + <pointer-type-def type-id='cd087e36' size-in-bits='64' id='e05e8614'/> + <qualified-type-def type-id='e05e8614' restrict='yes' id='0be2e71c'/> + <pointer-type-def type-id='29dbc0dd' size-in-bits='64' id='068c4f7e'/> + <pointer-type-def type-id='b9eccc8f' size-in-bits='64' id='78830f38'/> + <pointer-type-def type-id='62fab762' size-in-bits='64' id='db285b03'/> + <qualified-type-def type-id='db285b03' restrict='yes' id='2a468b41'/> + <qualified-type-def type-id='18c91f9e' restrict='yes' id='6e745582'/> + <pointer-type-def type-id='a9c79a1f' size-in-bits='64' id='3d83ba87'/> + <pointer-type-def type-id='2a693ac3' size-in-bits='64' id='896f1b83'/> + <qualified-type-def type-id='896f1b83' restrict='yes' id='4bcf44c1'/> + <function-decl name='pthread_self' visibility='default' binding='global' size-in-bits='64'> + <return type-id='4051f5e7'/> + </function-decl> + <function-decl name='pthread_cond_init' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2a468b41'/> + <parameter type-id='4c428e67'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_cond_destroy' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='db285b03'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_cond_signal' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='db285b03'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_cond_broadcast' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='db285b03'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_cond_wait' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2a468b41'/> + <parameter type-id='6e745582'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_cond_timedwait' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2a468b41'/> + <parameter type-id='6e745582'/> + <parameter type-id='0be2e71c'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='clock_gettime' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a1c3b834'/> + <parameter type-id='3d83ba87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='gettimeofday' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='4bcf44c1'/> + <parameter type-id='1b7446cd'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_init' mangled-name='cv_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_init'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='26a90f95' name='name'/> + <parameter type-id='95e97e5e' name='type'/> + <parameter type-id='eaa32e2f' name='arg'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_destroy' mangled-name='cv_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_destroy'> + <parameter type-id='068c4f7e' name='cv'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_wait' mangled-name='cv_wait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_wait'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_wait_sig' mangled-name='cv_wait_sig' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_wait_sig'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_timedwait' mangled-name='cv_timedwait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_timedwait'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <parameter type-id='4c3a2c61' name='abstime'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_timedwait_hires' mangled-name='cv_timedwait_hires' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_timedwait_hires'> + <parameter type-id='068c4f7e' name='cv'/> + <parameter type-id='78830f38' name='mp'/> + <parameter type-id='cebdd548' name='tim'/> + <parameter type-id='cebdd548' name='res'/> + <parameter type-id='95e97e5e' name='flag'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='cv_signal' mangled-name='cv_signal' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_signal'> + <parameter type-id='068c4f7e' name='cv'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='cv_broadcast' mangled-name='cv_broadcast' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cv_broadcast'> + <parameter type-id='068c4f7e' name='cv'/> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/cred.c' language='LANG_C99'> + <class-decl name='cred' is-struct='yes' visibility='default' is-declaration-only='yes' id='6739dd09'/> + <typedef-decl name='cred_t' type-id='6739dd09' id='a42f1a8f'/> + <typedef-decl name='gid_t' type-id='d94ec6d9' id='2bb2b96f'/> + <typedef-decl name='uid_t' type-id='cc5fcceb' id='354978ed'/> + <pointer-type-def type-id='a42f1a8f' size-in-bits='64' id='f89fcf80'/> + <pointer-type-def type-id='2bb2b96f' size-in-bits='64' id='b52814e6'/> + <class-decl name='cred' is-struct='yes' visibility='default' is-declaration-only='yes' id='6739dd09'/> + <function-decl name='crgetuid' mangled-name='crgetuid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crgetuid'> + <parameter type-id='f89fcf80' name='cr'/> + <return type-id='354978ed'/> + </function-decl> + <function-decl name='crgetngroups' mangled-name='crgetngroups' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crgetngroups'> + <parameter type-id='f89fcf80' name='cr'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='crgetgroups' mangled-name='crgetgroups' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='crgetgroups'> + <parameter type-id='f89fcf80' name='cr'/> + <return type-id='b52814e6'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/getexecname.c' language='LANG_C99'> <function-decl name='getexecname' mangled-name='getexecname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getexecname'> <return type-id='80f4b756'/> @@ -807,6 +1075,188 @@ <return type-id='79a0948f'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/kmem.c' language='LANG_C99'> + <class-decl name='__va_list_tag' size-in-bits='192' is-struct='yes' visibility='default' id='d5027220'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='gp_offset' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='fp_offset' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='overflow_arg_area' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='reg_save_area' type-id='eaa32e2f' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='fstrans_cookie_t' type-id='95e97e5e' id='059934c1'/> + <pointer-type-def type-id='d5027220' size-in-bits='64' id='b7f2d5e6'/> + <qualified-type-def type-id='26a90f95' restrict='yes' id='266fe297'/> + <pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/> + <qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/> + <function-decl name='__vasprintf_chk' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='8c85230f'/> + <parameter type-id='95e97e5e'/> + <parameter type-id='9d26089a'/> + <parameter type-id='b7f2d5e6'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='kmem_vasprintf' mangled-name='kmem_vasprintf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_vasprintf'> + <parameter type-id='80f4b756' name='fmt'/> + <parameter type-id='b7f2d5e6' name='adx'/> + <return type-id='26a90f95'/> + </function-decl> + <function-decl name='kmem_asprintf' mangled-name='kmem_asprintf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_asprintf'> + <parameter type-id='80f4b756' name='fmt'/> + <parameter is-variadic='yes'/> + <return type-id='26a90f95'/> + </function-decl> + <function-decl name='kmem_scnprintf' mangled-name='kmem_scnprintf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_scnprintf'> + <parameter type-id='266fe297' name='str'/> + <parameter type-id='b59d7dce' name='size'/> + <parameter type-id='9d26089a' name='fmt'/> + <parameter is-variadic='yes'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='spl_fstrans_unmark' mangled-name='spl_fstrans_unmark' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spl_fstrans_unmark'> + <parameter type-id='059934c1' name='cookie'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='kmem_cache_reap_active' mangled-name='kmem_cache_reap_active' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kmem_cache_reap_active'> + <return type-id='95e97e5e'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/kstat.c' language='LANG_C99'> + <class-decl name='kstat' size-in-bits='448' is-struct='yes' visibility='default' id='5f5c9d88'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ks_flags' type-id='d8bf0010' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ks_data' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ks_ndata' type-id='3502e3ff' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ks_data_size' type-id='b59d7dce' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='ks_update' type-id='8cf7b7e1' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='ks_private' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='ks_lock' type-id='eaa32e2f' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='kstat_t' type-id='5f5c9d88' id='dd12e024'/> + <typedef-decl name='__loff_t' type-id='724e4de6' id='00c9d214'/> + <typedef-decl name='loff_t' type-id='00c9d214' id='69bf7bee'/> + <pointer-type-def type-id='9d5d322a' size-in-bits='64' id='bbe97414'/> + <pointer-type-def type-id='05b3c714' size-in-bits='64' id='27cc5c36'/> + <pointer-type-def type-id='7a9ace65' size-in-bits='64' id='8cf7b7e1'/> + <pointer-type-def type-id='5f5c9d88' size-in-bits='64' id='0e87f9be'/> + <pointer-type-def type-id='dd12e024' size-in-bits='64' id='46e5e463'/> + <pointer-type-def type-id='527a97c5' size-in-bits='64' id='673f2af9'/> + <function-decl name='kstat_create' mangled-name='kstat_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_create'> + <parameter type-id='80f4b756' name='module'/> + <parameter type-id='95e97e5e' name='instance'/> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='80f4b756' name='class'/> + <parameter type-id='d8bf0010' name='type'/> + <parameter type-id='ee1f298e' name='ndata'/> + <parameter type-id='d8bf0010' name='ks_flag'/> + <return type-id='46e5e463'/> + </function-decl> + <function-decl name='kstat_install' mangled-name='kstat_install' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_install'> + <parameter type-id='46e5e463' name='ksp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='kstat_set_raw_ops' mangled-name='kstat_set_raw_ops' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='kstat_set_raw_ops'> + <parameter type-id='46e5e463' name='ksp'/> + <parameter type-id='bbe97414' name='headers'/> + <parameter type-id='27cc5c36' name='data'/> + <parameter type-id='673f2af9' name='addr'/> + <return type-id='48b5725f'/> + </function-decl> + <function-type size-in-bits='64' id='9d5d322a'> + <parameter type-id='26a90f95'/> + <parameter type-id='b59d7dce'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='05b3c714'> + <parameter type-id='26a90f95'/> + <parameter type-id='b59d7dce'/> + <parameter type-id='eaa32e2f'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='7a9ace65'> + <parameter type-id='0e87f9be'/> + <parameter type-id='95e97e5e'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='527a97c5'> + <parameter type-id='46e5e463'/> + <parameter type-id='69bf7bee'/> + <return type-id='eaa32e2f'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/libspl.c' language='LANG_C99'> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='520' id='5ddd38d2'> + <subrange length='65' type-id='7359adad' id='b50e2e4a'/> + </array-type-def> + <typedef-decl name='utsname_t' type-id='414a2ac6' id='5278297a'/> + <class-decl name='utsname' size-in-bits='3120' is-struct='yes' visibility='default' id='414a2ac6'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='sysname' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='520'> + <var-decl name='nodename' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1040'> + <var-decl name='release' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1560'> + <var-decl name='version' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2080'> + <var-decl name='machine' type-id='5ddd38d2' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2600'> + <var-decl name='domainname' type-id='5ddd38d2' visibility='default'/> + </data-member> + </class-decl> + <pointer-type-def type-id='414a2ac6' size-in-bits='64' id='a6724cec'/> + <pointer-type-def type-id='5278297a' size-in-bits='64' id='5c7868ad'/> + <function-decl name='sysconf' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='95e97e5e'/> + <return type-id='bd54fe1a'/> + </function-decl> + <function-decl name='uname' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6724cec'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='libspl_physmem' mangled-name='libspl_physmem' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_physmem'> + <return type-id='9c313c2d'/> + </function-decl> + <function-decl name='utsname' mangled-name='utsname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='utsname'> + <return type-id='5c7868ad'/> + </function-decl> + <function-decl name='libspl_init' mangled-name='libspl_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_init'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='libspl_fini' mangled-name='libspl_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_fini'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='random_init' mangled-name='random_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_init'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='random_fini' mangled-name='random_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_fini'> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/list.c' language='LANG_C99'> <typedef-decl name='list_node_t' type-id='b0b5e45e' id='b21843b2'/> <typedef-decl name='list_t' type-id='e824dae9' id='0899125f'/> @@ -918,7 +1368,6 @@ <abi-instr address-size='64' path='lib/libspl/mkdirp.c' language='LANG_C99'> <typedef-decl name='mode_t' type-id='e1c52942' id='d50d396c'/> <typedef-decl name='wchar_t' type-id='95e97e5e' id='928221d2'/> - <qualified-type-def type-id='26a90f95' restrict='yes' id='266fe297'/> <qualified-type-def type-id='928221d2' const='yes' id='effb3702'/> <pointer-type-def type-id='effb3702' size-in-bits='64' id='f077d3f8'/> <qualified-type-def type-id='f077d3f8' restrict='yes' id='598aab80'/> @@ -967,6 +1416,59 @@ <return type-id='95e97e5e'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/mutex.c' language='LANG_C99'> + <union-decl name='pthread_mutexattr_t' size-in-bits='32' naming-typedef-id='8afd6070' visibility='default' id='7300eb00'> + <data-member access='public'> + <var-decl name='__size' type-id='8e0573fd' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='95e97e5e' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_mutexattr_t' type-id='7300eb00' id='8afd6070'/> + <qualified-type-def type-id='8afd6070' const='yes' id='1d853360'/> + <pointer-type-def type-id='1d853360' size-in-bits='64' id='c2afbd7e'/> + <function-decl name='pthread_mutex_init' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='18c91f9e'/> + <parameter type-id='c2afbd7e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_mutex_destroy' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='18c91f9e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_mutex_trylock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='18c91f9e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='mutex_init' mangled-name='mutex_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_init'> + <parameter type-id='78830f38' name='mp'/> + <parameter type-id='26a90f95' name='name'/> + <parameter type-id='95e97e5e' name='type'/> + <parameter type-id='eaa32e2f' name='cookie'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='mutex_destroy' mangled-name='mutex_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_destroy'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='mutex_enter' mangled-name='mutex_enter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_enter'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='mutex_enter_check_return' mangled-name='mutex_enter_check_return' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_enter_check_return'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='mutex_tryenter' mangled-name='mutex_tryenter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_tryenter'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='mutex_exit' mangled-name='mutex_exit' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mutex_exit'> + <parameter type-id='78830f38' name='mp'/> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/os/linux/getexecname.c' language='LANG_C99'> <function-decl name='__readlink_chk' visibility='default' binding='global' size-in-bits='64'> <parameter type-id='9d26089a'/> @@ -977,7 +1479,6 @@ </function-decl> </abi-instr> <abi-instr address-size='64' path='lib/libspl/os/linux/gethostid.c' language='LANG_C99'> - <type-decl name='long long unsigned int' size-in-bits='64' id='3a47d82b'/> <function-decl name='strtoull' visibility='default' binding='global' size-in-bits='64'> <parameter type-id='9d26089a'/> <parameter type-id='8c85230f'/> @@ -1149,14 +1650,273 @@ </function-decl> </abi-instr> <abi-instr address-size='64' path='lib/libspl/page.c' language='LANG_C99'> - <function-decl name='sysconf' visibility='default' binding='global' size-in-bits='64'> - <parameter type-id='95e97e5e'/> - <return type-id='bd54fe1a'/> - </function-decl> <function-decl name='spl_pagesize' mangled-name='spl_pagesize' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spl_pagesize'> <return type-id='b59d7dce'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/procfs_list.c' language='LANG_C99'> + <class-decl name='procfs_list' size-in-bits='768' is-struct='yes' visibility='default' id='0f4d3b87'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='pl_private' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='pl_lock' type-id='b9eccc8f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='pl_list' type-id='0899125f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='pl_next_id' type-id='9c313c2d' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='pl_node_offset' type-id='b59d7dce' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='procfs_list_t' type-id='0f4d3b87' id='e5b5a21b'/> + <class-decl name='seq_file' is-struct='yes' visibility='default' id='f3415517'/> + <pointer-type-def type-id='be39c944' size-in-bits='64' id='b5c3ae96'/> + <pointer-type-def type-id='86932239' size-in-bits='64' id='6255c89d'/> + <pointer-type-def type-id='cf9ec29d' size-in-bits='64' id='0131eb61'/> + <pointer-type-def type-id='e5b5a21b' size-in-bits='64' id='7f432372'/> + <pointer-type-def type-id='f3415517' size-in-bits='64' id='f8dc9def'/> + <function-decl name='seq_printf' mangled-name='seq_printf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='seq_printf'> + <parameter type-id='f8dc9def' name='m'/> + <parameter type-id='80f4b756' name='fmt'/> + <parameter is-variadic='yes'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_install' mangled-name='procfs_list_install' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_install'> + <parameter type-id='80f4b756' name='module'/> + <parameter type-id='80f4b756' name='submodule'/> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='d50d396c' name='mode'/> + <parameter type-id='7f432372' name='procfs_list'/> + <parameter type-id='0131eb61' name='show'/> + <parameter type-id='6255c89d' name='show_header'/> + <parameter type-id='b5c3ae96' name='clear'/> + <parameter type-id='b59d7dce' name='procfs_list_node_off'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_uninstall' mangled-name='procfs_list_uninstall' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_uninstall'> + <parameter type-id='7f432372' name='procfs_list'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_destroy' mangled-name='procfs_list_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_destroy'> + <parameter type-id='7f432372' name='procfs_list'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='procfs_list_add' mangled-name='procfs_list_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='procfs_list_add'> + <parameter type-id='7f432372' name='procfs_list'/> + <parameter type-id='eaa32e2f' name='p'/> + <return type-id='48b5725f'/> + </function-decl> + <function-type size-in-bits='64' id='be39c944'> + <parameter type-id='7f432372'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='86932239'> + <parameter type-id='f8dc9def'/> + <return type-id='95e97e5e'/> + </function-type> + <function-type size-in-bits='64' id='cf9ec29d'> + <parameter type-id='f8dc9def'/> + <parameter type-id='eaa32e2f'/> + <return type-id='95e97e5e'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/random.c' language='LANG_C99'> + <function-decl name='random_force_pseudo' mangled-name='random_force_pseudo' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_force_pseudo'> + <parameter type-id='c19b74c3' name='onoff'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='random_get_bytes' mangled-name='random_get_bytes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_get_bytes'> + <parameter type-id='ae3e8ca6' name='ptr'/> + <parameter type-id='b59d7dce' name='len'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='random_get_pseudo_bytes' mangled-name='random_get_pseudo_bytes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='random_get_pseudo_bytes'> + <parameter type-id='ae3e8ca6' name='ptr'/> + <parameter type-id='b59d7dce' name='len'/> + <return type-id='95e97e5e'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/rwlock.c' language='LANG_C99'> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='64' id='8e100159'> + <subrange length='8' type-id='7359adad' id='56e0c0b1'/> + </array-type-def> + <array-type-def dimensions='1' type-id='002ac4a6' size-in-bits='56' id='08f7ce77'> + <subrange length='7' type-id='7359adad' id='16fc326e'/> + </array-type-def> + <class-decl name='krwlock' size-in-bits='576' is-struct='yes' visibility='default' id='4361e3b2'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='rw_lock' type-id='3f680bc6' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='rw_owner' type-id='4051f5e7' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='rw_readers' type-id='3502e3ff' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='krwlock_t' type-id='4361e3b2' id='477df69a'/> + <typedef-decl name='krw_t' type-id='95e97e5e' id='932eed5d'/> + <union-decl name='pthread_rwlock_t' size-in-bits='448' naming-typedef-id='3f680bc6' visibility='default' id='981886f6'> + <data-member access='public'> + <var-decl name='__data' type-id='afe414a4' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__size' type-id='6093ff7c' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='bd54fe1a' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_rwlock_t' type-id='981886f6' id='3f680bc6'/> + <union-decl name='pthread_rwlockattr_t' size-in-bits='64' naming-typedef-id='1b1c4591' visibility='default' id='b8e57521'> + <data-member access='public'> + <var-decl name='__size' type-id='8e100159' visibility='default'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='bd54fe1a' visibility='default'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_rwlockattr_t' type-id='b8e57521' id='1b1c4591'/> + <class-decl name='__pthread_rwlock_arch_t' size-in-bits='448' is-struct='yes' visibility='default' id='afe414a4'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__readers' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='__writers' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='__wrphase_futex' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='__writers_futex' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='__pad3' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='__pad4' type-id='f0981eeb' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='__cur_writer' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='__shared' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='__rwelision' type-id='28577a57' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='264'> + <var-decl name='__pad1' type-id='08f7ce77' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='__pad2' type-id='7359adad' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='__flags' type-id='f0981eeb' visibility='default'/> + </data-member> + </class-decl> + <qualified-type-def type-id='1b1c4591' const='yes' id='52c85581'/> + <pointer-type-def type-id='52c85581' size-in-bits='64' id='fc5edc31'/> + <qualified-type-def type-id='fc5edc31' restrict='yes' id='295e8f33'/> + <pointer-type-def type-id='477df69a' size-in-bits='64' id='0126db61'/> + <pointer-type-def type-id='3f680bc6' size-in-bits='64' id='a6210c87'/> + <qualified-type-def type-id='a6210c87' restrict='yes' id='27210b05'/> + <qualified-type-def type-id='3502e3ff' volatile='yes' id='d0290e74'/> + <pointer-type-def type-id='d0290e74' size-in-bits='64' id='0ea19dfa'/> + <function-decl name='atomic_inc_uint' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='0ea19dfa'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='atomic_dec_uint' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='0ea19dfa'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='pthread_rwlock_init' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='27210b05'/> + <parameter type-id='295e8f33'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_destroy' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_rdlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_tryrdlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_wrlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_trywrlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_rwlock_unlock' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='a6210c87'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='rw_init' mangled-name='rw_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_init'> + <parameter type-id='0126db61' name='rwlp'/> + <parameter type-id='26a90f95' name='name'/> + <parameter type-id='95e97e5e' name='type'/> + <parameter type-id='eaa32e2f' name='arg'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_destroy' mangled-name='rw_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_destroy'> + <parameter type-id='0126db61' name='rwlp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_enter' mangled-name='rw_enter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_enter'> + <parameter type-id='0126db61' name='rwlp'/> + <parameter type-id='932eed5d' name='rw'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_exit' mangled-name='rw_exit' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_exit'> + <parameter type-id='0126db61' name='rwlp'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='rw_tryenter' mangled-name='rw_tryenter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_tryenter'> + <parameter type-id='0126db61' name='rwlp'/> + <parameter type-id='932eed5d' name='rw'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='rw_tryupgrade' mangled-name='rw_tryupgrade' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='rw_tryupgrade'> + <parameter type-id='0126db61' name='rwlp'/> + <return type-id='95e97e5e'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/sid.c' language='LANG_C99'> + <class-decl name='ksiddomain' size-in-bits='128' is-struct='yes' visibility='default' id='b3a38f42'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kd_ref' type-id='3502e3ff' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='kd_len' type-id='3502e3ff' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='kd_name' type-id='26a90f95' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='ksiddomain_t' type-id='b3a38f42' id='db2eb030'/> + <pointer-type-def type-id='db2eb030' size-in-bits='64' id='3b684881'/> + <function-decl name='ksid_lookupdomain' mangled-name='ksid_lookupdomain' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ksid_lookupdomain'> + <parameter type-id='80f4b756' name='dom'/> + <return type-id='3b684881'/> + </function-decl> + <function-decl name='ksiddomain_rele' mangled-name='ksiddomain_rele' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='ksiddomain_rele'> + <parameter type-id='3b684881' name='ksid'/> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/strlcat.c' language='LANG_C99'> <function-decl name='strlcat' mangled-name='strlcat' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='strlcat'> <parameter type-id='26a90f95' name='dst'/> @@ -1165,6 +1925,261 @@ <return type-id='b59d7dce'/> </function-decl> </abi-instr> + <abi-instr address-size='64' path='lib/libspl/taskq.c' language='LANG_C99'> + <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='256' id='16dc656a'> + <subrange length='32' type-id='7359adad' id='ae5bde82'/> + </array-type-def> + <typedef-decl name='pri_t' type-id='a2185560' id='c497180a'/> + <typedef-decl name='taskqid_t' type-id='e475ab95' id='de0ea20e'/> + <typedef-decl name='task_func_t' type-id='c5c76c9c' id='d8481e1f'/> + <class-decl name='taskq_ent' size-in-bits='320' is-struct='yes' visibility='default' id='cfda1b05'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tqent_next' type-id='67918d75' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tqent_prev' type-id='67918d75' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='tqent_func' type-id='41cce5ce' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='tqent_arg' type-id='eaa32e2f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='tqent_flags' type-id='e475ab95' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='taskq_ent_t' type-id='cfda1b05' id='65d297d1'/> + <class-decl name='taskq' size-in-bits='3072' is-struct='yes' visibility='default' id='1804594f'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tq_name' type-id='16dc656a' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='tq_lock' type-id='b9eccc8f' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='tq_threadlock' type-id='477df69a' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='tq_dispatch_cv' type-id='29dbc0dd' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1600'> + <var-decl name='tq_wait_cv' type-id='29dbc0dd' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1984'> + <var-decl name='tq_threadlist' type-id='6e87b565' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2048'> + <var-decl name='tq_flags' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2080'> + <var-decl name='tq_active' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2112'> + <var-decl name='tq_nthreads' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2144'> + <var-decl name='tq_nalloc' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2176'> + <var-decl name='tq_minalloc' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2208'> + <var-decl name='tq_maxalloc' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2240'> + <var-decl name='tq_maxalloc_cv' type-id='29dbc0dd' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2624'> + <var-decl name='tq_maxalloc_wait' type-id='95e97e5e' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2688'> + <var-decl name='tq_freelist' type-id='3a4f23d4' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2752'> + <var-decl name='tq_task' type-id='65d297d1' visibility='default'/> + </data-member> + </class-decl> + <typedef-decl name='taskq_t' type-id='1804594f' id='ef507f03'/> + <typedef-decl name='kthread_t' type-id='4051f5e7' id='9bccee1a'/> + <typedef-decl name='uintptr_t' type-id='7359adad' id='e475ab95'/> + <typedef-decl name='pthread_key_t' type-id='f0981eeb' id='2de5383b'/> + <pointer-type-def type-id='9bccee1a' size-in-bits='64' id='6ae5a80d'/> + <pointer-type-def type-id='6ae5a80d' size-in-bits='64' id='6e87b565'/> + <pointer-type-def type-id='6e87b565' size-in-bits='64' id='4ea26b5d'/> + <pointer-type-def type-id='2de5383b' size-in-bits='64' id='ce04b822'/> + <pointer-type-def type-id='d8481e1f' size-in-bits='64' id='41cce5ce'/> + <pointer-type-def type-id='cfda1b05' size-in-bits='64' id='67918d75'/> + <pointer-type-def type-id='65d297d1' size-in-bits='64' id='3a4f23d4'/> + <pointer-type-def type-id='ef507f03' size-in-bits='64' id='4f8ed29a'/> + <pointer-type-def type-id='c5c76c9c' size-in-bits='64' id='b7f9d8e6'/> + <function-decl name='zk_thread_create' mangled-name='zk_thread_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zk_thread_create'> + <parameter type-id='80f4b756'/> + <parameter type-id='b7f9d8e6'/> + <parameter type-id='eaa32e2f'/> + <parameter type-id='b59d7dce'/> + <parameter type-id='95e97e5e'/> + <return type-id='6ae5a80d'/> + </function-decl> + <function-decl name='pthread_exit' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='eaa32e2f'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='pthread_key_create' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='ce04b822'/> + <parameter type-id='b7f9d8e6'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_key_delete' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2de5383b'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_getspecific' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2de5383b'/> + <return type-id='eaa32e2f'/> + </function-decl> + <function-decl name='pthread_setspecific' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='2de5383b'/> + <parameter type-id='eaa32e2f'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='_system_taskq' mangled-name='_system_taskq' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_system_taskq'> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='_system_delay_taskq' mangled-name='_system_delay_taskq' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_system_delay_taskq'> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_dispatch' mangled-name='taskq_dispatch' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_dispatch'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='41cce5ce' name='func'/> + <parameter type-id='eaa32e2f' name='arg'/> + <parameter type-id='3502e3ff' name='tqflags'/> + <return type-id='de0ea20e'/> + </function-decl> + <function-decl name='taskq_dispatch_delay' mangled-name='taskq_dispatch_delay' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_dispatch_delay'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='41cce5ce' name='func'/> + <parameter type-id='eaa32e2f' name='arg'/> + <parameter type-id='3502e3ff' name='tqflags'/> + <parameter type-id='4c3a2c61' name='expire_time'/> + <return type-id='de0ea20e'/> + </function-decl> + <function-decl name='taskq_empty_ent' mangled-name='taskq_empty_ent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_empty_ent'> + <parameter type-id='3a4f23d4' name='t'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='taskq_init_ent' mangled-name='taskq_init_ent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_init_ent'> + <parameter type-id='3a4f23d4' name='t'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_dispatch_ent' mangled-name='taskq_dispatch_ent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_dispatch_ent'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='41cce5ce' name='func'/> + <parameter type-id='eaa32e2f' name='arg'/> + <parameter type-id='3502e3ff' name='flags'/> + <parameter type-id='3a4f23d4' name='t'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_wait' mangled-name='taskq_wait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_wait'> + <parameter type-id='4f8ed29a' name='tq'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_wait_id' mangled-name='taskq_wait_id' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_wait_id'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='de0ea20e' name='id'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_create' mangled-name='taskq_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_create'> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='95e97e5e' name='nthreads'/> + <parameter type-id='c497180a' name='pri'/> + <parameter type-id='95e97e5e' name='minalloc'/> + <parameter type-id='95e97e5e' name='maxalloc'/> + <parameter type-id='3502e3ff' name='flags'/> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_destroy' mangled-name='taskq_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_destroy'> + <parameter type-id='4f8ed29a' name='tq'/> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='taskq_create_synced' mangled-name='taskq_create_synced' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_create_synced'> + <parameter type-id='80f4b756' name='name'/> + <parameter type-id='95e97e5e' name='nthreads'/> + <parameter type-id='c497180a' name='pri'/> + <parameter type-id='95e97e5e' name='minalloc'/> + <parameter type-id='95e97e5e' name='maxalloc'/> + <parameter type-id='3502e3ff' name='flags'/> + <parameter type-id='4ea26b5d' name='ktpp'/> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_member' mangled-name='taskq_member' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_member'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='6ae5a80d' name='t'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='taskq_of_curthread' mangled-name='taskq_of_curthread' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_of_curthread'> + <return type-id='4f8ed29a'/> + </function-decl> + <function-decl name='taskq_cancel_id' mangled-name='taskq_cancel_id' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='taskq_cancel_id'> + <parameter type-id='4f8ed29a' name='tq'/> + <parameter type-id='de0ea20e' name='id'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='system_taskq_init' mangled-name='system_taskq_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='system_taskq_init'> + <return type-id='48b5725f'/> + </function-decl> + <function-decl name='system_taskq_fini' mangled-name='system_taskq_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='system_taskq_fini'> + <return type-id='48b5725f'/> + </function-decl> + <function-type size-in-bits='64' id='c5c76c9c'> + <parameter type-id='eaa32e2f'/> + <return type-id='48b5725f'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='lib/libspl/thread.c' language='LANG_C99'> + <pointer-type-def type-id='7d8569fd' size-in-bits='64' id='7347a39e'/> + <function-decl name='pthread_attr_init' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='7347a39e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_attr_destroy' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='7347a39e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_attr_setdetachstate' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='7347a39e'/> + <parameter type-id='95e97e5e'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_attr_setguardsize' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='7347a39e'/> + <parameter type-id='b59d7dce'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_attr_setstacksize' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='7347a39e'/> + <parameter type-id='b59d7dce'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='pthread_setname_np' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='4051f5e7'/> + <parameter type-id='80f4b756'/> + <return type-id='95e97e5e'/> + </function-decl> + <function-decl name='strtol' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='9d26089a'/> + <parameter type-id='8c85230f'/> + <parameter type-id='95e97e5e'/> + <return type-id='bd54fe1a'/> + </function-decl> + <function-decl name='__sysconf' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='95e97e5e'/> + <return type-id='bd54fe1a'/> + </function-decl> + <function-decl name='p0' mangled-name='p0' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='p0'> + <return type-id='48b5725f'/> + </function-decl> + </abi-instr> <abi-instr address-size='64' path='lib/libspl/timestamp.c' language='LANG_C99'> <typedef-decl name='nl_item' type-id='95e97e5e' id='03b79a94'/> <class-decl name='tm' size-in-bits='448' is-struct='yes' visibility='default' id='dddf6ca2'> @@ -1256,52 +2271,10 @@ </function-decl> </abi-instr> <abi-instr address-size='64' path='lib/libspl/tunables.c' language='LANG_C99'> - <enum-decl name='zfs_tunable_type_t' naming-typedef-id='f50b1525' id='56905369'> - <underlying-type type-id='9cac1fee'/> - <enumerator name='ZFS_TUNABLE_TYPE_INT' value='0'/> - <enumerator name='ZFS_TUNABLE_TYPE_UINT' value='1'/> - <enumerator name='ZFS_TUNABLE_TYPE_ULONG' value='2'/> - <enumerator name='ZFS_TUNABLE_TYPE_U64' value='3'/> - <enumerator name='ZFS_TUNABLE_TYPE_STRING' value='4'/> - </enum-decl> - <typedef-decl name='zfs_tunable_type_t' type-id='56905369' id='f50b1525'/> - <enum-decl name='zfs_tunable_perm_t' naming-typedef-id='ada7336b' id='e80e6ebf'> - <underlying-type type-id='9cac1fee'/> - <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RW' value='0'/> - <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RD' value='1'/> - </enum-decl> - <typedef-decl name='zfs_tunable_perm_t' type-id='e80e6ebf' id='ada7336b'/> - <class-decl name='zfs_tunable' size-in-bits='320' is-struct='yes' visibility='default' id='1a97ee0e'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='zt_name' type-id='80f4b756' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='zt_varp' type-id='eaa32e2f' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='zt_varsz' type-id='b59d7dce' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='zt_type' type-id='f50b1525' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='zt_perm' type-id='ada7336b' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='zt_desc' type-id='80f4b756' visibility='default'/> - </data-member> - </class-decl> - <typedef-decl name='zfs_tunable_t' type-id='1a97ee0e' id='12bf5c5e'/> - <typedef-decl name='zfs_tunable_iter_t' type-id='7ef33f92' id='d8d5f4ab'/> <typedef-decl name='intmax_t' type-id='5b475db0' id='e104d842'/> <typedef-decl name='uintmax_t' type-id='04d82f4b' id='f8b828c9'/> <typedef-decl name='__intmax_t' type-id='bd54fe1a' id='5b475db0'/> <typedef-decl name='__uintmax_t' type-id='7359adad' id='04d82f4b'/> - <pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/> - <qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/> - <qualified-type-def type-id='12bf5c5e' const='yes' id='180e47ee'/> - <pointer-type-def type-id='180e47ee' size-in-bits='64' id='a27af98c'/> - <pointer-type-def type-id='92f86508' size-in-bits='64' id='7ef33f92'/> <function-decl name='strtoimax' visibility='default' binding='global' size-in-bits='64'> <parameter type-id='9d26089a'/> <parameter type-id='8c85230f'/> @@ -1319,31 +2292,6 @@ <parameter type-id='80f4b756'/> <return type-id='95e97e5e'/> </function-decl> - <function-decl name='zfs_tunable_lookup' mangled-name='zfs_tunable_lookup' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_lookup'> - <parameter type-id='80f4b756' name='name'/> - <return type-id='a27af98c'/> - </function-decl> - <function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'> - <parameter type-id='d8d5f4ab' name='cb'/> - <parameter type-id='eaa32e2f' name='arg'/> - <return type-id='48b5725f'/> - </function-decl> - <function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'> - <parameter type-id='a27af98c' name='zt'/> - <parameter type-id='80f4b756' name='val'/> - <return type-id='95e97e5e'/> - </function-decl> - <function-decl name='zfs_tunable_get' mangled-name='zfs_tunable_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_get'> - <parameter type-id='a27af98c' name='zt'/> - <parameter type-id='26a90f95' name='val'/> - <parameter type-id='b59d7dce' name='valsz'/> - <return type-id='95e97e5e'/> - </function-decl> - <function-type size-in-bits='64' id='92f86508'> - <parameter type-id='a27af98c'/> - <parameter type-id='eaa32e2f'/> - <return type-id='95e97e5e'/> - </function-type> </abi-instr> <abi-instr address-size='64' path='lib/libzfs_core/libzfs_core.c' language='LANG_C99'> <array-type-def dimensions='1' type-id='03085adc' size-in-bits='192' id='083f8d58'> @@ -1709,6 +2657,7 @@ <underlying-type type-id='9cac1fee'/> <enumerator name='ZPOOL_PREFETCH_NONE' value='0'/> <enumerator name='ZPOOL_PREFETCH_DDT' value='1'/> + <enumerator name='ZPOOL_PREFETCH_BRT' value='2'/> </enum-decl> <typedef-decl name='zpool_prefetch_type_t' type-id='0299ab50' id='e55ff6bc'/> <enum-decl name='zpool_ddt_prune_unit_t' naming-typedef-id='02e25ab0' id='509ae11c'> @@ -2342,10 +3291,10 @@ <var-decl name='zc_inject_record' type-id='a4301ca6' visibility='default'/> </data-member> <data-member access='public'> - <var-decl name='' type-id='e7f43f72' visibility='default'/> + <var-decl name='' type-id='e7f43f73' visibility='default'/> </data-member> </union-decl> - <class-decl name='__anonymous_struct__' size-in-bits='2944' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f72'> + <class-decl name='__anonymous_struct__' size-in-bits='2944' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f73'> <data-member access='public' layout-offset-in-bits='0'> <var-decl name='zc_pad1' type-id='514368c7' visibility='default'/> </data-member> diff --git a/sys/contrib/openzfs/lib/libzfsbootenv/libzfsbootenv.abi b/sys/contrib/openzfs/lib/libzfsbootenv/libzfsbootenv.abi index bf866b0fa61b..e2b492a0780d 100644 --- a/sys/contrib/openzfs/lib/libzfsbootenv/libzfsbootenv.abi +++ b/sys/contrib/openzfs/lib/libzfsbootenv/libzfsbootenv.abi @@ -1,6 +1,6 @@ <abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfsbootenv.so.1'> <elf-needed> - <dependency name='libzfs.so.6'/> + <dependency name='libzfs.so.7'/> <dependency name='libnvpair.so.3'/> <dependency name='libc.so.6'/> </elf-needed> diff --git a/sys/contrib/openzfs/lib/libzpool/Makefile.am b/sys/contrib/openzfs/lib/libzpool/Makefile.am index aeacc595b363..8340fe2efd71 100644 --- a/sys/contrib/openzfs/lib/libzpool/Makefile.am +++ b/sys/contrib/openzfs/lib/libzpool/Makefile.am @@ -1,8 +1,9 @@ +include $(srcdir)/%D%/include/Makefile.am + libzpool_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) $(LIBRARY_CFLAGS) libzpool_la_CFLAGS += $(ZLIB_CFLAGS) libzpool_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS) -libzpool_la_CPPFLAGS += -I$(srcdir)/include/os/@ac_system_l@/zfs libzpool_la_CPPFLAGS += -DLIB_ZPOOL_BUILD lib_LTLIBRARIES += libzpool.la @@ -12,7 +13,6 @@ dist_libzpool_la_SOURCES = \ %D%/abd_os.c \ %D%/arc_os.c \ %D%/kernel.c \ - %D%/taskq.c \ %D%/util.c \ %D%/vdev_label_os.c \ %D%/zfs_racct.c \ @@ -180,6 +180,7 @@ nodist_libzpool_la_SOURCES = \ module/zfs/zfs_crrd.c \ module/zfs/zfs_fm.c \ module/zfs/zfs_fuid.c \ + module/zfs/zfs_impl.c \ module/zfs/zfs_ratelimit.c \ module/zfs/zfs_rlock.c \ module/zfs/zfs_sa.c \ @@ -212,7 +213,7 @@ if BUILD_FREEBSD libzpool_la_LIBADD += -lgeom endif -libzpool_la_LDFLAGS += -version-info 6:0:0 +libzpool_la_LDFLAGS += -version-info 7:0:0 if TARGET_CPU_POWERPC module/zfs/libzpool_la-vdev_raidz_math_powerpc_altivec.$(OBJEXT) : CFLAGS += -maltivec diff --git a/sys/contrib/openzfs/lib/libzpool/include/Makefile.am b/sys/contrib/openzfs/lib/libzpool/include/Makefile.am new file mode 100644 index 000000000000..6cfa2d5ce089 --- /dev/null +++ b/sys/contrib/openzfs/lib/libzpool/include/Makefile.am @@ -0,0 +1,8 @@ +libzpool_sysdir = $(includedir)/libzpool/sys +libzpool_sys_HEADERS = \ + %D%/sys/abd_os.h \ + %D%/sys/abd_impl_os.h \ + %D%/sys/trace_zfs.h \ + %D%/sys/zfs_bootenv_os.h \ + %D%/sys/zfs_context_os.h \ + %D%/sys/zfs_debug_os.h diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/abd_impl_os.h b/sys/contrib/openzfs/lib/libzpool/include/sys/abd_impl_os.h index dee95652c71c..dee95652c71c 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/abd_impl_os.h +++ b/sys/contrib/openzfs/lib/libzpool/include/sys/abd_impl_os.h diff --git a/sys/contrib/openzfs/lib/libspl/include/sys/abd_os.h b/sys/contrib/openzfs/lib/libzpool/include/sys/abd_os.h index 80ce46e99a8e..80ce46e99a8e 100644 --- a/sys/contrib/openzfs/lib/libspl/include/sys/abd_os.h +++ b/sys/contrib/openzfs/lib/libzpool/include/sys/abd_os.h diff --git a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/sysmacros.h b/sys/contrib/openzfs/lib/libzpool/include/sys/trace_zfs.h index d9639d27b60e..d9639d27b60e 100644 --- a/sys/contrib/openzfs/lib/libspl/include/os/freebsd/sys/sysmacros.h +++ b/sys/contrib/openzfs/lib/libzpool/include/sys/trace_zfs.h diff --git a/sys/contrib/openzfs/lib/libzpool/include/sys/zfs_bootenv_os.h b/sys/contrib/openzfs/lib/libzpool/include/sys/zfs_bootenv_os.h new file mode 100644 index 000000000000..44afbb6f5b6b --- /dev/null +++ b/sys/contrib/openzfs/lib/libzpool/include/sys/zfs_bootenv_os.h @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2025, Rob Norris <robn@despairlabs.com> + */ + +#ifndef _ZFS_BOOTENV_OS_H +#define _ZFS_BOOTENV_OS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define BOOTENV_OS BE_POSIX_VENDOR + +#ifdef __cplusplus +} +#endif + +#endif /* _ZFS_BOOTENV_OS_H */ diff --git a/sys/contrib/openzfs/lib/libzpool/include/sys/zfs_context_os.h b/sys/contrib/openzfs/lib/libzpool/include/sys/zfs_context_os.h new file mode 100644 index 000000000000..4dcf386e3351 --- /dev/null +++ b/sys/contrib/openzfs/lib/libzpool/include/sys/zfs_context_os.h @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#ifndef ZFS_CONTEXT_OS_H_ +#define ZFS_CONTEXT_OS_H_ + +#define HAVE_LARGE_STACKS 1 + +#endif diff --git a/sys/contrib/openzfs/lib/libzpool/include/sys/zfs_debug_os.h b/sys/contrib/openzfs/lib/libzpool/include/sys/zfs_debug_os.h new file mode 100644 index 000000000000..b59165a6c903 --- /dev/null +++ b/sys/contrib/openzfs/lib/libzpool/include/sys/zfs_debug_os.h @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +#ifndef _SYS_ZFS_DEBUG_OS_H +#define _SYS_ZFS_DEBUG_OS_H + +#define SET_ERROR(err) \ + (__set_error(__FILE__, __func__, __LINE__, err), err) + +#endif diff --git a/sys/contrib/openzfs/lib/libzpool/kernel.c b/sys/contrib/openzfs/lib/libzpool/kernel.c index 70eba5099119..7e3ffec3b81d 100644 --- a/sys/contrib/openzfs/lib/libzpool/kernel.c +++ b/sys/contrib/openzfs/lib/libzpool/kernel.c @@ -40,10 +40,14 @@ #include <sys/rrwlock.h> #include <sys/spa.h> #include <sys/spa_impl.h> +#include <sys/sid.h> #include <sys/stat.h> #include <sys/systeminfo.h> #include <sys/time.h> -#include <sys/utsname.h> +#include <sys/tsd.h> + +#include <libspl.h> +#include <libzpool.h> #include <sys/zfs_context.h> #include <sys/zfs_onexit.h> #include <sys/zfs_vfsops.h> @@ -56,258 +60,11 @@ * Emulation of kernel services in userland. */ -uint64_t physmem; uint32_t hostid; -struct utsname hw_utsname; /* If set, all blocks read will be copied to the specified directory. */ char *vn_dumpdir = NULL; -/* this only exists to have its address taken */ -struct proc p0; - -/* - * ========================================================================= - * threads - * ========================================================================= - * - * TS_STACK_MIN is dictated by the minimum allowed pthread stack size. While - * TS_STACK_MAX is somewhat arbitrary, it was selected to be large enough for - * the expected stack depth while small enough to avoid exhausting address - * space with high thread counts. - */ -#define TS_STACK_MIN MAX(PTHREAD_STACK_MIN, 32768) -#define TS_STACK_MAX (256 * 1024) - -struct zk_thread_wrapper { - void (*func)(void *); - void *arg; -}; - -static void * -zk_thread_wrapper(void *arg) -{ - struct zk_thread_wrapper ztw; - memcpy(&ztw, arg, sizeof (ztw)); - free(arg); - ztw.func(ztw.arg); - return (NULL); -} - -kthread_t * -zk_thread_create(const char *name, void (*func)(void *), void *arg, - size_t stksize, int state) -{ - pthread_attr_t attr; - pthread_t tid; - char *stkstr; - struct zk_thread_wrapper *ztw; - int detachstate = PTHREAD_CREATE_DETACHED; - - VERIFY0(pthread_attr_init(&attr)); - - if (state & TS_JOINABLE) - detachstate = PTHREAD_CREATE_JOINABLE; - - VERIFY0(pthread_attr_setdetachstate(&attr, detachstate)); - - /* - * We allow the default stack size in user space to be specified by - * setting the ZFS_STACK_SIZE environment variable. This allows us - * the convenience of observing and debugging stack overruns in - * user space. Explicitly specified stack sizes will be honored. - * The usage of ZFS_STACK_SIZE is discussed further in the - * ENVIRONMENT VARIABLES sections of the ztest(1) man page. - */ - if (stksize == 0) { - stkstr = getenv("ZFS_STACK_SIZE"); - - if (stkstr == NULL) - stksize = TS_STACK_MAX; - else - stksize = MAX(atoi(stkstr), TS_STACK_MIN); - } - - VERIFY3S(stksize, >, 0); - stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE); - - /* - * If this ever fails, it may be because the stack size is not a - * multiple of system page size. - */ - VERIFY0(pthread_attr_setstacksize(&attr, stksize)); - VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE)); - - VERIFY(ztw = malloc(sizeof (*ztw))); - ztw->func = func; - ztw->arg = arg; - VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw)); - VERIFY0(pthread_attr_destroy(&attr)); - - pthread_setname_np(tid, name); - - return ((void *)(uintptr_t)tid); -} - -/* - * ========================================================================= - * kstats - * ========================================================================= - */ -kstat_t * -kstat_create(const char *module, int instance, const char *name, - const char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag) -{ - (void) module, (void) instance, (void) name, (void) class, (void) type, - (void) ndata, (void) ks_flag; - return (NULL); -} - -void -kstat_install(kstat_t *ksp) -{ - (void) ksp; -} - -void -kstat_delete(kstat_t *ksp) -{ - (void) ksp; -} - -void -kstat_set_raw_ops(kstat_t *ksp, - int (*headers)(char *buf, size_t size), - int (*data)(char *buf, size_t size, void *data), - void *(*addr)(kstat_t *ksp, loff_t index)) -{ - (void) ksp, (void) headers, (void) data, (void) addr; -} - -/* - * ========================================================================= - * mutexes - * ========================================================================= - */ - -void -mutex_init(kmutex_t *mp, char *name, int type, void *cookie) -{ - (void) name, (void) type, (void) cookie; - VERIFY0(pthread_mutex_init(&mp->m_lock, NULL)); - memset(&mp->m_owner, 0, sizeof (pthread_t)); -} - -void -mutex_destroy(kmutex_t *mp) -{ - VERIFY0(pthread_mutex_destroy(&mp->m_lock)); -} - -void -mutex_enter(kmutex_t *mp) -{ - VERIFY0(pthread_mutex_lock(&mp->m_lock)); - mp->m_owner = pthread_self(); -} - -int -mutex_enter_check_return(kmutex_t *mp) -{ - int error = pthread_mutex_lock(&mp->m_lock); - if (error == 0) - mp->m_owner = pthread_self(); - return (error); -} - -int -mutex_tryenter(kmutex_t *mp) -{ - int error = pthread_mutex_trylock(&mp->m_lock); - if (error == 0) { - mp->m_owner = pthread_self(); - return (1); - } else { - VERIFY3S(error, ==, EBUSY); - return (0); - } -} - -void -mutex_exit(kmutex_t *mp) -{ - memset(&mp->m_owner, 0, sizeof (pthread_t)); - VERIFY0(pthread_mutex_unlock(&mp->m_lock)); -} - -/* - * ========================================================================= - * rwlocks - * ========================================================================= - */ - -void -rw_init(krwlock_t *rwlp, char *name, int type, void *arg) -{ - (void) name, (void) type, (void) arg; - VERIFY0(pthread_rwlock_init(&rwlp->rw_lock, NULL)); - rwlp->rw_readers = 0; - rwlp->rw_owner = 0; -} - -void -rw_destroy(krwlock_t *rwlp) -{ - VERIFY0(pthread_rwlock_destroy(&rwlp->rw_lock)); -} - -void -rw_enter(krwlock_t *rwlp, krw_t rw) -{ - if (rw == RW_READER) { - VERIFY0(pthread_rwlock_rdlock(&rwlp->rw_lock)); - atomic_inc_uint(&rwlp->rw_readers); - } else { - VERIFY0(pthread_rwlock_wrlock(&rwlp->rw_lock)); - rwlp->rw_owner = pthread_self(); - } -} - -void -rw_exit(krwlock_t *rwlp) -{ - if (RW_READ_HELD(rwlp)) - atomic_dec_uint(&rwlp->rw_readers); - else - rwlp->rw_owner = 0; - - VERIFY0(pthread_rwlock_unlock(&rwlp->rw_lock)); -} - -int -rw_tryenter(krwlock_t *rwlp, krw_t rw) -{ - int error; - - if (rw == RW_READER) - error = pthread_rwlock_tryrdlock(&rwlp->rw_lock); - else - error = pthread_rwlock_trywrlock(&rwlp->rw_lock); - - if (error == 0) { - if (rw == RW_READER) - atomic_inc_uint(&rwlp->rw_readers); - else - rwlp->rw_owner = pthread_self(); - - return (1); - } - - VERIFY3S(error, ==, EBUSY); - - return (0); -} - uint32_t zone_get_hostid(void *zonep) { @@ -318,191 +75,6 @@ zone_get_hostid(void *zonep) return (hostid); } -int -rw_tryupgrade(krwlock_t *rwlp) -{ - (void) rwlp; - return (0); -} - -/* - * ========================================================================= - * condition variables - * ========================================================================= - */ - -void -cv_init(kcondvar_t *cv, char *name, int type, void *arg) -{ - (void) name, (void) type, (void) arg; - VERIFY0(pthread_cond_init(cv, NULL)); -} - -void -cv_destroy(kcondvar_t *cv) -{ - VERIFY0(pthread_cond_destroy(cv)); -} - -void -cv_wait(kcondvar_t *cv, kmutex_t *mp) -{ - memset(&mp->m_owner, 0, sizeof (pthread_t)); - VERIFY0(pthread_cond_wait(cv, &mp->m_lock)); - mp->m_owner = pthread_self(); -} - -int -cv_wait_sig(kcondvar_t *cv, kmutex_t *mp) -{ - cv_wait(cv, mp); - return (1); -} - -int -cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime) -{ - int error; - struct timeval tv; - struct timespec ts; - clock_t delta; - - delta = abstime - ddi_get_lbolt(); - if (delta <= 0) - return (-1); - - VERIFY0(gettimeofday(&tv, NULL)); - - ts.tv_sec = tv.tv_sec + delta / hz; - ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % hz) * (NANOSEC / hz); - if (ts.tv_nsec >= NANOSEC) { - ts.tv_sec++; - ts.tv_nsec -= NANOSEC; - } - - memset(&mp->m_owner, 0, sizeof (pthread_t)); - error = pthread_cond_timedwait(cv, &mp->m_lock, &ts); - mp->m_owner = pthread_self(); - - if (error == ETIMEDOUT) - return (-1); - - VERIFY0(error); - - return (1); -} - -int -cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res, - int flag) -{ - (void) res; - int error; - struct timeval tv; - struct timespec ts; - hrtime_t delta; - - ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE); - - delta = tim; - if (flag & CALLOUT_FLAG_ABSOLUTE) - delta -= gethrtime(); - - if (delta <= 0) - return (-1); - - VERIFY0(gettimeofday(&tv, NULL)); - - ts.tv_sec = tv.tv_sec + delta / NANOSEC; - ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % NANOSEC); - if (ts.tv_nsec >= NANOSEC) { - ts.tv_sec++; - ts.tv_nsec -= NANOSEC; - } - - memset(&mp->m_owner, 0, sizeof (pthread_t)); - error = pthread_cond_timedwait(cv, &mp->m_lock, &ts); - mp->m_owner = pthread_self(); - - if (error == ETIMEDOUT) - return (-1); - - VERIFY0(error); - - return (1); -} - -void -cv_signal(kcondvar_t *cv) -{ - VERIFY0(pthread_cond_signal(cv)); -} - -void -cv_broadcast(kcondvar_t *cv) -{ - VERIFY0(pthread_cond_broadcast(cv)); -} - -/* - * ========================================================================= - * procfs list - * ========================================================================= - */ - -void -seq_printf(struct seq_file *m, const char *fmt, ...) -{ - (void) m, (void) fmt; -} - -void -procfs_list_install(const char *module, - const char *submodule, - const char *name, - mode_t mode, - procfs_list_t *procfs_list, - int (*show)(struct seq_file *f, void *p), - int (*show_header)(struct seq_file *f), - int (*clear)(procfs_list_t *procfs_list), - size_t procfs_list_node_off) -{ - (void) module, (void) submodule, (void) name, (void) mode, (void) show, - (void) show_header, (void) clear; - mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL); - list_create(&procfs_list->pl_list, - procfs_list_node_off + sizeof (procfs_list_node_t), - procfs_list_node_off + offsetof(procfs_list_node_t, pln_link)); - procfs_list->pl_next_id = 1; - procfs_list->pl_node_offset = procfs_list_node_off; -} - -void -procfs_list_uninstall(procfs_list_t *procfs_list) -{ - (void) procfs_list; -} - -void -procfs_list_destroy(procfs_list_t *procfs_list) -{ - ASSERT(list_is_empty(&procfs_list->pl_list)); - list_destroy(&procfs_list->pl_list); - mutex_destroy(&procfs_list->pl_lock); -} - -#define NODE_ID(procfs_list, obj) \ - (((procfs_list_node_t *)(((char *)obj) + \ - (procfs_list)->pl_node_offset))->pln_id) - -void -procfs_list_add(procfs_list_t *procfs_list, void *p) -{ - ASSERT(MUTEX_HELD(&procfs_list->pl_lock)); - NODE_ID(procfs_list, p) = procfs_list->pl_next_id++; - list_insert_tail(&procfs_list->pl_list, p); -} - /* * ========================================================================= * vnode operations @@ -771,57 +343,6 @@ lowbit64(uint64_t i) return (__builtin_ffsll(i)); } -const char *random_path = "/dev/random"; -const char *urandom_path = "/dev/urandom"; -static int random_fd = -1, urandom_fd = -1; - -void -random_init(void) -{ - VERIFY((random_fd = open(random_path, O_RDONLY | O_CLOEXEC)) != -1); - VERIFY((urandom_fd = open(urandom_path, O_RDONLY | O_CLOEXEC)) != -1); -} - -void -random_fini(void) -{ - close(random_fd); - close(urandom_fd); - - random_fd = -1; - urandom_fd = -1; -} - -static int -random_get_bytes_common(uint8_t *ptr, size_t len, int fd) -{ - size_t resid = len; - ssize_t bytes; - - ASSERT(fd != -1); - - while (resid != 0) { - bytes = read(fd, ptr, resid); - ASSERT3S(bytes, >=, 0); - ptr += bytes; - resid -= bytes; - } - - return (0); -} - -int -random_get_bytes(uint8_t *ptr, size_t len) -{ - return (random_get_bytes_common(ptr, len, random_fd)); -} - -int -random_get_pseudo_bytes(uint8_t *ptr, size_t len) -{ - return (random_get_bytes_common(ptr, len, urandom_fd)); -} - int ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result) { @@ -832,12 +353,6 @@ ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result) return (0); } -utsname_t * -utsname(void) -{ - return (&hw_utsname); -} - /* * ========================================================================= * kernel emulation setup & teardown @@ -903,7 +418,7 @@ spa_config_load(void) * Iterate over all elements in the nvlist, creating a new spa_t for * each one with the specified configuration. */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); nvpair = NULL; while ((nvpair = nvlist_next_nvpair(nvlist, nvpair)) != NULL) { if (nvpair_type(nvpair) != DATA_TYPE_NVLIST) @@ -915,7 +430,7 @@ spa_config_load(void) continue; (void) spa_add(nvpair_name(nvpair), child, NULL); } - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); nvlist_free(nvlist); @@ -931,19 +446,15 @@ kernel_init(int mode) { extern uint_t rrw_tsd_key; - umem_nofail_callback(umem_out_of_memory); + libspl_init(); - physmem = sysconf(_SC_PHYS_PAGES); + umem_nofail_callback(umem_out_of_memory); dprintf("physmem = %llu pages (%.2f GB)\n", (u_longlong_t)physmem, (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30)); hostid = (mode & SPA_MODE_WRITE) ? get_system_hostid() : 0; - random_init(); - - VERIFY0(uname(&hw_utsname)); - system_taskq_init(); icp_init(); @@ -968,142 +479,7 @@ kernel_fini(void) icp_fini(); system_taskq_fini(); - random_fini(); -} - -uid_t -crgetuid(cred_t *cr) -{ - (void) cr; - return (0); -} - -uid_t -crgetruid(cred_t *cr) -{ - (void) cr; - return (0); -} - -gid_t -crgetgid(cred_t *cr) -{ - (void) cr; - return (0); -} - -int -crgetngroups(cred_t *cr) -{ - (void) cr; - return (0); -} - -gid_t * -crgetgroups(cred_t *cr) -{ - (void) cr; - return (NULL); -} - -int -zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr) -{ - (void) name, (void) cr; - return (0); -} - -int -zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr) -{ - (void) from, (void) to, (void) cr; - return (0); -} - -int -zfs_secpolicy_destroy_perms(const char *name, cred_t *cr) -{ - (void) name, (void) cr; - return (0); -} - -int -secpolicy_zfs(const cred_t *cr) -{ - (void) cr; - return (0); -} - -ksiddomain_t * -ksid_lookupdomain(const char *dom) -{ - ksiddomain_t *kd; - - kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL); - kd->kd_name = spa_strdup(dom); - return (kd); -} - -void -ksiddomain_rele(ksiddomain_t *ksid) -{ - spa_strfree(ksid->kd_name); - umem_free(ksid, sizeof (ksiddomain_t)); -} - -char * -kmem_vasprintf(const char *fmt, va_list adx) -{ - char *buf = NULL; - va_list adx_copy; - - va_copy(adx_copy, adx); - VERIFY(vasprintf(&buf, fmt, adx_copy) != -1); - va_end(adx_copy); - - return (buf); -} - -char * -kmem_asprintf(const char *fmt, ...) -{ - char *buf = NULL; - va_list adx; - - va_start(adx, fmt); - VERIFY(vasprintf(&buf, fmt, adx) != -1); - va_end(adx); - - return (buf); -} - -/* - * kmem_scnprintf() will return the number of characters that it would have - * printed whenever it is limited by value of the size variable, rather than - * the number of characters that it did print. This can cause misbehavior on - * subsequent uses of the return value, so we define a safe version that will - * return the number of characters actually printed, minus the NULL format - * character. Subsequent use of this by the safe string functions is safe - * whether it is snprintf(), strlcat() or strlcpy(). - */ -int -kmem_scnprintf(char *restrict str, size_t size, const char *restrict fmt, ...) -{ - int n; - va_list ap; - - /* Make the 0 case a no-op so that we do not return -1 */ - if (size == 0) - return (0); - - va_start(ap, fmt); - n = vsnprintf(str, size, fmt, ap); - va_end(ap); - - if (n >= size) - n = size - 1; - - return (n); + libspl_fini(); } zfs_file_t * @@ -1128,24 +504,6 @@ zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data, return (0); } -fstrans_cookie_t -spl_fstrans_mark(void) -{ - return ((fstrans_cookie_t)0); -} - -void -spl_fstrans_unmark(fstrans_cookie_t cookie) -{ - (void) cookie; -} - -int -kmem_cache_reap_active(void) -{ - return (0); -} - void zvol_create_minors(const char *name) { diff --git a/sys/contrib/openzfs/lib/libzpool/util.c b/sys/contrib/openzfs/lib/libzpool/util.c index 66d6f43967d5..a0b4480c4bcf 100644 --- a/sys/contrib/openzfs/lib/libzpool/util.c +++ b/sys/contrib/openzfs/lib/libzpool/util.c @@ -38,6 +38,7 @@ #include <sys/zfs_ioctl.h> #include <sys/tunables.h> #include <libzutil.h> +#include <libzpool.h> /* * Routines needed by more than one client of libzpool. diff --git a/sys/contrib/openzfs/man/man4/zfs.4 b/sys/contrib/openzfs/man/man4/zfs.4 index 11bcbf430210..60ec56b4d1f6 100644 --- a/sys/contrib/openzfs/man/man4/zfs.4 +++ b/sys/contrib/openzfs/man/man4/zfs.4 @@ -273,12 +273,12 @@ force this many of them to be gang blocks. .It Sy brt_zap_prefetch Ns = Ns Sy 1 Ns | Ns 0 Pq int Controls prefetching BRT records for blocks which are going to be cloned. . -.It Sy brt_zap_default_bs Ns = Ns Sy 12 Po 4 KiB Pc Pq int +.It Sy brt_zap_default_bs Ns = Ns Sy 13 Po 8 KiB Pc Pq int Default BRT ZAP data block size as a power of 2. Note that changing this after creating a BRT on the pool will not affect existing BRTs, only newly created ones. . -.It Sy brt_zap_default_ibs Ns = Ns Sy 12 Po 4 KiB Pc Pq int +.It Sy brt_zap_default_ibs Ns = Ns Sy 13 Po 8 KiB Pc Pq int Default BRT ZAP indirect block size as a power of 2. Note that changing this after creating a BRT on the pool will not affect existing BRTs, only newly created ones. @@ -2660,12 +2660,50 @@ Set value only applies to pools imported/created after that. Set the queue and thread configuration for the IO read queues. This is an advanced debugging parameter. Don't change this unless you understand what it does. +Each of the four values corresponds to the issue, issue high-priority, +interrupt, and interrupt high-priority queues. +Valid values are +.Sy fixed,N,M +(M queues with N threads each), +.Sy scale[,MIN] +(scale with CPUs, minimum MIN total threads), +.Sy sync , +and +.Sy null . Set values only apply to pools imported/created after that. . .It Sy zio_taskq_write Ns = Ns Sy sync null scale null Pq charp Set the queue and thread configuration for the IO write queues. This is an advanced debugging parameter. Don't change this unless you understand what it does. +Each of the four values corresponds to the issue, issue high-priority, +interrupt, and interrupt high-priority queues. +Valid values are +.Sy fixed,N,M +(M queues with N threads each), +.Sy scale[,MIN] +(scale with CPUs, minimum MIN total threads), +.Sy sync , +and +.Sy null . +Set values only apply to pools imported/created after that. +. +.It Sy zio_taskq_free Ns = Ns Sy scale,32 null null null Pq charp +Set the queue and thread configuration for the IO free queues. +This is an advanced debugging parameter. +Don't change this unless you understand what it does. +Each of the four values corresponds to the issue, issue high-priority, +interrupt, and interrupt high-priority queues. +Valid values are +.Sy fixed,N,M +(M queues with N threads each), +.Sy scale[,MIN] +(scale with CPUs, minimum MIN total threads), +.Sy sync , +and +.Sy null . +The default uses a minimum of 32 threads to improve parallelism for +DDT and BRT metadata operations during frees. Set values only apply to pools imported/created after that. . .It Sy zvol_inhibit_dev Ns = Ns Sy 0 Ns | Ns 1 Pq uint diff --git a/sys/contrib/openzfs/man/man7/vdevprops.7 b/sys/contrib/openzfs/man/man7/vdevprops.7 index 0fb28d7db13c..b54abcd3ecc9 100644 --- a/sys/contrib/openzfs/man/man7/vdevprops.7 +++ b/sys/contrib/openzfs/man/man7/vdevprops.7 @@ -45,7 +45,7 @@ section, below. Every vdev has a set of properties that export statistics about the vdev as well as control various behaviors. Properties are not inherited from top-level vdevs, with the exception of -checksum_n, checksum_t, io_n, io_t, slow_io_n, and slow_io_t. +checksum_n, checksum_t, io_n, io_t, slow_io_events, slow_io_n, and slow_io_t. .Pp The values of numeric properties can be specified using human-readable suffixes .Po for example, @@ -149,6 +149,12 @@ For .Sy OpenZFS on FreeBSD defaults see .Xr zfsd 8 . +The +.It Sy slow_io_events +property controls whether slow I/O events are generated. +Even when disabled, slow I/Os will be included in the +.Nm zpool Cm status Fl s +output. .It Sy comment A text comment up to 8192 characters long .It Sy bootsize diff --git a/sys/contrib/openzfs/man/man7/zpoolconcepts.7 b/sys/contrib/openzfs/man/man7/zpoolconcepts.7 index b9c8926d835d..21bd72351209 100644 --- a/sys/contrib/openzfs/man/man7/zpoolconcepts.7 +++ b/sys/contrib/openzfs/man/man7/zpoolconcepts.7 @@ -469,6 +469,11 @@ then rewind it during import: .Dl # Nm zpool Cm export Ar pool .Dl # Nm zpool Cm import Fl -rewind-to-checkpoint Ar pool .Pp +Note that rewinding to a checkpoint will +.Sy permanently discard it. +Once the pool has been successfully imported with the above rewind command, +you cannot rewind to the same checkpoint. +.Pp To discard the checkpoint from a pool: .Dl # Nm zpool Cm checkpoint Fl d Ar pool .Pp diff --git a/sys/contrib/openzfs/man/man8/zfs-jail.8 b/sys/contrib/openzfs/man/man8/zfs-jail.8 index 569f5f57eab4..8f94a1bd4d81 100644 --- a/sys/contrib/openzfs/man/man8/zfs-jail.8 +++ b/sys/contrib/openzfs/man/man8/zfs-jail.8 @@ -37,7 +37,7 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" -.Dd July 11, 2022 +.Dd November 4, 2025 .Dt ZFS-JAIL 8 .Os . @@ -53,9 +53,42 @@ .Ar filesystem . .Sh DESCRIPTION -.Bl -tag -width "" +The +.Nm +functionality can be used to assign a dataset onto a running +.Fx +system +.Xr jail 4 , +allowing +.Xr zfs 8 +management utilities to be run inside of the +.Xr jail 4 . +.Pp +To allow management of the dataset from within a jail, the +.Sy jailed +property should be set and the required +.Xr devfs.conf 5 +entries to expose +.Pa /dev/zfs +device within the jail must be present. +The +.Sy quota +property cannot be changed from within a jail. +.Pp +To use this functionality, the jail needs the +.Sy allow.mount +and +.Sy allow.mount.zfs +parameters set to +.Sy 1 +and the +.Sy enforce_statfs +parameter set to a value lower than +.Sy 2 . +.Pp +The subcommands are as follows: +.Bl -tag -width indent .It Xo -.Nm zfs .Cm jail .Ar jailid Ns | Ns Ar jailname .Ar filesystem @@ -69,16 +102,6 @@ or name From now on this file system tree can be managed from within a jail if the .Sy jailed property has been set. -To use this functionality, the jail needs the -.Sy allow.mount -and -.Sy allow.mount.zfs -parameters set to -.Sy 1 -and the -.Sy enforce_statfs -parameter set to a value lower than -.Sy 2 . .Pp You cannot attach a jailed dataset's children to another jail. You can also not attach the root file system @@ -86,29 +109,12 @@ of the jail or any dataset which needs to be mounted before the zfs rc script is run inside the jail, as it would be attached unmounted until it is mounted from the rc script inside the jail. .Pp -To allow management of the dataset from within a jail, the -.Sy jailed -property has to be set and the jail needs access to the -.Pa /dev/zfs -device. -The -.Sy quota -property cannot be changed from within a jail. -.Pp After a dataset is attached to a jail and the .Sy jailed property is set, a jailed file system cannot be mounted outside the jail, since the jail administrator might have set the mount point to an unacceptable value. -.Pp -See -.Xr jail 8 -for more information on managing jails. -Jails are a -.Fx -feature and are not relevant on other platforms. .It Xo -.Nm zfs .Cm unjail .Ar jailid Ns | Ns Ar jailname .Ar filesystem @@ -121,5 +127,18 @@ or name .Ar jailname . .El .Sh SEE ALSO +.Xr devfs.conf 5 , .Xr zfsprops 7 , .Xr jail 8 +.Sh CAVEATS +The root directory of jail can not be delegated to the jail with this +utility because the jail must be running with a valid root directory. +.Pp +Jails are a +.Fx +feature and are not relevant on other platforms. +See +.Xr jail 8 +for more information on managing jails, or +.Xr zfs-zone 8 +for the equivelant functionality on Linux. diff --git a/sys/contrib/openzfs/man/man8/zfs-rewrite.8 b/sys/contrib/openzfs/man/man8/zfs-rewrite.8 index ca5340c7e5eb..ae0a1588293e 100644 --- a/sys/contrib/openzfs/man/man8/zfs-rewrite.8 +++ b/sys/contrib/openzfs/man/man8/zfs-rewrite.8 @@ -20,8 +20,9 @@ .\" CDDL HEADER END .\" .\" Copyright (c) 2025 iXsystems, Inc. +.\" Copyright (c) 2025, Klara, Inc. .\" -.Dd July 23, 2025 +.Dd November 5, 2025 .Dt ZFS-REWRITE 8 .Os . @@ -39,9 +40,10 @@ .Sh DESCRIPTION Rewrite blocks of specified .Ar file -as is without modification at a new location and possibly with new -properties, such as checksum, compression, dedup, copies, etc, +as is without modification at a new location and possibly with new properties, as if they were atomically read and written back. +.No See Sx NOTES . +for more information about property changes that may be applied during rewrite. .Bl -tag -width "-r" .It Fl P Perform physical rewrite, preserving logical birth time of blocks. @@ -64,6 +66,20 @@ Print names of all successfully rewritten files. Don't cross file system mount points when recursing. .El .Sh NOTES +Rewrite works by replacing an existing block with a new block of the same +logical size. +Changed dataset properties that operate on the data or metadata without +changing the logical size will be applied. +These include +.Sy checksum , +.Sy compression , +.Sy dedup +and +.Sy copies . +Changes to properties that affect the size of a logical block, like +.Sy recordsize , +will have no effect. +.Pp Rewrite of cloned blocks and blocks that are part of any snapshots, same as some property changes may increase pool space usage. Holes that were never written or were previously zero-compressed are diff --git a/sys/contrib/openzfs/man/man8/zpool-events.8 b/sys/contrib/openzfs/man/man8/zpool-events.8 index 36a9864dc73b..3753139bdfe7 100644 --- a/sys/contrib/openzfs/man/man8/zpool-events.8 +++ b/sys/contrib/openzfs/man/man8/zpool-events.8 @@ -113,17 +113,19 @@ See for more details on the .Sy zfs_vdev_direct_write_verify module parameter. -.It Sy config +.It Sy config_sync Issued every time a vdev change have been done to the pool. .It Sy zpool Issued when a pool cannot be imported. -.It Sy zpool.destroy +.It Sy pool_create +Issued when a pool is created. +.It Sy pool_destroy Issued when a pool is destroyed. -.It Sy zpool.export +.It Sy pool_export Issued when a pool is exported. -.It Sy zpool.import +.It Sy pool_import Issued when a pool is imported. -.It Sy zpool.reguid +.It Sy pool_reguid Issued when a REGUID (new unique identifier for the pool have been regenerated) have been detected. .It Sy vdev.unknown @@ -150,21 +152,31 @@ event. Issued when the label is OK but invalid. .It Sy vdev.bad_ashift Issued when the ashift alignment requirement has increased. -.It Sy vdev.remove +.It Sy vdev_remove Issued when a vdev is detached from a mirror (or a spare detached from a vdev where it have been used to replace a failed drive - only works if the original drive have been re-added). -.It Sy vdev.clear +.It Sy vdev_remove_aux +Issued when an auxiliary vdev is removed. +.It Sy vdev_remove_dev +Issued when a specific device is removed from a vdev. +.It Sy vdev_clear Issued when clearing device errors in a pool. Such as running .Nm zpool Cm clear on a device in the pool. -.It Sy vdev.check +.It Sy vdev_check Issued when a check to see if a given vdev could be opened is started. -.It Sy vdev.spare +.It Sy vdev_spare Issued when a spare have kicked in to replace a failed device. -.It Sy vdev.autoexpand +.It Sy vdev_autoexpand Issued when a vdev can be automatically expanded. +.It Sy vdev_add +Issued when a vdev is added to a pool. +.It Sy vdev_attach +Issued when a vdev is attached to a mirror or raidz vdev type. +.It Sy vdev_online +Issued when an offline vdev is brought online .It Sy io_failure Issued when there is an I/O failure in a vdev in the pool. .It Sy probe_failure @@ -175,21 +187,46 @@ have removed the device). .It Sy log_replay Issued when the intent log cannot be replayed. The can occur in the case of a missing or damaged log device. -.It Sy resilver.start +.It Sy resilver_start Issued when a resilver is started. -.It Sy resilver.finish +.It Sy resilver_finish Issued when the running resilver have finished. -.It Sy scrub.start +.It Sy scrub_start Issued when a scrub is started on a pool. -.It Sy scrub.finish +.It Sy scrub_finish Issued when a pool has finished scrubbing. -.It Sy scrub.abort +.It Sy scrub_abort Issued when a scrub is aborted on a pool. -.It Sy scrub.resume +.It Sy scrub_resume Issued when a scrub is resumed on a pool. -.It Sy scrub.paused +.It Sy scrub_paused Issued when a scrub is paused on a pool. -.It Sy bootfs.vdev.attach +.It Sy errorscrub_start +Issued when a errorscrub is started on a pool. +.It Sy errorscrub_finish +Issued when a pool has finished errorscrubbing. +.It Sy errorscrub_abort +Issued when a errorscrub is aborted on a pool. +.It Sy errorscrub_resume +Issued when a errorscrub is resumed on a pool. +.It Sy errorscrub_paused +Issued when a errorscrub is paused on a pool. +.It Sy trim_start +Issued when a trim is started on a pool. +.It Sy trim_finish +Issued when a pool has finished trimbing. +.It Sy trim_cancel +Issued when a trim is canceled on a pool. +.It Sy trim_resume +Issued when a trim is resumed on a pool. +.It Sy trim_suspend +Issued when a trim is suspend on a pool. +.It Sy authentication +Issued when there is a decryption / authentication error. +.It Sy config_cache_write +Issued when the config cache file cannot be written. +.It Sy bootfs_vdev_attach +Issued when a vdev is attached to a root pool with the bootfs property set. .It Sy sitout Issued when a .Sy RAIDZ diff --git a/sys/contrib/openzfs/man/man8/zpool-prefetch.8 b/sys/contrib/openzfs/man/man8/zpool-prefetch.8 index a36ad52e681e..6f4c3b129040 100644 --- a/sys/contrib/openzfs/man/man8/zpool-prefetch.8 +++ b/sys/contrib/openzfs/man/man8/zpool-prefetch.8 @@ -28,20 +28,25 @@ . .Sh NAME .Nm zpool-prefetch -.Nd Loads specific types of data for the given pool +.Nd Prefetches pool metadata into ARC .Sh SYNOPSIS .Nm zpool .Cm prefetch -.Fl t Ar type +.Op Fl t Ar type .Ar pool .Sh DESCRIPTION -.Bl -tag -width Ds -.It Xo -.Nm zpool -.Cm prefetch -.Fl t Li ddt -.Ar pool -.Xc -Prefetch data of a specific type for the given pool; specifically the DDT, -which will improve write I/O performance when the DDT is resident in the ARC. +Massively prefetch metadata of a specific type for the given pool into the ARC +to reduce latency of some operations later. +If no type is specified, all types are prefetched. +.Pp +The following types are supported: +.Bl -tag -width "brt" +.It Sy brt +Prefetch the BRT (block reference table). +This may improve performance for block cloning operations, +and frees for earlier cloned blocks. +.It Sy ddt +Prefetch the DDT (deduplication table). +This may improve performance of writes when deduplication is enabled, +and frees for earlier deduplicated blocks. .El diff --git a/sys/contrib/openzfs/module/Kbuild.in b/sys/contrib/openzfs/module/Kbuild.in index 58a80dc4402c..95313c984178 100644 --- a/sys/contrib/openzfs/module/Kbuild.in +++ b/sys/contrib/openzfs/module/Kbuild.in @@ -293,10 +293,9 @@ ZSTD_UPSTREAM_OBJS := \ zfs-objs += $(addprefix zstd/,$(ZSTD_OBJS) $(ZSTD_UPSTREAM_OBJS)) -# Disable aarch64 neon SIMD instructions for kernel mode $(addprefix $(obj)/zstd/,$(ZSTD_OBJS) $(ZSTD_UPSTREAM_OBJS)) : ccflags-y += -I$(zstd_include) $(ZFS_ZSTD_FLAGS) $(addprefix $(obj)/zstd/,$(ZSTD_OBJS) $(ZSTD_UPSTREAM_OBJS)) : asflags-y += -I$(zstd_include) -$(addprefix $(obj)/zstd/,$(ZSTD_UPSTREAM_OBJS)) : ccflags-y += -include $(zstd_include)/aarch64_compat.h -include $(zstd_include)/zstd_compat_wrapper.h -Wp,-w +$(addprefix $(obj)/zstd/,$(ZSTD_UPSTREAM_OBJS)) : ccflags-y += -include $(zstd_include)/zstd_compat_wrapper.h -Wp,-w $(obj)/zstd/zfs_zstd.o : ccflags-y += -include $(zstd_include)/zstd_compat_wrapper.h diff --git a/sys/contrib/openzfs/module/Makefile.bsd b/sys/contrib/openzfs/module/Makefile.bsd index 3ba38c43f25b..c20fdc0c483b 100644 --- a/sys/contrib/openzfs/module/Makefile.bsd +++ b/sys/contrib/openzfs/module/Makefile.bsd @@ -521,30 +521,6 @@ CFLAGS.zstd_ldm.c= -U__BMI__ -fno-tree-vectorize ${NO_WBITWISE_INSTEAD_OF_LOGICA CFLAGS.zstd_opt.c= -U__BMI__ -fno-tree-vectorize ${NO_WBITWISE_INSTEAD_OF_LOGICAL} .if ${MACHINE_ARCH} == "aarch64" -__ZFS_ZSTD_AARCH64_FLAGS= -include ${SRCDIR}/zstd/include/aarch64_compat.h -CFLAGS.zstd.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.entropy_common.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.error_private.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.fse_compress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.fse_decompress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.hist.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.huf_compress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.huf_decompress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.pool.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.xxhash.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_common.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_compress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_compress_literals.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_compress_sequences.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_compress_superblock.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_ddict.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_decompress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_decompress_block.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_double_fast.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_fast.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_lazy.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_ldm.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} -CFLAGS.zstd_opt.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} sha256-armv8.o: sha256-armv8.S ${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC} \ diff --git a/sys/contrib/openzfs/module/icp/spi/kcf_spi.c b/sys/contrib/openzfs/module/icp/spi/kcf_spi.c index 806c0b028017..35fe55b2595d 100644 --- a/sys/contrib/openzfs/module/icp/spi/kcf_spi.c +++ b/sys/contrib/openzfs/module/icp/spi/kcf_spi.c @@ -31,7 +31,6 @@ */ -#include <sys/zfs_context.h> #include <sys/crypto/common.h> #include <sys/crypto/impl.h> #include <sys/crypto/sched_impl.h> diff --git a/sys/contrib/openzfs/module/os/freebsd/spl/spl_uio.c b/sys/contrib/openzfs/module/os/freebsd/spl/spl_uio.c index 54d4029c5e6f..b92be3710f3c 100644 --- a/sys/contrib/openzfs/module/os/freebsd/spl/spl_uio.c +++ b/sys/contrib/openzfs/module/os/freebsd/spl/spl_uio.c @@ -238,7 +238,7 @@ zfs_uio_iov_step(struct iovec v, zfs_uio_t *uio, int *numpages) zfs_uio_rw(uio), &uio->uio_dio.pages[uio->uio_dio.npages]); if (res != n) - return (SET_ERROR(EFAULT)); + return (EFAULT); ASSERT3U(len, ==, res * PAGE_SIZE); *numpages = res; diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c index 26cc7981bfcd..1990ec677d37 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/dmu_os.c @@ -76,7 +76,7 @@ dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, return (0); err = dmu_buf_hold_array(os, object, offset, size, - FALSE, FTAG, &numbufs, &dbp); + FALSE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH); if (err) return (err); @@ -147,7 +147,8 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count, ASSERT3S(last_size, <=, PAGE_SIZE); err = dmu_buf_hold_array(os, object, IDX_TO_OFF(ma[0]->pindex), - IDX_TO_OFF(count - 1) + last_size, TRUE, FTAG, &numbufs, &dbp); + IDX_TO_OFF(count - 1) + last_size, TRUE, FTAG, &numbufs, &dbp, + DMU_READ_PREFETCH); if (err != 0) return (err); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c index 2d04ccf95fbf..d918b26521a7 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/spa_os.c @@ -193,7 +193,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind) */ config = spa_generate_rootconf(name); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); if (config != NULL) { pname = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME); VERIFY0(strcmp(name, pname)); @@ -204,7 +204,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind) * e.g., after reboot -r. */ if (spa->spa_state == POOL_STATE_ACTIVE) { - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); fnvlist_free(config); return (0); } @@ -226,7 +226,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind) &spa->spa_ubsync.ub_version) != 0) spa->spa_ubsync.ub_version = SPA_VERSION_INITIAL; } else if ((spa = spa_lookup(name)) == NULL) { - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); fnvlist_free(config); cmn_err(CE_NOTE, "Cannot find the pool label for '%s'", name); @@ -249,7 +249,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind) VDEV_ALLOC_ROOTPOOL); spa_config_exit(spa, SCL_ALL, FTAG); if (error) { - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); fnvlist_free(config); cmn_err(CE_NOTE, "Can not parse the config for pool '%s'", name); @@ -259,7 +259,7 @@ spa_import_rootpool(const char *name, bool checkpointrewind) spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); vdev_free(rvd); spa_config_exit(spa, SCL_ALL, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); fnvlist_free(config); return (0); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c index 11e93b800a54..9663f05cb354 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c @@ -42,7 +42,8 @@ vdev_label_write_pad2(vdev_t *vd, const char *buf, size_t size) spa_t *spa = vd->vdev_spa; zio_t *zio; abd_t *pad2; - int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL; + int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL | + ZIO_FLAG_TRYHARD; int error; if (size > VDEV_PAD_SIZE) @@ -59,16 +60,11 @@ vdev_label_write_pad2(vdev_t *vd, const char *buf, size_t size) abd_copy_from_buf(pad2, buf, size); abd_zero_off(pad2, size, VDEV_PAD_SIZE - size); -retry: zio = zio_root(spa, NULL, NULL, flags); vdev_label_write(zio, vd, 0, pad2, offsetof(vdev_label_t, vl_be), VDEV_PAD_SIZE, NULL, NULL, flags); error = zio_wait(zio); - if (error != 0 && !(flags & ZIO_FLAG_TRYHARD)) { - flags |= ZIO_FLAG_TRYHARD; - goto retry; - } abd_free(pad2); return (error); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c index cb5787269db2..c98ccd756405 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c @@ -1262,7 +1262,8 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) if (aclnode->z_ace_count == 0) continue; dmu_write(zfsvfs->z_os, aoid, off, - aclnode->z_size, aclnode->z_acldata, tx); + aclnode->z_size, aclnode->z_acldata, tx, + DMU_READ_NO_PREFETCH); off += aclnode->z_size; } } else { diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c index dcdefae56639..29711fcf5d2c 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c @@ -108,11 +108,11 @@ zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) "command", &command) != 0) return (EINVAL); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa = spa_by_guid(pool_guid, vdev_guid); if (spa != NULL) strcpy(name, spa_name(spa)); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); if (spa == NULL) return (ENOENT); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c index f34a2fd37a77..8a9d23d0d554 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c @@ -278,7 +278,7 @@ zfs_ioctl_getxattr(vnode_t *vp, zfsxattr_t *fsx) memset(fsx, 0, sizeof (*fsx)); fsx->fsx_xflags = (zp->z_pflags & ZFS_PROJINHERIT) ? - ZFS_PROJINHERIT_FL : 0; + FS_PROJINHERIT_FL : 0; fsx->fsx_projid = zp->z_projid; return (0); @@ -290,7 +290,7 @@ zfs_ioctl_setflags(vnode_t *vp, uint32_t ioctl_flags, xvattr_t *xva) uint64_t zfs_flags = VTOZ(vp)->z_pflags; xoptattr_t *xoap; - if (ioctl_flags & ~(ZFS_PROJINHERIT_FL)) + if (ioctl_flags & ~(FS_PROJINHERIT_FL)) return (SET_ERROR(EOPNOTSUPP)); xva_init(xva); @@ -304,7 +304,7 @@ zfs_ioctl_setflags(vnode_t *vp, uint32_t ioctl_flags, xvattr_t *xva) } \ } while (0) - FLAG_CHANGE(ZFS_PROJINHERIT_FL, ZFS_PROJINHERIT, XAT_PROJINHERIT, + FLAG_CHANGE(FS_PROJINHERIT_FL, ZFS_PROJINHERIT, XAT_PROJINHERIT, xoap->xoa_projinherit); #undef FLAG_CHANGE @@ -4479,7 +4479,8 @@ zfs_putpages(struct vnode *vp, vm_page_t *ma, size_t len, int flags, for (i = 0; wlen > 0; woff += tocopy, wlen -= tocopy, i++) { tocopy = MIN(PAGE_SIZE, wlen); va = zfs_map_page(ma[i], &sf); - dmu_write(zfsvfs->z_os, zp->z_id, woff, tocopy, va, tx); + dmu_write(zfsvfs->z_os, zp->z_id, woff, tocopy, va, tx, + DMU_READ_PREFETCH); zfs_unmap_page(sf); } } else { @@ -5757,7 +5758,7 @@ zfs_freebsd_pathconf(struct vop_pathconf_args *ap) { ulong_t val; int error; -#ifdef _PC_CLONE_BLKSIZE +#if defined(_PC_CLONE_BLKSIZE) || defined(_PC_CASE_INSENSITIVE) zfsvfs_t *zfsvfs; #endif @@ -5821,6 +5822,15 @@ zfs_freebsd_pathconf(struct vop_pathconf_args *ap) *ap->a_retval = 0; return (0); #endif +#ifdef _PC_CASE_INSENSITIVE + case _PC_CASE_INSENSITIVE: + zfsvfs = (zfsvfs_t *)ap->a_vp->v_mount->mnt_data; + if (zfsvfs->z_case == ZFS_CASE_INSENSITIVE) + *ap->a_retval = 1; + else + *ap->a_retval = 0; + return (0); +#endif default: return (vop_stdpathconf(ap)); } diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c index 3ddbfcb97184..dc30f6dd939c 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c @@ -283,8 +283,8 @@ retry: * Take spa_namespace_lock to prevent lock inversion when * zvols from one pool are opened as vdevs in another. */ - if (!mutex_owned(&spa_namespace_lock)) { - if (!mutex_tryenter(&spa_namespace_lock)) { + if (!spa_namespace_held()) { + if (!spa_namespace_tryenter(FTAG)) { mutex_exit(&zv->zv_state_lock); rw_exit(&zv->zv_suspend_lock); drop_suspend = B_FALSE; @@ -296,7 +296,7 @@ retry: } err = zvol_first_open(zv, !(flag & FWRITE)); if (drop_namespace) - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); if (err) goto out_locked; pp->mediasize = zv->zv_volsize; @@ -963,8 +963,8 @@ retry: * Take spa_namespace_lock to prevent lock inversion when * zvols from one pool are opened as vdevs in another. */ - if (!mutex_owned(&spa_namespace_lock)) { - if (!mutex_tryenter(&spa_namespace_lock)) { + if (!spa_namespace_held()) { + if (!spa_namespace_tryenter(FTAG)) { mutex_exit(&zv->zv_state_lock); rw_exit(&zv->zv_suspend_lock); drop_suspend = B_FALSE; @@ -976,7 +976,7 @@ retry: } err = zvol_first_open(zv, !(flags & FWRITE)); if (drop_namespace) - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); if (err) goto out_locked; } diff --git a/sys/contrib/openzfs/module/os/linux/spl/spl-taskq.c b/sys/contrib/openzfs/module/os/linux/spl/spl-taskq.c index 092f090d934b..00ff789265c6 100644 --- a/sys/contrib/openzfs/module/os/linux/spl/spl-taskq.c +++ b/sys/contrib/openzfs/module/os/linux/spl/spl-taskq.c @@ -32,7 +32,6 @@ #include <sys/taskq.h> #include <sys/kmem.h> #include <sys/tsd.h> -#include <sys/trace_spl.h> #include <sys/time.h> #include <sys/atomic.h> #include <sys/kstat.h> @@ -325,7 +324,6 @@ task_expire_impl(taskq_ent_t *t) } t->tqent_birth = jiffies; - DTRACE_PROBE1(taskq_ent__birth, taskq_ent_t *, t); /* * The priority list must be maintained in strict task id order @@ -713,9 +711,7 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags) t->tqent_taskq = tq; t->tqent_timer.function = NULL; t->tqent_timer.expires = 0; - t->tqent_birth = jiffies; - DTRACE_PROBE1(taskq_ent__birth, taskq_ent_t *, t); ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC)); @@ -840,9 +836,7 @@ taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags, t->tqent_func = func; t->tqent_arg = arg; t->tqent_taskq = tq; - t->tqent_birth = jiffies; - DTRACE_PROBE1(taskq_ent__birth, taskq_ent_t *, t); spin_unlock(&t->tqent_lock); @@ -1054,11 +1048,6 @@ taskq_thread(void *args) * A TQENT_FLAG_PREALLOC task may be reused or freed * during the task function call. Store tqent_id and * tqent_flags here. - * - * Also use an on stack taskq_ent_t for tqt_task - * assignment in this case; we want to make sure - * to duplicate all fields, so the values are - * correct when it's accessed via DTRACE_PROBE*. */ tqt->tqt_id = t->tqent_id; tqt->tqt_flags = t->tqent_flags; @@ -1074,13 +1063,10 @@ taskq_thread(void *args) spin_unlock_irqrestore(&tq->tq_lock, flags); TQSTAT_INC(tq, threads_active); - DTRACE_PROBE1(taskq_ent__start, taskq_ent_t *, t); /* Perform the requested task */ t->tqent_func(t->tqent_arg); - DTRACE_PROBE1(taskq_ent__finish, taskq_ent_t *, t); - TQSTAT_DEC(tq, threads_active); if ((t->tqent_flags & TQENT_LIST_MASK) == TQENT_LIST_PENDING) diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c index 934d74a112fd..4c929a4642b1 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c @@ -1447,7 +1447,8 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) if (aclnode->z_ace_count == 0) continue; dmu_write(zfsvfs->z_os, aoid, off, - aclnode->z_size, aclnode->z_acldata, tx); + aclnode->z_size, aclnode->z_acldata, tx, + DMU_READ_NO_PREFETCH); off += aclnode->z_size; } } else { diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c index e845ad69ad78..02465adf36d5 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_vnops_os.c @@ -3892,7 +3892,8 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc, va = kmap(pp); ASSERT3U(pglen, <=, PAGE_SIZE); - dmu_write(zfsvfs->z_os, zp->z_id, pgoff, pglen, va, tx); + dmu_write(zfsvfs->z_os, zp->z_id, pgoff, pglen, va, tx, + DMU_READ_PREFETCH); kunmap(pp); SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16); diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c b/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c index 02965ac8cbee..f7691c02d163 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zpl_file.c @@ -811,28 +811,44 @@ zpl_fadvise(struct file *filp, loff_t offset, loff_t len, int advice) return (error); } -#define ZFS_FL_USER_VISIBLE (FS_FL_USER_VISIBLE | ZFS_PROJINHERIT_FL) -#define ZFS_FL_USER_MODIFIABLE (FS_FL_USER_MODIFIABLE | ZFS_PROJINHERIT_FL) +#define ZFS_FL_USER_VISIBLE (FS_FL_USER_VISIBLE | FS_PROJINHERIT_FL) +#define ZFS_FL_USER_MODIFIABLE (FS_FL_USER_MODIFIABLE | FS_PROJINHERIT_FL) + + +static struct { + uint64_t zfs_flag; + uint32_t fs_flag; + uint32_t xflag; +} flags_lookup[] = { + {ZFS_IMMUTABLE, FS_IMMUTABLE_FL, FS_XFLAG_IMMUTABLE}, + {ZFS_APPENDONLY, FS_APPEND_FL, FS_XFLAG_APPEND}, + {ZFS_NODUMP, FS_NODUMP_FL, FS_XFLAG_NODUMP}, + {ZFS_PROJINHERIT, FS_PROJINHERIT_FL, FS_XFLAG_PROJINHERIT} +}; static uint32_t __zpl_ioctl_getflags(struct inode *ip) { uint64_t zfs_flags = ITOZ(ip)->z_pflags; uint32_t ioctl_flags = 0; + for (int i = 0; i < ARRAY_SIZE(flags_lookup); i++) + if (zfs_flags & flags_lookup[i].zfs_flag) + ioctl_flags |= flags_lookup[i].fs_flag; - if (zfs_flags & ZFS_IMMUTABLE) - ioctl_flags |= FS_IMMUTABLE_FL; - - if (zfs_flags & ZFS_APPENDONLY) - ioctl_flags |= FS_APPEND_FL; + return (ioctl_flags); +} - if (zfs_flags & ZFS_NODUMP) - ioctl_flags |= FS_NODUMP_FL; +static uint32_t +__zpl_ioctl_getxflags(struct inode *ip) +{ + uint64_t zfs_flags = ITOZ(ip)->z_pflags; + uint32_t ioctl_flags = 0; - if (zfs_flags & ZFS_PROJINHERIT) - ioctl_flags |= ZFS_PROJINHERIT_FL; + for (int i = 0; i < ARRAY_SIZE(flags_lookup); i++) + if (zfs_flags & flags_lookup[i].zfs_flag) + ioctl_flags |= flags_lookup[i].xflag; - return (ioctl_flags & ZFS_FL_USER_VISIBLE); + return (ioctl_flags); } /* @@ -846,6 +862,7 @@ zpl_ioctl_getflags(struct file *filp, void __user *arg) int err; flags = __zpl_ioctl_getflags(file_inode(filp)); + flags = flags & ZFS_FL_USER_VISIBLE; err = copy_to_user(arg, &flags, sizeof (flags)); return (err); @@ -869,7 +886,7 @@ __zpl_ioctl_setflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva) xoptattr_t *xoap; if (ioctl_flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NODUMP_FL | - ZFS_PROJINHERIT_FL)) + FS_PROJINHERIT_FL)) return (-EOPNOTSUPP); if (ioctl_flags & ~ZFS_FL_USER_MODIFIABLE) @@ -900,7 +917,51 @@ __zpl_ioctl_setflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva) xoap->xoa_appendonly); FLAG_CHANGE(FS_NODUMP_FL, ZFS_NODUMP, XAT_NODUMP, xoap->xoa_nodump); - FLAG_CHANGE(ZFS_PROJINHERIT_FL, ZFS_PROJINHERIT, XAT_PROJINHERIT, + FLAG_CHANGE(FS_PROJINHERIT_FL, ZFS_PROJINHERIT, XAT_PROJINHERIT, + xoap->xoa_projinherit); + +#undef FLAG_CHANGE + + return (0); +} + +static int +__zpl_ioctl_setxflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva) +{ + uint64_t zfs_flags = ITOZ(ip)->z_pflags; + xoptattr_t *xoap; + + if (ioctl_flags & ~(FS_XFLAG_IMMUTABLE | FS_XFLAG_APPEND | + FS_XFLAG_NODUMP | FS_XFLAG_PROJINHERIT)) + return (-EOPNOTSUPP); + + if ((fchange(ioctl_flags, zfs_flags, FS_XFLAG_IMMUTABLE, + ZFS_IMMUTABLE) || + fchange(ioctl_flags, zfs_flags, FS_XFLAG_APPEND, ZFS_APPENDONLY)) && + !capable(CAP_LINUX_IMMUTABLE)) + return (-EPERM); + + if (!zpl_inode_owner_or_capable(zfs_init_idmap, ip)) + return (-EACCES); + + xva_init(xva); + xoap = xva_getxoptattr(xva); + +#define FLAG_CHANGE(iflag, zflag, xflag, xfield) do { \ + if (((ioctl_flags & (iflag)) && !(zfs_flags & (zflag))) || \ + ((zfs_flags & (zflag)) && !(ioctl_flags & (iflag)))) { \ + XVA_SET_REQ(xva, (xflag)); \ + (xfield) = ((ioctl_flags & (iflag)) != 0); \ + } \ +} while (0) + + FLAG_CHANGE(FS_XFLAG_IMMUTABLE, ZFS_IMMUTABLE, XAT_IMMUTABLE, + xoap->xoa_immutable); + FLAG_CHANGE(FS_XFLAG_APPEND, ZFS_APPENDONLY, XAT_APPENDONLY, + xoap->xoa_appendonly); + FLAG_CHANGE(FS_XFLAG_NODUMP, ZFS_NODUMP, XAT_NODUMP, + xoap->xoa_nodump); + FLAG_CHANGE(FS_XFLAG_PROJINHERIT, ZFS_PROJINHERIT, XAT_PROJINHERIT, xoap->xoa_projinherit); #undef FLAG_CHANGE @@ -941,7 +1002,7 @@ zpl_ioctl_getxattr(struct file *filp, void __user *arg) struct inode *ip = file_inode(filp); int err; - fsx.fsx_xflags = __zpl_ioctl_getflags(ip); + fsx.fsx_xflags = __zpl_ioctl_getxflags(ip); fsx.fsx_projid = ITOZ(ip)->z_projid; err = copy_to_user(arg, &fsx, sizeof (fsx)); @@ -965,7 +1026,7 @@ zpl_ioctl_setxattr(struct file *filp, void __user *arg) if (!zpl_is_valid_projid(fsx.fsx_projid)) return (-EINVAL); - err = __zpl_ioctl_setflags(ip, fsx.fsx_xflags, &xva); + err = __zpl_ioctl_setxflags(ip, fsx.fsx_xflags, &xva); if (err) return (err); diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c index fe939150b641..89f9bc555fcf 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c @@ -809,8 +809,8 @@ retry: * the kernel so the only option is to return the error for * the caller to handle it. */ - if (!mutex_owned(&spa_namespace_lock)) { - if (!mutex_tryenter(&spa_namespace_lock)) { + if (!spa_namespace_held()) { + if (!spa_namespace_tryenter(FTAG)) { mutex_exit(&zv->zv_state_lock); rw_exit(&zv->zv_suspend_lock); drop_suspend = B_FALSE; @@ -834,7 +834,7 @@ retry: error = -zvol_first_open(zv, !(blk_mode_is_open_write(flag))); if (drop_namespace) - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } if (error == 0) { diff --git a/sys/contrib/openzfs/module/zcommon/zpool_prop.c b/sys/contrib/openzfs/module/zcommon/zpool_prop.c index 07819ba2be8b..4826237b23e8 100644 --- a/sys/contrib/openzfs/module/zcommon/zpool_prop.c +++ b/sys/contrib/openzfs/module/zcommon/zpool_prop.c @@ -481,6 +481,9 @@ vdev_prop_init(void) zprop_register_index(VDEV_PROP_FAILFAST, "failfast", B_TRUE, PROP_DEFAULT, ZFS_TYPE_VDEV, "on | off", "FAILFAST", boolean_table, sfeatures); + zprop_register_index(VDEV_PROP_SLOW_IO_EVENTS, "slow_io_events", + B_TRUE, PROP_DEFAULT, ZFS_TYPE_VDEV, "on | off", + "SLOW_IO_EVENTS", boolean_table, sfeatures); /* hidden properties */ zprop_register_hidden(VDEV_PROP_NAME, "name", PROP_TYPE_STRING, diff --git a/sys/contrib/openzfs/module/zfs/arc.c b/sys/contrib/openzfs/module/zfs/arc.c index dbb5e942e2e6..48bf99f1aeb7 100644 --- a/sys/contrib/openzfs/module/zfs/arc.c +++ b/sys/contrib/openzfs/module/zfs/arc.c @@ -8548,7 +8548,7 @@ l2arc_dev_get_next(void) * of cache devices (l2arc_dev_mtx). Once a device has been selected, * both locks will be dropped and a spa config lock held instead. */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); mutex_enter(&l2arc_dev_mtx); /* if there are no vdevs, there is nothing to do */ @@ -8591,7 +8591,7 @@ out: */ if (next != NULL) spa_config_enter(next->l2ad_spa, SCL_L2ARC, next, RW_READER); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (next); } @@ -10231,7 +10231,7 @@ l2arc_stop(void) void l2arc_spa_rebuild_start(spa_t *spa) { - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); /* * Locate the spa's l2arc devices and kick off rebuild threads. @@ -10256,7 +10256,7 @@ l2arc_spa_rebuild_start(spa_t *spa) void l2arc_spa_rebuild_stop(spa_t *spa) { - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || spa->spa_export_thread == curthread); for (int i = 0; i < spa->spa_l2cache.sav_count; i++) { diff --git a/sys/contrib/openzfs/module/zfs/bpobj.c b/sys/contrib/openzfs/module/zfs/bpobj.c index ea9fbd036c6e..afcb2374f824 100644 --- a/sys/contrib/openzfs/module/zfs/bpobj.c +++ b/sys/contrib/openzfs/module/zfs/bpobj.c @@ -752,7 +752,8 @@ bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx) } dmu_write(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs, bpo->bpo_phys->bpo_num_subobjs * sizeof (subobj), - numsubsub * sizeof (subobj), subdb->db_data, tx); + numsubsub * sizeof (subobj), subdb->db_data, tx, + DMU_READ_NO_PREFETCH); dmu_buf_rele(subdb, FTAG); bpo->bpo_phys->bpo_num_subobjs += numsubsub; @@ -777,7 +778,7 @@ bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx) dmu_write(bpo->bpo_os, bpo->bpo_object, bpo->bpo_phys->bpo_num_blkptrs * sizeof (blkptr_t), numbps * sizeof (blkptr_t), - bps->db_data, tx); + bps->db_data, tx, DMU_READ_NO_PREFETCH); dmu_buf_rele(bps, FTAG); bpo->bpo_phys->bpo_num_blkptrs += numbps; @@ -794,7 +795,7 @@ bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx) dmu_write(bpo->bpo_os, bpo->bpo_phys->bpo_subobjs, bpo->bpo_phys->bpo_num_subobjs * sizeof (subobj), - sizeof (subobj), &subobj, tx); + sizeof (subobj), &subobj, tx, DMU_READ_NO_PREFETCH); bpo->bpo_phys->bpo_num_subobjs++; } diff --git a/sys/contrib/openzfs/module/zfs/bptree.c b/sys/contrib/openzfs/module/zfs/bptree.c index a98bba3eb259..1274278e8e91 100644 --- a/sys/contrib/openzfs/module/zfs/bptree.c +++ b/sys/contrib/openzfs/module/zfs/bptree.c @@ -137,7 +137,8 @@ bptree_add(objset_t *os, uint64_t obj, blkptr_t *bp, uint64_t birth_txg, bte = kmem_zalloc(sizeof (*bte), KM_SLEEP); bte->be_birth_txg = birth_txg; bte->be_bp = *bp; - dmu_write(os, obj, bt->bt_end * sizeof (*bte), sizeof (*bte), bte, tx); + dmu_write(os, obj, bt->bt_end * sizeof (*bte), sizeof (*bte), bte, tx, + DMU_READ_NO_PREFETCH); kmem_free(bte, sizeof (*bte)); dmu_buf_will_dirty(db, tx); @@ -247,7 +248,8 @@ bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func, ZB_DESTROYED_OBJSET); ASSERT0(bte.be_zb.zb_level); dmu_write(os, obj, i * sizeof (bte), - sizeof (bte), &bte, tx); + sizeof (bte), &bte, tx, + DMU_READ_NO_PREFETCH); if (err == EIO || err == ECKSUM || err == ENXIO) { /* @@ -269,7 +271,8 @@ bptree_iterate(objset_t *os, uint64_t obj, boolean_t free, bptree_itor_t func, */ bte.be_birth_txg = UINT64_MAX; dmu_write(os, obj, i * sizeof (bte), - sizeof (bte), &bte, tx); + sizeof (bte), &bte, tx, + DMU_READ_NO_PREFETCH); } if (!ioerr) { diff --git a/sys/contrib/openzfs/module/zfs/brt.c b/sys/contrib/openzfs/module/zfs/brt.c index 40664354aa73..08a6bd52ab31 100644 --- a/sys/contrib/openzfs/module/zfs/brt.c +++ b/sys/contrib/openzfs/module/zfs/brt.c @@ -260,8 +260,8 @@ static int brt_zap_prefetch = 1; #define BRT_DEBUG(...) do { } while (0) #endif -static int brt_zap_default_bs = 12; -static int brt_zap_default_ibs = 12; +static int brt_zap_default_bs = 13; +static int brt_zap_default_ibs = 13; static kstat_t *brt_ksp; @@ -454,6 +454,7 @@ brt_vdev_create(spa_t *spa, brt_vdev_t *brtvd, dmu_tx_t *tx) VERIFY(mos_entries != 0); VERIFY0(dnode_hold(spa->spa_meta_objset, mos_entries, brtvd, &brtvd->bv_mos_entries_dnode)); + dnode_set_storage_type(brtvd->bv_mos_entries_dnode, DMU_OT_DDT_ZAP); rw_enter(&brtvd->bv_mos_entries_lock, RW_WRITER); brtvd->bv_mos_entries = mos_entries; rw_exit(&brtvd->bv_mos_entries_lock); @@ -508,8 +509,8 @@ brt_vdev_realloc(spa_t *spa, brt_vdev_t *brtvd) size = (vdev_get_min_asize(vd) - 1) / spa->spa_brt_rangesize + 1; spa_config_exit(spa, SCL_VDEV, FTAG); - entcount = vmem_zalloc(sizeof (entcount[0]) * size, KM_SLEEP); nblocks = BRT_RANGESIZE_TO_NBLOCKS(size); + entcount = vmem_zalloc(nblocks * BRT_BLOCKSIZE, KM_SLEEP); bitmap = kmem_zalloc(BT_SIZEOFMAP(nblocks), KM_SLEEP); if (!brtvd->bv_initiated) { @@ -530,9 +531,8 @@ brt_vdev_realloc(spa_t *spa, brt_vdev_t *brtvd) memcpy(entcount, brtvd->bv_entcount, sizeof (entcount[0]) * MIN(size, brtvd->bv_size)); - vmem_free(brtvd->bv_entcount, - sizeof (entcount[0]) * brtvd->bv_size); onblocks = BRT_RANGESIZE_TO_NBLOCKS(brtvd->bv_size); + vmem_free(brtvd->bv_entcount, onblocks * BRT_BLOCKSIZE); memcpy(bitmap, brtvd->bv_bitmap, MIN(BT_SIZEOFMAP(nblocks), BT_SIZEOFMAP(onblocks))); kmem_free(brtvd->bv_bitmap, BT_SIZEOFMAP(onblocks)); @@ -581,13 +581,14 @@ brt_vdev_load(spa_t *spa, brt_vdev_t *brtvd) */ error = dmu_read(spa->spa_meta_objset, brtvd->bv_mos_brtvdev, 0, MIN(brtvd->bv_size, bvphys->bvp_size) * sizeof (uint16_t), - brtvd->bv_entcount, DMU_READ_NO_PREFETCH); + brtvd->bv_entcount, DMU_READ_NO_PREFETCH | DMU_UNCACHEDIO); if (error != 0) return (error); ASSERT(bvphys->bvp_mos_entries != 0); VERIFY0(dnode_hold(spa->spa_meta_objset, bvphys->bvp_mos_entries, brtvd, &brtvd->bv_mos_entries_dnode)); + dnode_set_storage_type(brtvd->bv_mos_entries_dnode, DMU_OT_DDT_ZAP); rw_enter(&brtvd->bv_mos_entries_lock, RW_WRITER); brtvd->bv_mos_entries = bvphys->bvp_mos_entries; rw_exit(&brtvd->bv_mos_entries_lock); @@ -613,9 +614,9 @@ brt_vdev_dealloc(brt_vdev_t *brtvd) ASSERT(brtvd->bv_initiated); ASSERT0(avl_numnodes(&brtvd->bv_tree)); - vmem_free(brtvd->bv_entcount, sizeof (uint16_t) * brtvd->bv_size); - brtvd->bv_entcount = NULL; uint64_t nblocks = BRT_RANGESIZE_TO_NBLOCKS(brtvd->bv_size); + vmem_free(brtvd->bv_entcount, nblocks * BRT_BLOCKSIZE); + brtvd->bv_entcount = NULL; kmem_free(brtvd->bv_bitmap, BT_SIZEOFMAP(nblocks)); brtvd->bv_bitmap = NULL; @@ -807,10 +808,10 @@ brt_vdev_sync(spa_t *spa, brt_vdev_t *brtvd, dmu_tx_t *tx) /* * TODO: Walk brtvd->bv_bitmap and write only the dirty blocks. */ - dmu_write(spa->spa_meta_objset, brtvd->bv_mos_brtvdev, 0, - brtvd->bv_size * sizeof (brtvd->bv_entcount[0]), - brtvd->bv_entcount, tx); uint64_t nblocks = BRT_RANGESIZE_TO_NBLOCKS(brtvd->bv_size); + dmu_write(spa->spa_meta_objset, brtvd->bv_mos_brtvdev, 0, + nblocks * BRT_BLOCKSIZE, brtvd->bv_entcount, tx, + DMU_READ_NO_PREFETCH | DMU_UNCACHEDIO); memset(brtvd->bv_bitmap, 0, BT_SIZEOFMAP(nblocks)); brtvd->bv_entcount_dirty = FALSE; } @@ -1510,6 +1511,31 @@ brt_load(spa_t *spa) } void +brt_prefetch_all(spa_t *spa) +{ + /* + * Load all BRT entries for each vdev. This is intended to perform + * a prefetch on all such blocks. For the same reason that brt_prefetch + * (called from brt_pending_add) isn't locked, this is also not locked. + */ + brt_rlock(spa); + for (uint64_t vdevid = 0; vdevid < spa->spa_brt_nvdevs; vdevid++) { + brt_vdev_t *brtvd = spa->spa_brt_vdevs[vdevid]; + brt_unlock(spa); + + rw_enter(&brtvd->bv_mos_entries_lock, RW_READER); + if (brtvd->bv_mos_entries != 0) { + (void) zap_prefetch_object(spa->spa_meta_objset, + brtvd->bv_mos_entries); + } + rw_exit(&brtvd->bv_mos_entries_lock); + + brt_rlock(spa); + } + brt_unlock(spa); +} + +void brt_unload(spa_t *spa) { if (spa->spa_brt_rangesize == 0) diff --git a/sys/contrib/openzfs/module/zfs/dbuf.c b/sys/contrib/openzfs/module/zfs/dbuf.c index fccc4c5b5b94..72c597609ade 100644 --- a/sys/contrib/openzfs/module/zfs/dbuf.c +++ b/sys/contrib/openzfs/module/zfs/dbuf.c @@ -446,7 +446,10 @@ static boolean_t dbuf_include_in_metadata_cache(dmu_buf_impl_t *db) { DB_DNODE_ENTER(db); - dmu_object_type_t type = DB_DNODE(db)->dn_type; + dnode_t *dn = DB_DNODE(db); + dmu_object_type_t type = dn->dn_storage_type; + if (type == DMU_OT_NONE) + type = dn->dn_type; DB_DNODE_EXIT(db); /* Check if this dbuf is one of the types we care about */ diff --git a/sys/contrib/openzfs/module/zfs/ddt_log.c b/sys/contrib/openzfs/module/zfs/ddt_log.c index c7a2426f3a77..3d42c51365a8 100644 --- a/sys/contrib/openzfs/module/zfs/ddt_log.c +++ b/sys/contrib/openzfs/module/zfs/ddt_log.c @@ -222,7 +222,7 @@ ddt_log_begin(ddt_t *ddt, size_t nentries, dmu_tx_t *tx, ddt_log_update_t *dlu) VERIFY0(dmu_buf_hold_array_by_dnode(dlu->dlu_dn, offset, length, B_FALSE, FTAG, &dlu->dlu_ndbp, &dlu->dlu_dbp, - DMU_READ_NO_PREFETCH)); + DMU_READ_NO_PREFETCH | DMU_UNCACHEDIO)); dlu->dlu_tx = tx; dlu->dlu_block = dlu->dlu_offset = 0; @@ -298,7 +298,8 @@ ddt_log_entry(ddt_t *ddt, ddt_lightweight_entry_t *ddlwe, ddt_log_update_t *dlu) * we will fill it, and zero it out. */ if (dlu->dlu_offset == 0) { - dmu_buf_will_fill(db, dlu->dlu_tx, B_FALSE); + dmu_buf_will_fill_flags(db, dlu->dlu_tx, B_FALSE, + DMU_UNCACHEDIO); memset(db->db_data, 0, db->db_size); } @@ -597,7 +598,7 @@ ddt_log_load_one(ddt_t *ddt, uint_t n) for (uint64_t offset = 0; offset < hdr.dlh_length; offset += dn->dn_datablksz) { err = dmu_buf_hold_by_dnode(dn, offset, FTAG, &db, - DMU_READ_PREFETCH); + DMU_READ_PREFETCH | DMU_UNCACHEDIO); if (err != 0) { dnode_rele(dn, FTAG); ddt_log_empty(ddt, ddl); diff --git a/sys/contrib/openzfs/module/zfs/dmu.c b/sys/contrib/openzfs/module/zfs/dmu.c index a7a5c89bdafb..5690f8afad00 100644 --- a/sys/contrib/openzfs/module/zfs/dmu.c +++ b/sys/contrib/openzfs/module/zfs/dmu.c @@ -635,7 +635,7 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length, int dmu_buf_hold_array(objset_t *os, uint64_t object, uint64_t offset, uint64_t length, int read, const void *tag, int *numbufsp, - dmu_buf_t ***dbpp) + dmu_buf_t ***dbpp, dmu_flags_t flags) { dnode_t *dn; int err; @@ -645,7 +645,7 @@ dmu_buf_hold_array(objset_t *os, uint64_t object, uint64_t offset, return (err); err = dmu_buf_hold_array_by_dnode(dn, offset, length, read, tag, - numbufsp, dbpp, DMU_READ_PREFETCH); + numbufsp, dbpp, flags); dnode_rele(dn, FTAG); @@ -655,14 +655,14 @@ dmu_buf_hold_array(objset_t *os, uint64_t object, uint64_t offset, int dmu_buf_hold_array_by_bonus(dmu_buf_t *db_fake, uint64_t offset, uint64_t length, boolean_t read, const void *tag, int *numbufsp, - dmu_buf_t ***dbpp) + dmu_buf_t ***dbpp, dmu_flags_t flags) { dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake; int err; DB_DNODE_ENTER(db); err = dmu_buf_hold_array_by_dnode(DB_DNODE(db), offset, length, read, - tag, numbufsp, dbpp, DMU_READ_PREFETCH); + tag, numbufsp, dbpp, flags); DB_DNODE_EXIT(db); return (err); @@ -850,12 +850,15 @@ dmu_prefetch_wait(objset_t *os, uint64_t object, uint64_t offset, uint64_t size) return (err); /* - * Chunk the requests (16 indirects worth) so that we can be interrupted + * Chunk the requests (16 indirects worth) so that we can be + * interrupted. Prefetch at least SPA_MAXBLOCKSIZE at a time + * to better utilize pools with smaller block sizes. */ uint64_t chunksize; if (dn->dn_indblkshift) { uint64_t nbps = bp_span_in_blocks(dn->dn_indblkshift, 1); chunksize = (nbps * 16) << dn->dn_datablkshift; + chunksize = MAX(chunksize, SPA_MAXBLOCKSIZE); } else { chunksize = dn->dn_datablksz; } @@ -1293,7 +1296,7 @@ dmu_write_impl(dmu_buf_t **dbp, int numbufs, uint64_t offset, uint64_t size, void dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, - const void *buf, dmu_tx_t *tx) + const void *buf, dmu_tx_t *tx, dmu_flags_t flags) { dmu_buf_t **dbp; int numbufs; @@ -1302,8 +1305,8 @@ dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, return; VERIFY0(dmu_buf_hold_array(os, object, offset, size, - FALSE, FTAG, &numbufs, &dbp)); - dmu_write_impl(dbp, numbufs, offset, size, buf, tx, DMU_READ_PREFETCH); + FALSE, FTAG, &numbufs, &dbp, flags)); + dmu_write_impl(dbp, numbufs, offset, size, buf, tx, flags); dmu_buf_rele_array(dbp, numbufs, FTAG); } @@ -1346,7 +1349,7 @@ dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, return; VERIFY0(dmu_buf_hold_array(os, object, offset, size, - FALSE, FTAG, &numbufs, &dbp)); + FALSE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH)); for (i = 0; i < numbufs; i++) { dmu_buf_t *db = dbp[i]; @@ -1383,7 +1386,7 @@ dmu_redact(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_buf_t **dbp; VERIFY0(dmu_buf_hold_array(os, object, offset, size, FALSE, FTAG, - &numbufs, &dbp)); + &numbufs, &dbp, DMU_READ_PREFETCH)); for (i = 0; i < numbufs; i++) dmu_buf_redact(dbp[i], tx); dmu_buf_rele_array(dbp, numbufs, FTAG); @@ -2592,7 +2595,7 @@ dmu_read_l0_bps(objset_t *os, uint64_t object, uint64_t offset, uint64_t length, int error, numbufs; error = dmu_buf_hold_array(os, object, offset, length, FALSE, FTAG, - &numbufs, &dbp); + &numbufs, &dbp, DMU_READ_PREFETCH); if (error != 0) { if (error == ESRCH) { error = SET_ERROR(ENXIO); @@ -2693,7 +2696,7 @@ dmu_brt_clone(objset_t *os, uint64_t object, uint64_t offset, uint64_t length, spa = os->os_spa; VERIFY0(dmu_buf_hold_array(os, object, offset, length, FALSE, FTAG, - &numbufs, &dbp)); + &numbufs, &dbp, DMU_READ_PREFETCH)); ASSERT3U(nbps, ==, numbufs); /* diff --git a/sys/contrib/openzfs/module/zfs/dmu_redact.c b/sys/contrib/openzfs/module/zfs/dmu_redact.c index 5a22ed71a5fe..c087be4c811d 100644 --- a/sys/contrib/openzfs/module/zfs/dmu_redact.c +++ b/sys/contrib/openzfs/module/zfs/dmu_redact.c @@ -544,7 +544,8 @@ redaction_list_update_sync(void *arg, dmu_tx_t *tx) if (index == bufsize) { dmu_write(mos, rl->rl_object, rl->rl_phys->rlp_num_entries * sizeof (*buf), - bufsize * sizeof (*buf), buf, tx); + bufsize * sizeof (*buf), buf, tx, + DMU_READ_NO_PREFETCH); rl->rl_phys->rlp_num_entries += bufsize; index = 0; } @@ -552,7 +553,8 @@ redaction_list_update_sync(void *arg, dmu_tx_t *tx) } if (index > 0) { dmu_write(mos, rl->rl_object, rl->rl_phys->rlp_num_entries * - sizeof (*buf), index * sizeof (*buf), buf, tx); + sizeof (*buf), index * sizeof (*buf), buf, tx, + DMU_READ_NO_PREFETCH); rl->rl_phys->rlp_num_entries += index; } kmem_free(buf, bufsize * sizeof (*buf)); diff --git a/sys/contrib/openzfs/module/zfs/dnode.c b/sys/contrib/openzfs/module/zfs/dnode.c index e88d394b5229..e0cc4a7e13e0 100644 --- a/sys/contrib/openzfs/module/zfs/dnode.c +++ b/sys/contrib/openzfs/module/zfs/dnode.c @@ -2496,26 +2496,27 @@ dnode_diduse_space(dnode_t *dn, int64_t delta) } /* - * Scans a block at the indicated "level" looking for a hole or data, - * depending on 'flags'. + * Scans the block at the indicated "level" looking for a hole or data, + * depending on 'flags' starting from array position given by *index. * - * If level > 0, then we are scanning an indirect block looking at its - * pointers. If level == 0, then we are looking at a block of dnodes. + * If lvl > 0, then we are scanning an indirect block looking at its + * pointers. If lvl == 0, then we are looking at a block of dnodes. * * If we don't find what we are looking for in the block, we return ESRCH. - * Otherwise, return with *offset pointing to the beginning (if searching - * forwards) or end (if searching backwards) of the range covered by the - * block pointer we matched on (or dnode). + * Otherwise, return with *index set to the matching array position. * - * The basic search algorithm used below by dnode_next_offset() is to - * use this function to search up the block tree (widen the search) until - * we find something (i.e., we don't return ESRCH) and then search back - * down the tree (narrow the search) until we reach our original search - * level. + * In both cases, *offset is updated to point at the matched BP/dnode or + * the next offset to search (unless at the limit of possible offsets). + * + * The basic search algorithm used below by dnode_next_offset() uses this + * function to perform a block-order tree traversal. We search up the block + * tree (widen the search) until we find something (i.e., we don't return + * ESRCH) and then search back down the tree (narrow the search) until we + * reach our original search level or backtrack up because nothing matches. */ static int -dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset, - int lvl, uint64_t blkfill, uint64_t txg) +dnode_next_offset_level(dnode_t *dn, int flags, int lvl, uint64_t blkid, + int *index, uint64_t blkfill, uint64_t txg, uint64_t *offset) { dmu_buf_impl_t *db = NULL; void *data = NULL; @@ -2541,20 +2542,12 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset, rrw_enter(&dmu_objset_ds(dn->dn_objset)->ds_bp_rwlock, RW_READER, FTAG); } else { - uint64_t blkid = dbuf_whichblock(dn, lvl, *offset); error = dbuf_hold_impl(dn, lvl, blkid, TRUE, FALSE, FTAG, &db); if (error) { if (error != ENOENT) return (error); if (hole) return (0); - /* - * This can only happen when we are searching up - * the block tree for data. We don't really need to - * adjust the offset, as we will just end up looking - * at the pointer to this block in its parent, and its - * going to be unallocated, so we will skip over it. - */ return (SET_ERROR(ESRCH)); } error = dbuf_read(db, NULL, @@ -2582,8 +2575,7 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset, ASSERT(dn->dn_type == DMU_OT_DNODE); ASSERT(!(flags & DNODE_FIND_BACKWARDS)); - for (i = (*offset >> DNODE_SHIFT) & (blkfill - 1); - i < blkfill; i += dnp[i].dn_extra_slots + 1) { + for (i = *index; i < blkfill; i += dnp[i].dn_extra_slots + 1) { if ((dnp[i].dn_type == DMU_OT_NONE) == hole) break; } @@ -2591,11 +2583,11 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset, if (i == blkfill) error = SET_ERROR(ESRCH); + *index = i; *offset = (*offset & ~(DNODE_BLOCK_SIZE - 1)) + (i << DNODE_SHIFT); } else { blkptr_t *bp = data; - uint64_t start = *offset; span = (lvl - 1) * epbs + dn->dn_datablkshift; minfill = 0; maxfill = blkfill << ((lvl - 1) * epbs); @@ -2605,40 +2597,27 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset, else minfill++; - if (span >= 8 * sizeof (*offset)) { - /* This only happens on the highest indirection level */ - ASSERT3U((lvl - 1), ==, dn->dn_phys->dn_nlevels - 1); - *offset = 0; - } else { - *offset = *offset >> span; - } - - for (i = BF64_GET(*offset, 0, epbs); - i >= 0 && i < epb; i += inc) { + for (i = *index; i >= 0 && i < epb; i += inc) { if (BP_GET_FILL(&bp[i]) >= minfill && BP_GET_FILL(&bp[i]) <= maxfill && (hole || BP_GET_LOGICAL_BIRTH(&bp[i]) > txg)) break; - if (inc > 0 || *offset > 0) - *offset += inc; } - if (span >= 8 * sizeof (*offset)) { - *offset = start; - } else { - *offset = *offset << span; - } - - if (inc < 0) { - /* traversing backwards; position offset at the end */ - if (span < 8 * sizeof (*offset)) - *offset = MIN(*offset + (1ULL << span) - 1, - start); - } else if (*offset < start) { - *offset = start; - } if (i < 0 || i >= epb) error = SET_ERROR(ESRCH); + + *index = i; + if (span < 8 * sizeof (*offset)) { + uint64_t nblk = blkid << epbs; + if (i >= 0 || blkid != 0) + nblk += i; + if ((nblk >> (8 * sizeof (*offset) - span)) == 0) + *offset = (flags & DNODE_FIND_BACKWARDS) ? + /* backwards: position offset at the end */ + MIN(*offset, ((nblk + 1) << span) - 1) : + MAX(*offset, nblk << span); + } } if (db != NULL) { @@ -2656,38 +2635,24 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset, } /* - * Adjust *offset to the next (or previous) block byte offset at lvl. - * Returns FALSE if *offset would overflow or underflow. - */ -static boolean_t -dnode_next_block(dnode_t *dn, int flags, uint64_t *offset, int lvl) -{ - int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT; - int span = lvl * epbs + dn->dn_datablkshift; - uint64_t blkid, maxblkid; - - if (span >= 8 * sizeof (uint64_t)) - return (B_FALSE); - - blkid = *offset >> span; - maxblkid = 1ULL << (8 * sizeof (*offset) - span); - if (!(flags & DNODE_FIND_BACKWARDS) && blkid + 1 < maxblkid) - *offset = (blkid + 1) << span; - else if ((flags & DNODE_FIND_BACKWARDS) && blkid > 0) - *offset = (blkid << span) - 1; - else - return (B_FALSE); - - return (B_TRUE); -} - -/* * Find the next hole, data, or sparse region at or after *offset. * The value 'blkfill' tells us how many items we expect to find * in an L0 data block; this value is 1 for normal objects, * DNODES_PER_BLOCK for the meta dnode, and some fraction of * DNODES_PER_BLOCK when searching for sparse regions thereof. * + * If minlvl == 0, this searches for dnodes or unallocated dnodes. + * If found, *offset points to the first offset of the matched dnode. + * Backwards search is not allowed for dnodes. + * + * If minlvl > 0, this searches for blocks at the given level. + * If found, *offset points to the first L0 offset of the block + * (or for backwards search, the last offset, inclusive). + * + * If not found, in both cases, *offset is set to the first (or last) + * offset of the unallocated indirect block where the search ended or + * the initial offset if no such block was encountered. + * * Examples: * * dnode_next_offset(dn, flags, offset, 1, 1, 0); @@ -2708,7 +2673,8 @@ int dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset, int minlvl, uint64_t blkfill, uint64_t txg) { - uint64_t matched = *offset; + uint64_t blkid; + int index, epbs; int lvl, maxlvl; int error = 0; @@ -2730,18 +2696,31 @@ dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset, goto out; } + epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT; maxlvl = dn->dn_phys->dn_nlevels; + if (minlvl > 0) { + uint64_t n = dbuf_whichblock(dn, minlvl - 1, *offset); + blkid = n >> epbs; + index = BF64_GET(n, 0, epbs); + } else { + blkid = dbuf_whichblock(dn, 0, *offset); + index = (*offset >> DNODE_SHIFT) & (blkfill - 1); + ASSERT3U(BF64_GET(*offset, 0, DNODE_SHIFT), ==, 0); + } + for (lvl = minlvl; lvl <= maxlvl; ) { error = dnode_next_offset_level(dn, - flags, offset, lvl, blkfill, txg); + flags, lvl, blkid, &index, blkfill, txg, offset); + if (error == 0 && lvl > minlvl) { + /* Continue search at matched block in lvl-1. */ + blkid = (blkid << epbs) + index; + index = 0; --lvl; - matched = *offset; - } else if (error == ESRCH && lvl < maxlvl && - dnode_next_block(dn, flags, &matched, lvl)) { + } else if (error == ESRCH && lvl < maxlvl) { /* - * Continue search at next/prev offset in lvl+1 block. + * Continue search at next/prev index in lvl+1 block. * * Usually we only search upwards at the start of the * search as higher level blocks point at a matching @@ -2752,13 +2731,14 @@ dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset, * happens if we are still syncing out the tree, and * some BP's at higher levels are not updated yet. * - * We must adjust offset to avoid coming back to the - * same offset and getting stuck looping forever. This - * also deals with the case where offset is already at - * the beginning or end of the object. + * We must adjust index to avoid coming back to the + * same offset and getting stuck looping forever. The + * next loop goes up again if index is -1 or (1<<epbs). */ + index = BF64_GET(blkid, 0, epbs) + + ((flags & DNODE_FIND_BACKWARDS) ? -1 : 1); + blkid = blkid >> epbs; ++lvl; - *offset = matched; } else { break; } diff --git a/sys/contrib/openzfs/module/zfs/metaslab.c b/sys/contrib/openzfs/module/zfs/metaslab.c index 9f4399af56bd..3f649ffb44e4 100644 --- a/sys/contrib/openzfs/module/zfs/metaslab.c +++ b/sys/contrib/openzfs/module/zfs/metaslab.c @@ -3966,7 +3966,8 @@ metaslab_condense(metaslab_t *msp, dmu_tx_t *tx) object = space_map_object(msp->ms_sm); dmu_write(spa->spa_meta_objset, msp->ms_group->mg_vd->vdev_ms_array, sizeof (uint64_t) * - msp->ms_id, sizeof (uint64_t), &object, tx); + msp->ms_id, sizeof (uint64_t), &object, tx, + DMU_READ_NO_PREFETCH); } /* @@ -4292,7 +4293,8 @@ metaslab_sync(metaslab_t *msp, uint64_t txg) VERIFY3U(new_object, !=, 0); dmu_write(mos, vd->vdev_ms_array, sizeof (uint64_t) * - msp->ms_id, sizeof (uint64_t), &new_object, tx); + msp->ms_id, sizeof (uint64_t), &new_object, tx, + DMU_READ_NO_PREFETCH); VERIFY0(space_map_open(&msp->ms_sm, mos, new_object, msp->ms_start, msp->ms_size, vd->vdev_ashift)); @@ -6328,7 +6330,7 @@ metaslab_update_ondisk_flush_data(metaslab_t *ms, dmu_tx_t *tx) } dmu_write(spa_meta_objset(spa), object, entry_offset, entry_size, - &entry, tx); + &entry, tx, DMU_READ_NO_PREFETCH); } void diff --git a/sys/contrib/openzfs/module/zfs/mmp.c b/sys/contrib/openzfs/module/zfs/mmp.c index fd46127b6068..b8ba40ecdc9d 100644 --- a/sys/contrib/openzfs/module/zfs/mmp.c +++ b/sys/contrib/openzfs/module/zfs/mmp.c @@ -729,12 +729,12 @@ mmp_signal_all_threads(void) { spa_t *spa = NULL; - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); while ((spa = spa_next(spa))) { if (spa->spa_state == POOL_STATE_ACTIVE) mmp_signal_thread(spa); } - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } ZFS_MODULE_PARAM_CALL(zfs_multihost, zfs_multihost_, interval, diff --git a/sys/contrib/openzfs/module/zfs/spa.c b/sys/contrib/openzfs/module/zfs/spa.c index b3bb46da263b..34de3f1d9525 100644 --- a/sys/contrib/openzfs/module/zfs/spa.c +++ b/sys/contrib/openzfs/module/zfs/spa.c @@ -141,7 +141,7 @@ typedef enum zti_modes { #define ZTI_P(n, q) { ZTI_MODE_FIXED, (n), (q) } #define ZTI_PCT(n) { ZTI_MODE_ONLINE_PERCENT, (n), 1 } -#define ZTI_SCALE { ZTI_MODE_SCALE, 0, 1 } +#define ZTI_SCALE(min) { ZTI_MODE_SCALE, (min), 1 } #define ZTI_SYNC { ZTI_MODE_SYNC, 0, 1 } #define ZTI_NULL { ZTI_MODE_NULL, 0, 0 } @@ -180,13 +180,13 @@ static const char *const zio_taskq_types[ZIO_TASKQ_TYPES] = { static zio_taskq_info_t zio_taskqs[ZIO_TYPES][ZIO_TASKQ_TYPES] = { /* ISSUE ISSUE_HIGH INTR INTR_HIGH */ { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* NULL */ - { ZTI_N(8), ZTI_NULL, ZTI_SCALE, ZTI_NULL }, /* READ */ + { ZTI_N(8), ZTI_NULL, ZTI_SCALE(0), ZTI_NULL }, /* READ */ #ifdef illumos - { ZTI_SYNC, ZTI_N(5), ZTI_SCALE, ZTI_N(5) }, /* WRITE */ + { ZTI_SYNC, ZTI_N(5), ZTI_SCALE(0), ZTI_N(5) }, /* WRITE */ #else - { ZTI_SYNC, ZTI_NULL, ZTI_SCALE, ZTI_NULL }, /* WRITE */ + { ZTI_SYNC, ZTI_NULL, ZTI_SCALE(0), ZTI_NULL }, /* WRITE */ #endif - { ZTI_SCALE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* FREE */ + { ZTI_SCALE(32), ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* FREE */ { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* CLAIM */ { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* FLUSH */ { ZTI_N(4), ZTI_NULL, ZTI_ONE, ZTI_NULL }, /* TRIM */ @@ -1082,7 +1082,7 @@ spa_change_guid(spa_t *spa, const uint64_t *guidp) int error; mutex_enter(&spa->spa_vdev_top_lock); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); if (guidp != NULL) { guid = *guidp; @@ -1117,7 +1117,7 @@ spa_change_guid(spa_t *spa, const uint64_t *guidp) } out: - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); mutex_exit(&spa->spa_vdev_top_lock); return (error); @@ -1170,7 +1170,7 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q) uint_t value = ztip->zti_value; uint_t count = ztip->zti_count; spa_taskqs_t *tqs = &spa->spa_zio_taskq[t][q]; - uint_t cpus, flags = TASKQ_DYNAMIC; + uint_t cpus, threads, flags = TASKQ_DYNAMIC; switch (mode) { case ZTI_MODE_FIXED: @@ -1183,8 +1183,8 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q) * Create one wr_iss taskq for every 'zio_taskq_write_tpq' CPUs, * not to exceed the number of spa allocators, and align to it. */ - cpus = MAX(1, boot_ncpus * zio_taskq_batch_pct / 100); - count = MAX(1, cpus / MAX(1, zio_taskq_write_tpq)); + threads = MAX(1, boot_ncpus * zio_taskq_batch_pct / 100); + count = MAX(1, threads / MAX(1, zio_taskq_write_tpq)); count = MAX(count, (zio_taskq_batch_pct + 99) / 100); count = MIN(count, spa->spa_alloc_count); while (spa->spa_alloc_count % count != 0 && @@ -1201,14 +1201,14 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q) break; case ZTI_MODE_SCALE: - flags |= TASKQ_THREADS_CPU_PCT; /* * We want more taskqs to reduce lock contention, but we want * less for better request ordering and CPU utilization. */ - cpus = MAX(1, boot_ncpus * zio_taskq_batch_pct / 100); + threads = MAX(1, boot_ncpus * zio_taskq_batch_pct / 100); + threads = MAX(threads, value); if (zio_taskq_batch_tpq > 0) { - count = MAX(1, (cpus + zio_taskq_batch_tpq / 2) / + count = MAX(1, (threads + zio_taskq_batch_tpq / 2) / zio_taskq_batch_tpq); } else { /* @@ -1228,13 +1228,23 @@ spa_taskqs_init(spa_t *spa, zio_type_t t, zio_taskq_type_t q) * 128 10 8% 10 100 * 256 14 6% 15 210 */ - count = 1 + cpus / 6; + cpus = MIN(threads, boot_ncpus); + count = 1 + threads / 6; while (count * count > cpus) count--; } - /* Limit each taskq within 100% to not trigger assertion. */ - count = MAX(count, (zio_taskq_batch_pct + 99) / 100); - value = (zio_taskq_batch_pct + count / 2) / count; + + /* + * Try to represent the number of threads per taskq as percent + * of online CPUs to allow scaling with later online/offline. + * Fall back to absolute numbers if can't. + */ + value = (threads * 100 + boot_ncpus * count / 2) / + (boot_ncpus * count); + if (value < 5 || value > 100) + value = MAX(1, (threads + count / 2) / count); + else + flags |= TASKQ_THREADS_CPU_PCT; break; case ZTI_MODE_NULL: @@ -1433,8 +1443,30 @@ spa_taskq_param_set(zio_type_t t, char *cfg) break; } + /* + * SCALE is optionally parameterised by minimum number of + * threads. + */ case ZTI_MODE_SCALE: { - const zio_taskq_info_t zti = ZTI_SCALE; + unsigned long long mint = 0; + if (c != NULL && *c != '\0') { + /* Need a number */ + if (!(isdigit(*c))) + break; + tok = c; + + /* Take digits */ + err = ddi_strtoull(tok, &tok, 10, &mint); + /* Must succeed, and moved forward */ + if (err != 0 || tok == c || *tok != '\0') + break; + + /* Sanity check */ + if (mint >= 16384) + break; + } + + const zio_taskq_info_t zti = ZTI_SCALE(mint); row[q] = zti; break; } @@ -1501,6 +1533,9 @@ spa_taskq_param_get(zio_type_t t, char *buf, boolean_t add_newline) pos += sprintf(&buf[pos], "%s%s,%u,%u", sep, modes[zti->zti_mode], zti->zti_count, zti->zti_value); + else if (zti->zti_mode == ZTI_MODE_SCALE && zti->zti_value > 0) + pos += sprintf(&buf[pos], "%s%s,%u", sep, + modes[zti->zti_mode], zti->zti_value); else pos += sprintf(&buf[pos], "%s%s", sep, modes[zti->zti_mode]); @@ -1520,9 +1555,10 @@ spa_taskq_read_param_set(const char *val, zfs_kernel_param_t *kp) { char *cfg = kmem_strdup(val); int err = spa_taskq_param_set(ZIO_TYPE_READ, cfg); - kmem_free(cfg, strlen(val)+1); + kmem_strfree(cfg); return (-err); } + static int spa_taskq_read_param_get(char *buf, zfs_kernel_param_t *kp) { @@ -1534,14 +1570,30 @@ spa_taskq_write_param_set(const char *val, zfs_kernel_param_t *kp) { char *cfg = kmem_strdup(val); int err = spa_taskq_param_set(ZIO_TYPE_WRITE, cfg); - kmem_free(cfg, strlen(val)+1); + kmem_strfree(cfg); return (-err); } + static int spa_taskq_write_param_get(char *buf, zfs_kernel_param_t *kp) { return (spa_taskq_param_get(ZIO_TYPE_WRITE, buf, TRUE)); } + +static int +spa_taskq_free_param_set(const char *val, zfs_kernel_param_t *kp) +{ + char *cfg = kmem_strdup(val); + int err = spa_taskq_param_set(ZIO_TYPE_FREE, cfg); + kmem_strfree(cfg); + return (-err); +} + +static int +spa_taskq_free_param_get(char *buf, zfs_kernel_param_t *kp) +{ + return (spa_taskq_param_get(ZIO_TYPE_FREE, buf, TRUE)); +} #else /* * On FreeBSD load-time parameters can be set up before malloc() is available, @@ -1574,6 +1626,19 @@ spa_taskq_write_param(ZFS_MODULE_PARAM_ARGS) return (err); return (spa_taskq_param_set(ZIO_TYPE_WRITE, buf)); } + +static int +spa_taskq_free_param(ZFS_MODULE_PARAM_ARGS) +{ + char buf[SPA_TASKQ_PARAM_MAX]; + int err; + + (void) spa_taskq_param_get(ZIO_TYPE_FREE, buf, FALSE); + err = sysctl_handle_string(oidp, buf, sizeof (buf), req); + if (err || req->newptr == NULL) + return (err); + return (spa_taskq_param_set(ZIO_TYPE_FREE, buf)); +} #endif #endif /* _KERNEL */ @@ -2187,7 +2252,7 @@ spa_should_sync_time_logger_on_unload(spa_t *spa) static void spa_unload(spa_t *spa) { - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || spa->spa_export_thread == curthread); ASSERT(spa_state(spa) != POOL_STATE_UNINITIALIZED); @@ -5260,7 +5325,7 @@ spa_ld_read_checkpoint_txg(spa_t *spa) int error = 0; ASSERT0(spa->spa_checkpoint_txg); - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || spa->spa_load_thread == curthread); error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT, @@ -5287,7 +5352,7 @@ spa_ld_mos_init(spa_t *spa, spa_import_type_t type) { int error = 0; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); ASSERT(spa->spa_config_source != SPA_CONFIG_SRC_NONE); /* @@ -5363,7 +5428,7 @@ spa_ld_checkpoint_rewind(spa_t *spa) uberblock_t checkpoint; int error = 0; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); ASSERT(spa->spa_import_flags & ZFS_IMPORT_CHECKPOINT); error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT, @@ -5510,7 +5575,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport) boolean_t update_config_cache = B_FALSE; hrtime_t load_start = gethrtime(); - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); ASSERT(spa->spa_config_source != SPA_CONFIG_SRC_NONE); spa_load_note(spa, "LOADING"); @@ -5557,7 +5622,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport) * Drop the namespace lock for the rest of the function. */ spa->spa_load_thread = curthread; - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); /* * Retrieve the checkpoint txg if the pool has a checkpoint. @@ -5796,9 +5861,9 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport) spa_load_note(spa, "LOADED"); fail: - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa->spa_load_thread = NULL; - cv_broadcast(&spa_namespace_cv); + spa_namespace_broadcast(); return (error); @@ -5960,14 +6025,14 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag, * up calling spa_open() again. The real fix is to figure out how to * avoid dsl_dir_open() calling this in the first place. */ - if (MUTEX_NOT_HELD(&spa_namespace_lock)) { - mutex_enter(&spa_namespace_lock); + if (!spa_namespace_held()) { + spa_namespace_enter(FTAG); locked = B_TRUE; } if ((spa = spa_lookup(pool)) == NULL) { if (locked) - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (SET_ERROR(ENOENT)); } @@ -6004,7 +6069,7 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag, spa_write_cachefile(spa, B_TRUE, B_TRUE, B_FALSE); spa_remove(spa); if (locked) - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (SET_ERROR(ENOENT)); } @@ -6024,7 +6089,7 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag, spa_deactivate(spa); spa->spa_last_open_failed = error; if (locked) - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); *spapp = NULL; return (error); } @@ -6048,7 +6113,7 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag, spa->spa_last_open_failed = 0; spa->spa_last_ubsync_txg = 0; spa->spa_load_txg = 0; - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } if (firstopen) @@ -6081,13 +6146,13 @@ spa_inject_addref(char *name) { spa_t *spa; - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); if ((spa = spa_lookup(name)) == NULL) { - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (NULL); } spa->spa_inject_ref++; - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (spa); } @@ -6095,9 +6160,9 @@ spa_inject_addref(char *name) void spa_inject_delref(spa_t *spa) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa->spa_inject_ref--; - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } /* @@ -6341,14 +6406,14 @@ spa_get_stats(const char *name, nvlist_t **config, */ if (altroot) { if (spa == NULL) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa = spa_lookup(name); if (spa) spa_altroot(spa, altroot, buflen); else altroot[0] = '\0'; spa = NULL; - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } else { spa_altroot(spa, altroot, buflen); } @@ -6568,9 +6633,9 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, /* * If this pool already exists, return failure. */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); if (spa_lookup(poolname) != NULL) { - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (SET_ERROR(EEXIST)); } @@ -6588,7 +6653,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, if (props && (error = spa_prop_validate(spa, props))) { spa_deactivate(spa); spa_remove(spa); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (error); } @@ -6621,14 +6686,14 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, if (error != 0) { spa_deactivate(spa); spa_remove(spa); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (error); } } if (!has_allocclass && zfs_special_devs(nvroot, NULL)) { spa_deactivate(spa); spa_remove(spa); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (ENOTSUP); } @@ -6694,7 +6759,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, spa_unload(spa); spa_deactivate(spa); spa_remove(spa); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (error); } @@ -6847,7 +6912,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, spa_import_os(spa); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (0); } @@ -6872,9 +6937,9 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags) /* * If a pool with this name exists, return failure. */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); if (spa_lookup(pool) != NULL) { - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (SET_ERROR(EEXIST)); } @@ -6901,7 +6966,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags) spa_write_cachefile(spa, B_FALSE, B_TRUE, B_FALSE); spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_IMPORT); zfs_dbgmsg("spa_import: verbatim import of %s", pool); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (0); } @@ -6960,7 +7025,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags) spa_unload(spa); spa_deactivate(spa); spa_remove(spa); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (error); } @@ -7028,7 +7093,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags) spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_IMPORT); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); zvol_create_minors(pool); @@ -7060,7 +7125,7 @@ spa_tryimport(nvlist_t *tryconfig) (void) snprintf(name, MAXPATHLEN, "%s-%llx-%s", TRYIMPORT_NAME, (u_longlong_t)(uintptr_t)curthread, poolname); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa = spa_add(name, tryconfig, NULL); spa_activate(spa, SPA_MODE_READ); kmem_free(name, MAXPATHLEN); @@ -7158,7 +7223,7 @@ spa_tryimport(nvlist_t *tryconfig) spa_unload(spa); spa_deactivate(spa); spa_remove(spa); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (config); } @@ -7186,15 +7251,15 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig, if (!(spa_mode_global & SPA_MODE_WRITE)) return (SET_ERROR(EROFS)); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); if ((spa = spa_lookup(pool)) == NULL) { - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (SET_ERROR(ENOENT)); } if (spa->spa_is_exporting) { /* the pool is being exported by another thread */ - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (SET_ERROR(ZFS_ERR_EXPORT_IN_PROGRESS)); } spa->spa_is_exporting = B_TRUE; @@ -7204,18 +7269,18 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig, * and see if we can export. */ spa_open_ref(spa, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); spa_async_suspend(spa); if (spa->spa_zvol_taskq) { zvol_remove_minors(spa, spa_name(spa), B_TRUE); taskq_wait(spa->spa_zvol_taskq); } - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa->spa_export_thread = curthread; spa_close(spa, FTAG); if (spa->spa_state == POOL_STATE_UNINITIALIZED) { - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); goto export_spa; } @@ -7239,7 +7304,7 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig, goto fail; } - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); /* * At this point we no longer hold the spa_namespace_lock and * there were no references on the spa. Future spa_lookups will @@ -7258,7 +7323,7 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig, if (!force && new_state == POOL_STATE_EXPORTED && spa_has_active_shared_spare(spa)) { error = SET_ERROR(EXDEV); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); goto fail; } @@ -7333,7 +7398,7 @@ export_spa: /* * Take the namespace lock for the actual spa_t removal */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); if (new_state != POOL_STATE_UNINITIALIZED) { if (!hardforce) spa_write_cachefile(spa, B_TRUE, B_TRUE, B_FALSE); @@ -7351,8 +7416,8 @@ export_spa: /* * Wake up any waiters in spa_lookup() */ - cv_broadcast(&spa_namespace_cv); - mutex_exit(&spa_namespace_lock); + spa_namespace_broadcast(); + spa_namespace_exit(FTAG); return (0); fail: @@ -7363,8 +7428,8 @@ fail: /* * Wake up any waiters in spa_lookup() */ - cv_broadcast(&spa_namespace_cv); - mutex_exit(&spa_namespace_lock); + spa_namespace_broadcast(); + spa_namespace_exit(FTAG); return (error); } @@ -7574,10 +7639,10 @@ spa_vdev_add(spa_t *spa, nvlist_t *nvroot, boolean_t check_ashift) */ (void) spa_vdev_exit(spa, vd, txg, 0); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_config_update(spa, SPA_CONFIG_UPDATE_POOL); spa_event_notify(spa, NULL, NULL, ESC_ZFS_VDEV_ADD); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (0); } @@ -7694,7 +7759,7 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing, oldvd = spa_lookup_by_guid(spa, guid, B_FALSE); - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) { error = (spa_has_checkpoint(spa)) ? ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT; @@ -8078,7 +8143,7 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done) * as spa_vdev_resilver_done() calls this function everything * should be fine as the resilver will return right away. */ - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) { error = (spa_has_checkpoint(spa)) ? ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT; @@ -8282,28 +8347,28 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done) if (unspare) { spa_t *altspa = NULL; - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); while ((altspa = spa_next(altspa)) != NULL) { if (altspa->spa_state != POOL_STATE_ACTIVE || altspa == spa) continue; spa_open_ref(altspa, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); (void) spa_vdev_remove(altspa, unspare_guid, B_TRUE); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_close(altspa, FTAG); } - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); /* search the rest of the vdevs for spares to remove */ spa_vdev_resilver_done(spa); } /* all done with the spa; OK to release */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_close(spa, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (error); } @@ -8312,7 +8377,7 @@ static int spa_vdev_initialize_impl(spa_t *spa, uint64_t guid, uint64_t cmd_type, list_t *vd_list) { - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER); @@ -8396,7 +8461,7 @@ spa_vdev_initialize(spa_t *spa, nvlist_t *nv, uint64_t cmd_type, * we can properly assess the vdev state before we commit to * the initializing operation. */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); for (nvpair_t *pair = nvlist_next_nvpair(nv, NULL); pair != NULL; pair = nvlist_next_nvpair(nv, pair)) { @@ -8419,7 +8484,7 @@ spa_vdev_initialize(spa_t *spa, nvlist_t *nv, uint64_t cmd_type, /* Sync out the initializing state */ txg_wait_synced(spa->spa_dsl_pool, 0); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); list_destroy(&vd_list); @@ -8430,7 +8495,7 @@ static int spa_vdev_trim_impl(spa_t *spa, uint64_t guid, uint64_t cmd_type, uint64_t rate, boolean_t partial, boolean_t secure, list_t *vd_list) { - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER); @@ -8517,7 +8582,7 @@ spa_vdev_trim(spa_t *spa, nvlist_t *nv, uint64_t cmd_type, uint64_t rate, * we can properly assess the vdev state before we commit to * the TRIM operation. */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); for (nvpair_t *pair = nvlist_next_nvpair(nv, NULL); pair != NULL; pair = nvlist_next_nvpair(nv, pair)) { @@ -8540,7 +8605,7 @@ spa_vdev_trim(spa_t *spa, nvlist_t *nv, uint64_t cmd_type, uint64_t rate, /* Sync out the TRIM state */ txg_wait_synced(spa->spa_dsl_pool, 0); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); list_destroy(&vd_list); @@ -8568,7 +8633,7 @@ spa_vdev_split_mirror(spa_t *spa, const char *newname, nvlist_t *config, txg = spa_vdev_enter(spa); - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) { error = (spa_has_checkpoint(spa)) ? ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT; @@ -9242,7 +9307,7 @@ spa_async_thread(void *arg) if (tasks & SPA_ASYNC_CONFIG_UPDATE) { uint64_t old_space, new_space; - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); old_space = metaslab_class_get_space(spa_normal_class(spa)); old_space += metaslab_class_get_space(spa_special_class(spa)); old_space += metaslab_class_get_space(spa_dedup_class(spa)); @@ -9260,7 +9325,7 @@ spa_async_thread(void *arg) spa_embedded_log_class(spa)); new_space += metaslab_class_get_space( spa_special_embedded_log_class(spa)); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); /* * If the pool grew as a result of the config update, @@ -9329,49 +9394,49 @@ spa_async_thread(void *arg) dsl_scan_restart_resilver(dp, 0); if (tasks & SPA_ASYNC_INITIALIZE_RESTART) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER); vdev_initialize_restart(spa->spa_root_vdev); spa_config_exit(spa, SCL_CONFIG, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } if (tasks & SPA_ASYNC_TRIM_RESTART) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER); vdev_trim_restart(spa->spa_root_vdev); spa_config_exit(spa, SCL_CONFIG, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } if (tasks & SPA_ASYNC_AUTOTRIM_RESTART) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER); vdev_autotrim_restart(spa); spa_config_exit(spa, SCL_CONFIG, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } /* * Kick off L2 cache whole device TRIM. */ if (tasks & SPA_ASYNC_L2CACHE_TRIM) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER); vdev_trim_l2arc(spa); spa_config_exit(spa, SCL_CONFIG, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } /* * Kick off L2 cache rebuilding. */ if (tasks & SPA_ASYNC_L2CACHE_REBUILD) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_config_enter(spa, SCL_L2ARC, FTAG, RW_READER); l2arc_spa_rebuild_start(spa); spa_config_exit(spa, SCL_L2ARC, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } /* @@ -9601,7 +9666,8 @@ spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx) KM_SLEEP)); memset(packed + nvsize, 0, bufsize - nvsize); - dmu_write(spa->spa_meta_objset, obj, 0, bufsize, packed, tx); + dmu_write(spa->spa_meta_objset, obj, 0, bufsize, packed, tx, + DMU_READ_NO_PREFETCH); vmem_free(packed, bufsize); @@ -10522,18 +10588,18 @@ void spa_sync_allpools(void) { spa_t *spa = NULL; - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); while ((spa = spa_next(spa)) != NULL) { if (spa_state(spa) != POOL_STATE_ACTIVE || !spa_writeable(spa) || spa_suspended(spa)) continue; spa_open_ref(spa, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); txg_wait_synced(spa_get_dsl(spa), 0); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_close(spa, FTAG); } - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } taskq_t * @@ -10680,7 +10746,7 @@ spa_evict_all(void) * Remove all cached state. All pools should be closed now, * so every spa in the AVL tree should be unreferenced. */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); while ((spa = spa_next(NULL)) != NULL) { /* * Stop async tasks. The async thread may need to detach @@ -10688,9 +10754,9 @@ spa_evict_all(void) * spa_namespace_lock, so we must drop it here. */ spa_open_ref(spa, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); spa_async_suspend(spa); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_close(spa, FTAG); if (spa->spa_state != POOL_STATE_UNINITIALIZED) { @@ -10699,7 +10765,7 @@ spa_evict_all(void) } spa_remove(spa); } - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } vdev_t * @@ -11272,6 +11338,9 @@ ZFS_MODULE_VIRTUAL_PARAM_CALL(zfs_zio, zio_, taskq_read, ZFS_MODULE_VIRTUAL_PARAM_CALL(zfs_zio, zio_, taskq_write, spa_taskq_write_param_set, spa_taskq_write_param_get, ZMOD_RW, "Configure IO queues for write IO"); +ZFS_MODULE_VIRTUAL_PARAM_CALL(zfs_zio, zio_, taskq_free, + spa_taskq_free_param_set, spa_taskq_free_param_get, ZMOD_RW, + "Configure IO queues for free IO"); #endif ZFS_MODULE_PARAM(zfs_zio, zio_, taskq_write_tpq, UINT, ZMOD_RW, diff --git a/sys/contrib/openzfs/module/zfs/spa_checkpoint.c b/sys/contrib/openzfs/module/zfs/spa_checkpoint.c index e07756c46748..a42aa62e6599 100644 --- a/sys/contrib/openzfs/module/zfs/spa_checkpoint.c +++ b/sys/contrib/openzfs/module/zfs/spa_checkpoint.c @@ -427,7 +427,7 @@ spa_checkpoint_discard_thread(void *arg, zthr_t *zthr) */ int error = dmu_buf_hold_array_by_bonus( checkpoint_sm->sm_dbuf, offset, size, - B_TRUE, FTAG, &numbufs, &dbp); + B_TRUE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH); if (error != 0) { zfs_panic_recover("zfs: error %d was returned " "while prefetching checkpoint space map " diff --git a/sys/contrib/openzfs/module/zfs/spa_config.c b/sys/contrib/openzfs/module/zfs/spa_config.c index f615591e826b..31216e9a7ccc 100644 --- a/sys/contrib/openzfs/module/zfs/spa_config.c +++ b/sys/contrib/openzfs/module/zfs/spa_config.c @@ -161,7 +161,7 @@ spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent, boolean_t ccw_failure; int error = 0; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); if (!(spa_mode_global & SPA_MODE_WRITE)) return; @@ -287,7 +287,7 @@ spa_all_configs(uint64_t *generation, nvlist_t **pools) if (*generation == spa_config_generation) return (SET_ERROR(EEXIST)); - int error = mutex_enter_interruptible(&spa_namespace_lock); + int error = spa_namespace_enter_interruptible(FTAG); if (error) return (SET_ERROR(EINTR)); @@ -302,7 +302,7 @@ spa_all_configs(uint64_t *generation, nvlist_t **pools) } } *generation = spa_config_generation; - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (0); } @@ -483,7 +483,7 @@ spa_config_update(spa_t *spa, int what) uint64_t txg; int c; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER); txg = spa_last_synced_txg(spa) + 1; diff --git a/sys/contrib/openzfs/module/zfs/spa_history.c b/sys/contrib/openzfs/module/zfs/spa_history.c index 60ab07944d72..b9d0c9656726 100644 --- a/sys/contrib/openzfs/module/zfs/spa_history.c +++ b/sys/contrib/openzfs/module/zfs/spa_history.c @@ -169,13 +169,14 @@ spa_history_write(spa_t *spa, void *buf, uint64_t len, spa_history_phys_t *shpp, phys_eof = spa_history_log_to_phys(shpp->sh_eof, shpp); firstwrite = MIN(len, shpp->sh_phys_max_off - phys_eof); shpp->sh_eof += len; - dmu_write(mos, spa->spa_history, phys_eof, firstwrite, buf, tx); + dmu_write(mos, spa->spa_history, phys_eof, firstwrite, buf, tx, + DMU_READ_NO_PREFETCH); len -= firstwrite; if (len > 0) { /* write out the rest at the beginning of physical file */ dmu_write(mos, spa->spa_history, shpp->sh_pool_create_len, - len, (char *)buf + firstwrite, tx); + len, (char *)buf + firstwrite, tx, DMU_READ_NO_PREFETCH); } return (0); diff --git a/sys/contrib/openzfs/module/zfs/spa_misc.c b/sys/contrib/openzfs/module/zfs/spa_misc.c index 0bead6d49666..bf22d2eb68e7 100644 --- a/sys/contrib/openzfs/module/zfs/spa_misc.c +++ b/sys/contrib/openzfs/module/zfs/spa_misc.c @@ -28,7 +28,7 @@ * Copyright (c) 2017 Datto Inc. * Copyright (c) 2017, Intel Corporation. * Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. - * Copyright (c) 2023, 2024, Klara Inc. + * Copyright (c) 2023, 2024, 2025, Klara, Inc. */ #include <sys/zfs_context.h> @@ -237,9 +237,10 @@ * locking is, always, based on spa_namespace_lock and spa_config_lock[]. */ -avl_tree_t spa_namespace_avl; -kmutex_t spa_namespace_lock; -kcondvar_t spa_namespace_cv; +static avl_tree_t spa_namespace_avl; +static kmutex_t spa_namespace_lock; +static kcondvar_t spa_namespace_cv; + static const int spa_max_replication_override = SPA_DVAS_PER_BP; static kmutex_t spa_spare_lock; @@ -608,6 +609,58 @@ spa_config_held(spa_t *spa, int locks, krw_t rw) * ========================================================================== */ +void +spa_namespace_enter(const void *tag) +{ + (void) tag; + ASSERT(!MUTEX_HELD(&spa_namespace_lock)); + mutex_enter(&spa_namespace_lock); +} + +boolean_t +spa_namespace_tryenter(const void *tag) +{ + (void) tag; + ASSERT(!MUTEX_HELD(&spa_namespace_lock)); + return (mutex_tryenter(&spa_namespace_lock)); +} + +int +spa_namespace_enter_interruptible(const void *tag) +{ + (void) tag; + ASSERT(!MUTEX_HELD(&spa_namespace_lock)); + return (mutex_enter_interruptible(&spa_namespace_lock)); +} + +void +spa_namespace_exit(const void *tag) +{ + (void) tag; + ASSERT(MUTEX_HELD(&spa_namespace_lock)); + mutex_exit(&spa_namespace_lock); +} + +boolean_t +spa_namespace_held(void) +{ + return (MUTEX_HELD(&spa_namespace_lock)); +} + +void +spa_namespace_wait(void) +{ + ASSERT(MUTEX_HELD(&spa_namespace_lock)); + cv_wait(&spa_namespace_cv, &spa_namespace_lock); +} + +void +spa_namespace_broadcast(void) +{ + ASSERT(MUTEX_HELD(&spa_namespace_lock)); + cv_broadcast(&spa_namespace_cv); +} + /* * Lookup the named spa_t in the AVL tree. The spa_namespace_lock must be held. * Returns NULL if no matching spa_t is found. @@ -620,7 +673,7 @@ spa_lookup(const char *name) avl_index_t where; char *cp; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); retry: (void) strlcpy(search.spa_name, name, sizeof (search.spa_name)); @@ -645,7 +698,7 @@ retry: spa->spa_load_thread != curthread) || (spa->spa_export_thread != NULL && spa->spa_export_thread != curthread)) { - cv_wait(&spa_namespace_cv, &spa_namespace_lock); + spa_namespace_wait(); goto retry; } @@ -697,7 +750,7 @@ spa_add(const char *name, nvlist_t *config, const char *altroot) spa_t *spa; spa_config_dirent_t *dp; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); spa = kmem_zalloc(sizeof (spa_t), KM_SLEEP); @@ -747,7 +800,7 @@ spa_add(const char *name, nvlist_t *config, const char *altroot) spa_config_lock_init(spa); spa_stats_init(spa); - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); avl_add(&spa_namespace_avl, spa); /* @@ -837,7 +890,7 @@ spa_remove(spa_t *spa) { spa_config_dirent_t *dp; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); ASSERT(spa_state(spa) == POOL_STATE_UNINITIALIZED); ASSERT3U(zfs_refcount_count(&spa->spa_refcount), ==, 0); ASSERT0(spa->spa_waiters); @@ -916,7 +969,7 @@ spa_remove(spa_t *spa) spa_t * spa_next(spa_t *prev) { - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); if (prev) return (AVL_NEXT(&spa_namespace_avl, prev)); @@ -938,7 +991,7 @@ void spa_open_ref(spa_t *spa, const void *tag) { ASSERT(zfs_refcount_count(&spa->spa_refcount) >= spa->spa_minref || - MUTEX_HELD(&spa_namespace_lock) || + spa_namespace_held() || spa->spa_load_thread == curthread); (void) zfs_refcount_add(&spa->spa_refcount, tag); } @@ -951,7 +1004,7 @@ void spa_close(spa_t *spa, const void *tag) { ASSERT(zfs_refcount_count(&spa->spa_refcount) > spa->spa_minref || - MUTEX_HELD(&spa_namespace_lock) || + spa_namespace_held() || spa->spa_load_thread == curthread || spa->spa_export_thread == curthread); (void) zfs_refcount_remove(&spa->spa_refcount, tag); @@ -980,7 +1033,7 @@ spa_async_close(spa_t *spa, const void *tag) boolean_t spa_refcount_zero(spa_t *spa) { - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || spa->spa_export_thread == curthread); return (zfs_refcount_count(&spa->spa_refcount) == spa->spa_minref); @@ -1227,7 +1280,7 @@ uint64_t spa_vdev_enter(spa_t *spa) { mutex_enter(&spa->spa_vdev_top_lock); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); ASSERT0(spa->spa_export_thread); @@ -1246,7 +1299,7 @@ uint64_t spa_vdev_detach_enter(spa_t *spa, uint64_t guid) { mutex_enter(&spa->spa_vdev_top_lock); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); ASSERT0(spa->spa_export_thread); @@ -1270,7 +1323,7 @@ spa_vdev_detach_enter(spa_t *spa, uint64_t guid) uint64_t spa_vdev_config_enter(spa_t *spa) { - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); spa_config_enter(spa, SCL_ALL, spa, RW_WRITER); @@ -1285,7 +1338,7 @@ void spa_vdev_config_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error, const char *tag) { - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); int config_changed = B_FALSE; @@ -1374,7 +1427,7 @@ spa_vdev_exit(spa_t *spa, vdev_t *vd, uint64_t txg, int error) vdev_rebuild_restart(spa); spa_vdev_config_exit(spa, vd, txg, error, FTAG); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); mutex_exit(&spa->spa_vdev_top_lock); return (error); @@ -1452,9 +1505,9 @@ spa_vdev_state_exit(spa_t *spa, vdev_t *vd, int error) * If the config changed, update the config cache. */ if (config_changed) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa_write_cachefile(spa, B_FALSE, B_TRUE, B_FALSE); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } return (error); @@ -1501,7 +1554,7 @@ spa_by_guid(uint64_t pool_guid, uint64_t device_guid) spa_t *spa; avl_tree_t *t = &spa_namespace_avl; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); for (spa = avl_first(t); spa != NULL; spa = AVL_NEXT(t, spa)) { if (spa->spa_state == POOL_STATE_UNINITIALIZED) @@ -1583,7 +1636,7 @@ spa_load_guid_exists(uint64_t guid) { avl_tree_t *t = &spa_namespace_avl; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); for (spa_t *spa = avl_first(t); spa != NULL; spa = AVL_NEXT(t, spa)) { if (spa_load_guid(spa) == guid) @@ -2200,10 +2253,10 @@ spa_set_deadman_ziotime(hrtime_t ns) spa_t *spa = NULL; if (spa_mode_global != SPA_MODE_UNINIT) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); while ((spa = spa_next(spa)) != NULL) spa->spa_deadman_ziotime = ns; - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } } @@ -2213,10 +2266,10 @@ spa_set_deadman_synctime(hrtime_t ns) spa_t *spa = NULL; if (spa_mode_global != SPA_MODE_UNINIT) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); while ((spa = spa_next(spa)) != NULL) spa->spa_deadman_synctime = ns; - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } } @@ -3048,10 +3101,10 @@ param_set_deadman_failmode_common(const char *val) return (SET_ERROR(EINVAL)); if (spa_mode_global != SPA_MODE_UNINIT) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); while ((spa = spa_next(spa)) != NULL) spa_set_deadman_failmode(spa, val); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } return (0); @@ -3135,7 +3188,6 @@ EXPORT_SYMBOL(spa_has_slogs); EXPORT_SYMBOL(spa_is_root); EXPORT_SYMBOL(spa_writeable); EXPORT_SYMBOL(spa_mode); -EXPORT_SYMBOL(spa_namespace_lock); EXPORT_SYMBOL(spa_trust_config); EXPORT_SYMBOL(spa_missing_tvds_allowed); EXPORT_SYMBOL(spa_set_missing_tvds); diff --git a/sys/contrib/openzfs/module/zfs/space_map.c b/sys/contrib/openzfs/module/zfs/space_map.c index 5f24963f2291..f20c49ebb6de 100644 --- a/sys/contrib/openzfs/module/zfs/space_map.c +++ b/sys/contrib/openzfs/module/zfs/space_map.c @@ -537,7 +537,7 @@ space_map_write_intro_debug(space_map_t *sm, maptype_t maptype, dmu_tx_t *tx) SM_DEBUG_TXG_ENCODE(dmu_tx_get_txg(tx)); dmu_write(sm->sm_os, space_map_object(sm), sm->sm_phys->smp_length, - sizeof (dentry), &dentry, tx); + sizeof (dentry), &dentry, tx, DMU_READ_NO_PREFETCH); sm->sm_phys->smp_length += sizeof (dentry); } diff --git a/sys/contrib/openzfs/module/zfs/vdev.c b/sys/contrib/openzfs/module/zfs/vdev.c index c8d7280387a2..2a4d1876251f 100644 --- a/sys/contrib/openzfs/module/zfs/vdev.c +++ b/sys/contrib/openzfs/module/zfs/vdev.c @@ -449,32 +449,53 @@ vdev_get_nparity(vdev_t *vd) } static int -vdev_prop_get_int(vdev_t *vd, vdev_prop_t prop, uint64_t *value) +vdev_prop_get_objid(vdev_t *vd, uint64_t *objid) { - spa_t *spa = vd->vdev_spa; - objset_t *mos = spa->spa_meta_objset; - uint64_t objid; - int err; if (vd->vdev_root_zap != 0) { - objid = vd->vdev_root_zap; + *objid = vd->vdev_root_zap; } else if (vd->vdev_top_zap != 0) { - objid = vd->vdev_top_zap; + *objid = vd->vdev_top_zap; } else if (vd->vdev_leaf_zap != 0) { - objid = vd->vdev_leaf_zap; + *objid = vd->vdev_leaf_zap; } else { return (EINVAL); } + return (0); +} + +static int +vdev_prop_get_int(vdev_t *vd, vdev_prop_t prop, uint64_t *value) +{ + spa_t *spa = vd->vdev_spa; + objset_t *mos = spa->spa_meta_objset; + uint64_t objid; + int err; + + if (vdev_prop_get_objid(vd, &objid) != 0) + return (EINVAL); + err = zap_lookup(mos, objid, vdev_prop_to_name(prop), sizeof (uint64_t), 1, value); - if (err == ENOENT) *value = vdev_prop_default_numeric(prop); return (err); } +static int +vdev_prop_get_bool(vdev_t *vd, vdev_prop_t prop, boolean_t *bvalue) +{ + int err; + uint64_t ivalue; + + err = vdev_prop_get_int(vd, prop, &ivalue); + *bvalue = ivalue != 0; + + return (err); +} + /* * Get the number of data disks for a top-level vdev. */ @@ -737,8 +758,12 @@ vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops) */ vd->vdev_checksum_n = vdev_prop_default_numeric(VDEV_PROP_CHECKSUM_N); vd->vdev_checksum_t = vdev_prop_default_numeric(VDEV_PROP_CHECKSUM_T); + vd->vdev_io_n = vdev_prop_default_numeric(VDEV_PROP_IO_N); vd->vdev_io_t = vdev_prop_default_numeric(VDEV_PROP_IO_T); + + vd->vdev_slow_io_events = vdev_prop_default_numeric( + VDEV_PROP_SLOW_IO_EVENTS); vd->vdev_slow_io_n = vdev_prop_default_numeric(VDEV_PROP_SLOW_IO_N); vd->vdev_slow_io_t = vdev_prop_default_numeric(VDEV_PROP_SLOW_IO_T); @@ -3931,6 +3956,11 @@ vdev_load(vdev_t *vd) vdev_dbgmsg(vd, "vdev_load: zap_lookup(zap=%llu) " "failed [error=%d]", (u_longlong_t)zapobj, error); + error = vdev_prop_get_bool(vd, VDEV_PROP_SLOW_IO_EVENTS, + &vd->vdev_slow_io_events); + if (error && error != ENOENT) + vdev_dbgmsg(vd, "vdev_load: zap_lookup(zap=%llu) " + "failed [error=%d]", (u_longlong_t)zapobj, error); error = vdev_prop_get_int(vd, VDEV_PROP_SLOW_IO_N, &vd->vdev_slow_io_n); if (error && error != ENOENT) @@ -5980,15 +6010,8 @@ vdev_props_set_sync(void *arg, dmu_tx_t *tx) /* * Set vdev property values in the vdev props mos object. */ - if (vd->vdev_root_zap != 0) { - objid = vd->vdev_root_zap; - } else if (vd->vdev_top_zap != 0) { - objid = vd->vdev_top_zap; - } else if (vd->vdev_leaf_zap != 0) { - objid = vd->vdev_leaf_zap; - } else { + if (vdev_prop_get_objid(vd, &objid) != 0) panic("unexpected vdev type"); - } mutex_enter(&spa->spa_props_lock); @@ -6215,6 +6238,13 @@ vdev_prop_set(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl) } vd->vdev_io_t = intval; break; + case VDEV_PROP_SLOW_IO_EVENTS: + if (nvpair_value_uint64(elem, &intval) != 0) { + error = EINVAL; + break; + } + vd->vdev_slow_io_events = intval != 0; + break; case VDEV_PROP_SLOW_IO_N: if (nvpair_value_uint64(elem, &intval) != 0) { error = EINVAL; @@ -6256,6 +6286,7 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl) nvpair_t *elem = NULL; nvlist_t *nvprops = NULL; uint64_t intval = 0; + boolean_t boolval = 0; char *strval = NULL; const char *propname = NULL; vdev_prop_t prop; @@ -6269,15 +6300,8 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl) nvlist_lookup_nvlist(innvl, ZPOOL_VDEV_PROPS_GET_PROPS, &nvprops); - if (vd->vdev_root_zap != 0) { - objid = vd->vdev_root_zap; - } else if (vd->vdev_top_zap != 0) { - objid = vd->vdev_top_zap; - } else if (vd->vdev_leaf_zap != 0) { - objid = vd->vdev_leaf_zap; - } else { + if (vdev_prop_get_objid(vd, &objid) != 0) return (SET_ERROR(EINVAL)); - } ASSERT(objid != 0); mutex_enter(&spa->spa_props_lock); @@ -6622,6 +6646,18 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl) intval, src); break; + case VDEV_PROP_SLOW_IO_EVENTS: + err = vdev_prop_get_bool(vd, prop, &boolval); + if (err && err != ENOENT) + break; + + src = ZPROP_SRC_LOCAL; + if (boolval == vdev_prop_default_numeric(prop)) + src = ZPROP_SRC_DEFAULT; + + vdev_prop_add_list(outnvl, propname, NULL, + boolval, src); + break; case VDEV_PROP_CHECKSUM_N: case VDEV_PROP_CHECKSUM_T: case VDEV_PROP_IO_N: diff --git a/sys/contrib/openzfs/module/zfs/vdev_indirect_births.c b/sys/contrib/openzfs/module/zfs/vdev_indirect_births.c index c0127829c26c..ab7069f44b37 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_indirect_births.c +++ b/sys/contrib/openzfs/module/zfs/vdev_indirect_births.c @@ -147,7 +147,7 @@ vdev_indirect_births_add_entry(vdev_indirect_births_t *vib, old_size = vdev_indirect_births_size_impl(vib); dmu_write(vib->vib_objset, vib->vib_object, old_size, sizeof (vibe), - &vibe, tx); + &vibe, tx, DMU_READ_NO_PREFETCH); vib->vib_phys->vib_count++; new_size = vdev_indirect_births_size_impl(vib); diff --git a/sys/contrib/openzfs/module/zfs/vdev_indirect_mapping.c b/sys/contrib/openzfs/module/zfs/vdev_indirect_mapping.c index 1515ddc1baa2..da90a8de016f 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_indirect_mapping.c +++ b/sys/contrib/openzfs/module/zfs/vdev_indirect_mapping.c @@ -459,13 +459,14 @@ vdev_indirect_mapping_add_entries(vdev_indirect_mapping_t *vim, dmu_write(vim->vim_objset, vim->vim_object, vim->vim_phys->vimp_num_entries * sizeof (*mapbuf), i * sizeof (*mapbuf), - mapbuf, tx); + mapbuf, tx, DMU_READ_NO_PREFETCH); if (vim->vim_havecounts) { dmu_write(vim->vim_objset, vim->vim_phys->vimp_counts_object, vim->vim_phys->vimp_num_entries * sizeof (*countbuf), - i * sizeof (*countbuf), countbuf, tx); + i * sizeof (*countbuf), countbuf, tx, + DMU_READ_NO_PREFETCH); } vim->vim_phys->vimp_num_entries += i; } diff --git a/sys/contrib/openzfs/module/zfs/vdev_initialize.c b/sys/contrib/openzfs/module/zfs/vdev_initialize.c index 27188c46e561..d13da1e5a663 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_initialize.c +++ b/sys/contrib/openzfs/module/zfs/vdev_initialize.c @@ -685,7 +685,7 @@ vdev_initialize_stop_wait(spa_t *spa, list_t *vd_list) (void) spa; vdev_t *vd; - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || spa->spa_export_thread == curthread); while ((vd = list_remove_head(vd_list)) != NULL) { @@ -728,7 +728,7 @@ vdev_initialize_stop(vdev_t *vd, vdev_initializing_state_t tgt_state, if (vd_list == NULL) { vdev_initialize_stop_wait_impl(vd); } else { - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || vd->vdev_spa->spa_export_thread == curthread); list_insert_tail(vd_list, vd); } @@ -761,7 +761,7 @@ vdev_initialize_stop_all(vdev_t *vd, vdev_initializing_state_t tgt_state) spa_t *spa = vd->vdev_spa; list_t vd_list; - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || spa->spa_export_thread == curthread); list_create(&vd_list, sizeof (vdev_t), @@ -781,7 +781,7 @@ vdev_initialize_stop_all(vdev_t *vd, vdev_initializing_state_t tgt_state) void vdev_initialize_restart(vdev_t *vd) { - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || vd->vdev_spa->spa_load_thread == curthread); ASSERT(!spa_config_held(vd->vdev_spa, SCL_ALL, RW_WRITER)); diff --git a/sys/contrib/openzfs/module/zfs/vdev_label.c b/sys/contrib/openzfs/module/zfs/vdev_label.c index 0d4fdaa77ba0..7e222eac5edc 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_label.c +++ b/sys/contrib/openzfs/module/zfs/vdev_label.c @@ -862,8 +862,8 @@ retry: } } - if (config == NULL && !(flags & ZIO_FLAG_TRYHARD)) { - flags |= ZIO_FLAG_TRYHARD; + if (config == NULL && !(flags & ZIO_FLAG_IO_RETRY)) { + flags |= ZIO_FLAG_IO_RETRY; goto retry; } @@ -1079,7 +1079,8 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) size_t buflen; int error; uint64_t spare_guid = 0, l2cache_guid = 0; - int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL; + int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL | + ZIO_FLAG_TRYHARD; boolean_t reason_spare = (reason == VDEV_LABEL_SPARE || (reason == VDEV_LABEL_REMOVE && vd->vdev_isspare)); boolean_t reason_l2cache = (reason == VDEV_LABEL_L2CACHE || (reason == @@ -1223,7 +1224,6 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) /* * Write everything in parallel. */ -retry: zio = zio_root(spa, NULL, NULL, flags); for (int l = 0; l < VDEV_LABELS; l++) { @@ -1248,11 +1248,6 @@ retry: error = zio_wait(zio); - if (error != 0 && !(flags & ZIO_FLAG_TRYHARD)) { - flags |= ZIO_FLAG_TRYHARD; - goto retry; - } - nvlist_free(label); abd_free(bootenv); abd_free(ub_abd); @@ -1398,7 +1393,8 @@ vdev_label_write_bootenv(vdev_t *vd, nvlist_t *env) zio_t *zio; spa_t *spa = vd->vdev_spa; vdev_boot_envblock_t *bootenv; - int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL; + int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL | + ZIO_FLAG_TRYHARD; int error; size_t nvsize; char *nvbuf; @@ -1466,7 +1462,6 @@ vdev_label_write_bootenv(vdev_t *vd, nvlist_t *env) return (SET_ERROR(error)); } -retry: zio = zio_root(spa, NULL, NULL, flags); for (int l = 0; l < VDEV_LABELS; l++) { vdev_label_write(zio, vd, l, abd, @@ -1475,10 +1470,6 @@ retry: } error = zio_wait(zio); - if (error != 0 && !(flags & ZIO_FLAG_TRYHARD)) { - flags |= ZIO_FLAG_TRYHARD; - goto retry; - } abd_free(abd); return (error); @@ -2056,13 +2047,13 @@ retry: * Normally, we don't want to try too hard to write every label and * uberblock. If there is a flaky disk, we don't want the rest of the * sync process to block while we retry. But if we can't write a - * single label out, we should retry with ZIO_FLAG_TRYHARD before + * single label out, we should retry with ZIO_FLAG_IO_RETRY before * bailing out and declaring the pool faulted. */ if (error != 0) { - if ((flags & ZIO_FLAG_TRYHARD) != 0) + if ((flags & ZIO_FLAG_IO_RETRY) != 0) return (error); - flags |= ZIO_FLAG_TRYHARD; + flags |= ZIO_FLAG_IO_RETRY; } ASSERT(ub->ub_txg <= txg); @@ -2113,7 +2104,7 @@ retry: * are committed to stable storage before the uberblock update. */ if ((error = vdev_label_sync_list(spa, 0, txg, flags)) != 0) { - if ((flags & ZIO_FLAG_TRYHARD) != 0) { + if ((flags & ZIO_FLAG_IO_RETRY) != 0) { zfs_dbgmsg("vdev_label_sync_list() returned error %d " "for pool '%s' when syncing out the even labels " "of dirty vdevs", error, spa_name(spa)); @@ -2137,7 +2128,7 @@ retry: * to the new uberblocks. */ if ((error = vdev_uberblock_sync_list(svd, svdcount, ub, flags)) != 0) { - if ((flags & ZIO_FLAG_TRYHARD) != 0) { + if ((flags & ZIO_FLAG_IO_RETRY) != 0) { zfs_dbgmsg("vdev_uberblock_sync_list() returned error " "%d for pool '%s'", error, spa_name(spa)); } @@ -2158,7 +2149,7 @@ retry: * stable storage before the next transaction group begins. */ if ((error = vdev_label_sync_list(spa, 1, txg, flags)) != 0) { - if ((flags & ZIO_FLAG_TRYHARD) != 0) { + if ((flags & ZIO_FLAG_IO_RETRY) != 0) { zfs_dbgmsg("vdev_label_sync_list() returned error %d " "for pool '%s' when syncing out the odd labels of " "dirty vdevs", error, spa_name(spa)); diff --git a/sys/contrib/openzfs/module/zfs/vdev_raidz.c b/sys/contrib/openzfs/module/zfs/vdev_raidz.c index 56b8e3b60b22..5fe70ec2b1d5 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_raidz.c +++ b/sys/contrib/openzfs/module/zfs/vdev_raidz.c @@ -4872,7 +4872,7 @@ spa_raidz_expand_thread(void *arg, zthr_t *zthr) else vre->vre_offset = RRSS_GET_OFFSET(&spa->spa_ubsync); - /* Reflow the begining portion using the scratch area */ + /* Reflow the beginning portion using the scratch area */ if (vre->vre_offset == 0) { VERIFY0(dsl_sync_task(spa_name(spa), NULL, raidz_reflow_scratch_sync, diff --git a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c index 47b3b9921abe..30be1f851eb3 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_rebuild.c +++ b/sys/contrib/openzfs/module/zfs/vdev_rebuild.c @@ -1079,7 +1079,7 @@ vdev_rebuild_restart_impl(vdev_t *vd) void vdev_rebuild_restart(spa_t *spa) { - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || spa->spa_load_thread == curthread); vdev_rebuild_restart_impl(spa->spa_root_vdev); @@ -1094,7 +1094,7 @@ vdev_rebuild_stop_wait(vdev_t *vd) { spa_t *spa = vd->vdev_spa; - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || spa->spa_export_thread == curthread); if (vd == spa->spa_root_vdev) { diff --git a/sys/contrib/openzfs/module/zfs/vdev_removal.c b/sys/contrib/openzfs/module/zfs/vdev_removal.c index abb71543e3ab..81e6ecb68ff1 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_removal.c +++ b/sys/contrib/openzfs/module/zfs/vdev_removal.c @@ -309,12 +309,12 @@ spa_vdev_noalloc(spa_t *spa, uint64_t guid) uint64_t txg; int error = 0; - ASSERT(!MUTEX_HELD(&spa_namespace_lock)); + ASSERT(!spa_namespace_held()); ASSERT(spa_writeable(spa)); txg = spa_vdev_enter(spa); - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); vd = spa_lookup_by_guid(spa, guid, B_FALSE); @@ -342,12 +342,12 @@ spa_vdev_alloc(spa_t *spa, uint64_t guid) uint64_t txg; int error = 0; - ASSERT(!MUTEX_HELD(&spa_namespace_lock)); + ASSERT(!spa_namespace_held()); ASSERT(spa_writeable(spa)); txg = spa_vdev_enter(spa); - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); vd = spa_lookup_by_guid(spa, guid, B_FALSE); @@ -2085,7 +2085,7 @@ vdev_remove_make_hole_and_free(vdev_t *vd) spa_t *spa = vd->vdev_spa; vdev_t *rvd = spa->spa_root_vdev; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); vdev_free(vd); @@ -2113,7 +2113,7 @@ spa_vdev_remove_log(vdev_t *vd, uint64_t *txg) ASSERT(vd->vdev_islog); ASSERT(vd == vd->vdev_top); ASSERT0P(vd->vdev_log_mg); - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); /* * Stop allocating from this vdev. @@ -2140,7 +2140,7 @@ spa_vdev_remove_log(vdev_t *vd, uint64_t *txg) * spa_namespace_lock held. Once this completes the device * should no longer have any blocks allocated on it. */ - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); if (vd->vdev_stat.vs_alloc != 0) error = spa_reset_logs(spa); @@ -2189,7 +2189,7 @@ spa_vdev_remove_log(vdev_t *vd, uint64_t *txg) sysevent_t *ev = spa_event_create(spa, vd, NULL, ESC_ZFS_VDEV_REMOVE_DEV); - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); /* The top ZAP should have been destroyed by vdev_remove_empty. */ @@ -2433,7 +2433,7 @@ spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare) uint64_t txg = 0; uint_t nspares, nl2cache; int error = 0, error_log; - boolean_t locked = MUTEX_HELD(&spa_namespace_lock); + boolean_t locked = spa_namespace_held(); sysevent_t *ev = NULL; const char *vd_type = NULL; char *vd_path = NULL; @@ -2443,7 +2443,7 @@ spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare) if (!locked) txg = spa_vdev_enter(spa); - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) { error = (spa_has_checkpoint(spa)) ? ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT; diff --git a/sys/contrib/openzfs/module/zfs/vdev_trim.c b/sys/contrib/openzfs/module/zfs/vdev_trim.c index eee18b367909..a97f6650a81c 100644 --- a/sys/contrib/openzfs/module/zfs/vdev_trim.c +++ b/sys/contrib/openzfs/module/zfs/vdev_trim.c @@ -1045,7 +1045,7 @@ vdev_trim_stop_wait(spa_t *spa, list_t *vd_list) (void) spa; vdev_t *vd; - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || spa->spa_export_thread == curthread); while ((vd = list_remove_head(vd_list)) != NULL) { @@ -1085,7 +1085,7 @@ vdev_trim_stop(vdev_t *vd, vdev_trim_state_t tgt_state, list_t *vd_list) if (vd_list == NULL) { vdev_trim_stop_wait_impl(vd); } else { - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || vd->vdev_spa->spa_export_thread == curthread); list_insert_tail(vd_list, vd); } @@ -1122,7 +1122,7 @@ vdev_trim_stop_all(vdev_t *vd, vdev_trim_state_t tgt_state) list_t vd_list; vdev_t *vd_l2cache; - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || spa->spa_export_thread == curthread); list_create(&vd_list, sizeof (vdev_t), @@ -1156,7 +1156,7 @@ vdev_trim_stop_all(vdev_t *vd, vdev_trim_state_t tgt_state) void vdev_trim_restart(vdev_t *vd) { - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || vd->vdev_spa->spa_load_thread == curthread); ASSERT(!spa_config_held(vd->vdev_spa, SCL_ALL, RW_WRITER)); @@ -1582,7 +1582,7 @@ vdev_autotrim_stop_all(spa_t *spa) void vdev_autotrim_restart(spa_t *spa) { - ASSERT(MUTEX_HELD(&spa_namespace_lock) || + ASSERT(spa_namespace_held() || spa->spa_load_thread == curthread); if (spa->spa_autotrim) vdev_autotrim(spa); @@ -1689,7 +1689,7 @@ vdev_trim_l2arc_thread(void *arg) void vdev_trim_l2arc(spa_t *spa) { - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); /* * Locate the spa's l2arc devices and kick off TRIM threads. diff --git a/sys/contrib/openzfs/module/zfs/zap_micro.c b/sys/contrib/openzfs/module/zfs/zap_micro.c index ea4e3117a8b9..7e9e625a193e 100644 --- a/sys/contrib/openzfs/module/zfs/zap_micro.c +++ b/sys/contrib/openzfs/module/zfs/zap_micro.c @@ -625,12 +625,10 @@ zap_lockdir_impl(dnode_t *dn, dmu_buf_t *db, const void *tag, dmu_tx_t *tx, ASSERT0(db->db_offset); objset_t *os = dmu_buf_get_objset(db); uint64_t obj = db->db_object; - dmu_object_info_t doi; *zapp = NULL; - dmu_object_info_from_dnode(dn, &doi); - if (DMU_OT_BYTESWAP(doi.doi_type) != DMU_BSWAP_ZAP) + if (DMU_OT_BYTESWAP(dn->dn_type) != DMU_BSWAP_ZAP) return (SET_ERROR(EINVAL)); zap_t *zap = dmu_buf_get_user(db); diff --git a/sys/contrib/openzfs/module/zfs/zfs_fm.c b/sys/contrib/openzfs/module/zfs/zfs_fm.c index 221f24e381dc..4a0d41c24eed 100644 --- a/sys/contrib/openzfs/module/zfs/zfs_fm.c +++ b/sys/contrib/openzfs/module/zfs/zfs_fm.c @@ -223,6 +223,9 @@ vdev_prop_get_inherited(vdev_t *vd, vdev_prop_t prop) case VDEV_PROP_IO_T: propval = vd->vdev_io_t; break; + case VDEV_PROP_SLOW_IO_EVENTS: + propval = vd->vdev_slow_io_events; + break; case VDEV_PROP_SLOW_IO_N: propval = vd->vdev_slow_io_n; break; @@ -1580,10 +1583,10 @@ zfs_ereport_zvol_post(const char *subclass, const char *name, nvlist_t *aux; char *r; - boolean_t locked = mutex_owned(&spa_namespace_lock); - if (!locked) mutex_enter(&spa_namespace_lock); + boolean_t locked = spa_namespace_held(); + if (!locked) spa_namespace_enter(FTAG); spa_t *spa = spa_lookup(name); - if (!locked) mutex_exit(&spa_namespace_lock); + if (!locked) spa_namespace_exit(FTAG); if (spa == NULL) return; diff --git a/sys/contrib/openzfs/module/zfs/zfs_fuid.c b/sys/contrib/openzfs/module/zfs/zfs_fuid.c index 2af1efe82e62..aa10741ba870 100644 --- a/sys/contrib/openzfs/module/zfs/zfs_fuid.c +++ b/sys/contrib/openzfs/module/zfs/zfs_fuid.c @@ -28,8 +28,8 @@ #include <sys/avl.h> #include <sys/zap.h> #include <sys/nvpair.h> -#ifdef _KERNEL #include <sys/sid.h> +#ifdef _KERNEL #include <sys/zfs_vfsops.h> #include <sys/zfs_znode.h> #endif @@ -268,7 +268,7 @@ zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx) nvlist_free(nvp); zfsvfs->z_fuid_size = nvsize; dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0, - zfsvfs->z_fuid_size, packed, tx); + zfsvfs->z_fuid_size, packed, tx, DMU_READ_NO_PREFETCH); kmem_free(packed, zfsvfs->z_fuid_size); VERIFY0(dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj, FTAG, &db)); dmu_buf_will_dirty(db, tx); diff --git a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c index 5ca7c2320c4e..1b2392aeaa85 100644 --- a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c +++ b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c @@ -212,6 +212,8 @@ #include <sys/vdev_impl.h> #include <sys/vdev_initialize.h> #include <sys/vdev_trim.h> +#include <sys/brt.h> +#include <sys/ddt.h> #include "zfs_namecheck.h" #include "zfs_prop.h" @@ -3122,12 +3124,12 @@ zfs_ioc_pool_set_props(zfs_cmd_t *zc) if (pair != NULL && strcmp(nvpair_name(pair), zpool_prop_to_name(ZPOOL_PROP_CACHEFILE)) == 0 && nvlist_next_nvpair(props, pair) == NULL) { - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); if ((spa = spa_lookup(zc->zc_name)) != NULL) { spa_configfile_set(spa, props, B_FALSE); spa_write_cachefile(spa, B_FALSE, B_TRUE, B_FALSE); } - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); if (spa != NULL) { nvlist_free(props); return (0); @@ -3176,14 +3178,14 @@ zfs_ioc_pool_get_props(const char *pool, nvlist_t *innvl, nvlist_t *outnvl) * get (such as altroot and cachefile), so attempt to get them * anyway. */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); if ((spa = spa_lookup(pool)) != NULL) { error = spa_prop_get(spa, outnvl); if (error == 0 && props != NULL) error = spa_prop_get_nvlist(spa, props, n_props, outnvl); } - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); } else { error = spa_prop_get(spa, outnvl); if (error == 0 && props != NULL) @@ -4276,13 +4278,11 @@ zfs_ioc_pool_prefetch(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl) spa_t *spa; int32_t type; - /* - * Currently, only ZPOOL_PREFETCH_DDT is supported - */ - if (nvlist_lookup_int32(innvl, ZPOOL_PREFETCH_TYPE, &type) != 0 || - type != ZPOOL_PREFETCH_DDT) { + if (nvlist_lookup_int32(innvl, ZPOOL_PREFETCH_TYPE, &type) != 0) + return (EINVAL); + + if (type != ZPOOL_PREFETCH_DDT && type != ZPOOL_PREFETCH_BRT) return (EINVAL); - } error = spa_open(poolname, &spa, FTAG); if (error != 0) @@ -4290,10 +4290,17 @@ zfs_ioc_pool_prefetch(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl) hrtime_t start_time = gethrtime(); - ddt_prefetch_all(spa); - - zfs_dbgmsg("pool '%s': loaded ddt into ARC in %llu ms", spa->spa_name, - (u_longlong_t)NSEC2MSEC(gethrtime() - start_time)); + if (type == ZPOOL_PREFETCH_DDT) { + ddt_prefetch_all(spa); + zfs_dbgmsg("pool '%s': loaded ddt into ARC in %llu ms", + spa->spa_name, + (u_longlong_t)NSEC2MSEC(gethrtime() - start_time)); + } else { + brt_prefetch_all(spa); + zfs_dbgmsg("pool '%s': loaded brt into ARC in %llu ms", + spa->spa_name, + (u_longlong_t)NSEC2MSEC(gethrtime() - start_time)); + } spa_close(spa, FTAG); @@ -6121,10 +6128,10 @@ zfs_ioc_clear(zfs_cmd_t *zc) /* * On zpool clear we also fix up missing slogs */ - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); spa = spa_lookup(zc->zc_name); if (spa == NULL) { - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (SET_ERROR(EIO)); } if (spa_get_log_state(spa) == SPA_LOG_MISSING) { @@ -6132,7 +6139,7 @@ zfs_ioc_clear(zfs_cmd_t *zc) spa_set_log_state(spa, SPA_LOG_CLEAR); } spa->spa_last_open_failed = 0; - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); if (zc->zc_cookie & ZPOOL_NO_REWIND) { error = spa_open(zc->zc_name, &spa, FTAG); diff --git a/sys/contrib/openzfs/module/zfs/zio.c b/sys/contrib/openzfs/module/zfs/zio.c index aeea58bedfe4..74373f759cec 100644 --- a/sys/contrib/openzfs/module/zfs/zio.c +++ b/sys/contrib/openzfs/module/zfs/zio.c @@ -3318,8 +3318,8 @@ zio_write_gang_block(zio_t *pio, metaslab_class_t *mc) } else if (any_failed && candidate > SPA_OLD_GANGBLOCKSIZE && spa_feature_is_enabled(spa, SPA_FEATURE_DYNAMIC_GANG_HEADER) && !spa_feature_is_active(spa, SPA_FEATURE_DYNAMIC_GANG_HEADER)) { - dmu_tx_t *tx = - dmu_tx_create_assigned(spa->spa_dsl_pool, txg + 1); + dmu_tx_t *tx = dmu_tx_create_assigned(spa->spa_dsl_pool, + MAX(txg, spa_syncing_txg(spa) + 1)); dsl_sync_task_nowait(spa->spa_dsl_pool, zio_update_feature, (void *)SPA_FEATURE_DYNAMIC_GANG_HEADER, tx); @@ -5569,9 +5569,12 @@ zio_done(zio_t *zio) zio->io_vd->vdev_stat.vs_slow_ios++; mutex_exit(&zio->io_vd->vdev_stat_lock); - (void) zfs_ereport_post(FM_EREPORT_ZFS_DELAY, - zio->io_spa, zio->io_vd, &zio->io_bookmark, - zio, 0); + if (zio->io_vd->vdev_slow_io_events) { + (void) zfs_ereport_post( + FM_EREPORT_ZFS_DELAY, + zio->io_spa, zio->io_vd, + &zio->io_bookmark, zio, 0); + } } } } diff --git a/sys/contrib/openzfs/module/zfs/zio_inject.c b/sys/contrib/openzfs/module/zfs/zio_inject.c index 287577018ed1..c3adfdab54ce 100644 --- a/sys/contrib/openzfs/module/zfs/zio_inject.c +++ b/sys/contrib/openzfs/module/zfs/zio_inject.c @@ -1008,9 +1008,9 @@ zio_inject_fault(char *name, int flags, int *id, zinject_record_t *record) if (zio_pool_handler_exists(name, record->zi_cmd)) return (SET_ERROR(EEXIST)); - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); boolean_t has_spa = spa_lookup(name) != NULL; - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); if (record->zi_cmd == ZINJECT_DELAY_IMPORT && has_spa) return (SET_ERROR(EEXIST)); @@ -1095,7 +1095,7 @@ zio_inject_list_next(int *id, char *name, size_t buflen, inject_handler_t *handler; int ret; - mutex_enter(&spa_namespace_lock); + spa_namespace_enter(FTAG); rw_enter(&inject_lock, RW_READER); for (handler = list_head(&inject_handlers); handler != NULL; @@ -1117,7 +1117,7 @@ zio_inject_list_next(int *id, char *name, size_t buflen, } rw_exit(&inject_lock); - mutex_exit(&spa_namespace_lock); + spa_namespace_exit(FTAG); return (ret); } diff --git a/sys/contrib/openzfs/module/zfs/zvol.c b/sys/contrib/openzfs/module/zfs/zvol.c index 00f98168d3d8..407758641580 100644 --- a/sys/contrib/openzfs/module/zfs/zvol.c +++ b/sys/contrib/openzfs/module/zfs/zvol.c @@ -547,7 +547,8 @@ zvol_replay_write(void *arg1, void *arg2, boolean_t byteswap) if (error) { dmu_tx_abort(tx); } else { - dmu_write(os, ZVOL_OBJ, offset, length, data, tx); + dmu_write(os, ZVOL_OBJ, offset, length, data, tx, + DMU_READ_PREFETCH); (void) zil_replaying(zv->zv_zilog, tx); dmu_tx_commit(tx); } @@ -1232,7 +1233,7 @@ zvol_first_open(zvol_state_t *zv, boolean_t readonly) ASSERT(RW_READ_HELD(&zv->zv_suspend_lock)); ASSERT(MUTEX_HELD(&zv->zv_state_lock)); - ASSERT(mutex_owned(&spa_namespace_lock)); + ASSERT(spa_namespace_held()); boolean_t ro = (readonly || (strchr(zv->zv_name, '@') != NULL)); error = dmu_objset_own(zv->zv_name, DMU_OST_ZVOL, ro, B_TRUE, zv, &os); @@ -1302,7 +1303,7 @@ zvol_create_snap_minor_cb(const char *dsname, void *arg) list_t *minors_list = j->list; const char *name = j->name; - ASSERT0(MUTEX_HELD(&spa_namespace_lock)); + ASSERT0(spa_namespace_held()); /* skip the designated dataset */ if (name && strcmp(dsname, name) == 0) @@ -1402,7 +1403,7 @@ zvol_create_minors_cb(const char *dsname, void *arg) int error; list_t *minors_list = arg; - ASSERT0(MUTEX_HELD(&spa_namespace_lock)); + ASSERT0(spa_namespace_held()); error = dsl_prop_get_integer(dsname, "snapdev", &snapdev, NULL); if (error) diff --git a/sys/contrib/openzfs/module/zstd/include/aarch64_compat.h b/sys/contrib/openzfs/module/zstd/include/aarch64_compat.h deleted file mode 100644 index 9500a832b81c..000000000000 --- a/sys/contrib/openzfs/module/zstd/include/aarch64_compat.h +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* - * BSD 3-Clause New License (https://spdx.org/licenses/BSD-3-Clause.html) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright (c) 2018-2020, Sebastian Gottschall - */ - -#ifdef _KERNEL -#undef __aarch64__ -#endif diff --git a/sys/contrib/openzfs/module/zstd/lib/common/compiler.h b/sys/contrib/openzfs/module/zstd/lib/common/compiler.h index d0f588e2ec3c..c8d65a201212 100644 --- a/sys/contrib/openzfs/module/zstd/lib/common/compiler.h +++ b/sys/contrib/openzfs/module/zstd/lib/common/compiler.h @@ -115,9 +115,6 @@ # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ # define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) # define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1) -# elif defined(__aarch64__) -# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))) -# define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))) # elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) # define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) # define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */) diff --git a/sys/contrib/openzfs/module/zstd/lib/common/zstd_internal.h b/sys/contrib/openzfs/module/zstd/lib/common/zstd_internal.h index 6b1fc44cf9f6..9650af77bcea 100644 --- a/sys/contrib/openzfs/module/zstd/lib/common/zstd_internal.h +++ b/sys/contrib/openzfs/module/zstd/lib/common/zstd_internal.h @@ -12,6 +12,15 @@ #ifndef ZSTD_CCOMMON_H_MODULE #define ZSTD_CCOMMON_H_MODULE +/* + * Disable the aarch64 NEON SIMD intrinsics for kernel builds. Safely + * using them in the kernel context requires saving/restoring the FPU + * registers which is not currently done. + */ +#ifdef _KERNEL +#define ZSTD_NO_INTRINSICS +#endif + /* this module contains definitions which must be identical * across compression, decompression and dictBuilder. * It also contains a few functions useful to at least 2 of them diff --git a/sys/contrib/openzfs/rpm/generic/zfs.spec.in b/sys/contrib/openzfs/rpm/generic/zfs.spec.in index 8986e29eb7fb..9ae479aeb96b 100644 --- a/sys/contrib/openzfs/rpm/generic/zfs.spec.in +++ b/sys/contrib/openzfs/rpm/generic/zfs.spec.in @@ -111,10 +111,10 @@ License: @ZFS_META_LICENSE@ URL: https://github.com/openzfs/zfs Source0: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Requires: libzpool6%{?_isa} = %{version}-%{release} +Requires: libzpool7%{?_isa} = %{version}-%{release} Requires: libnvpair3%{?_isa} = %{version}-%{release} Requires: libuutil3%{?_isa} = %{version}-%{release} -Requires: libzfs6%{?_isa} = %{version}-%{release} +Requires: libzfs7%{?_isa} = %{version}-%{release} Requires: %{name}-kmod = %{version} Provides: %{name}-kmod-common = %{version}-%{release} Obsoletes: spl <= %{version} @@ -162,22 +162,23 @@ Requires: sysstat %description This package contains the core ZFS command line utilities. -%package -n libzpool6 +%package -n libzpool7 Summary: Native ZFS pool library for Linux Group: System Environment/Kernel Obsoletes: libzpool2 <= %{version} Obsoletes: libzpool4 <= %{version} Obsoletes: libzpool5 <= %{version} +Obsoletes: libzpool6 <= %{version} -%description -n libzpool6 +%description -n libzpool7 This package contains the zpool library, which provides support for managing zpools %if %{defined ldconfig_scriptlets} -%ldconfig_scriptlets -n libzpool6 +%ldconfig_scriptlets -n libzpool7 %else -%post -n libzpool6 -p /sbin/ldconfig -%postun -n libzpool6 -p /sbin/ldconfig +%post -n libzpool7 -p /sbin/ldconfig +%postun -n libzpool7 -p /sbin/ldconfig %endif %package -n libnvpair3 @@ -224,31 +225,32 @@ This library provides a variety of compatibility functions for OpenZFS: # The library version is encoded in the package name. When updating the # version information it is important to add an obsoletes line below for # the previous version of the package. -%package -n libzfs6 +%package -n libzfs7 Summary: Native ZFS filesystem library for Linux Group: System Environment/Kernel Obsoletes: libzfs2 <= %{version} Obsoletes: libzfs4 <= %{version} Obsoletes: libzfs5 <= %{version} +Obsoletes: libzfs6 <= %{version} -%description -n libzfs6 +%description -n libzfs7 This package provides support for managing ZFS filesystems %if %{defined ldconfig_scriptlets} -%ldconfig_scriptlets -n libzfs6 +%ldconfig_scriptlets -n libzfs7 %else -%post -n libzfs6 -p /sbin/ldconfig -%postun -n libzfs6 -p /sbin/ldconfig +%post -n libzfs7 -p /sbin/ldconfig +%postun -n libzfs7 -p /sbin/ldconfig %endif -%package -n libzfs6-devel +%package -n libzfs7-devel Summary: Development headers Group: System Environment/Kernel -Requires: libzfs6%{?_isa} = %{version}-%{release} -Requires: libzpool6%{?_isa} = %{version}-%{release} +Requires: libzfs7%{?_isa} = %{version}-%{release} +Requires: libzpool7%{?_isa} = %{version}-%{release} Requires: libnvpair3%{?_isa} = %{version}-%{release} Requires: libuutil3%{?_isa} = %{version}-%{release} -Provides: libzpool6-devel = %{version}-%{release} +Provides: libzpool7-devel = %{version}-%{release} Provides: libnvpair3-devel = %{version}-%{release} Provides: libuutil3-devel = %{version}-%{release} Obsoletes: zfs-devel <= %{version} @@ -256,7 +258,7 @@ Obsoletes: libzfs2-devel <= %{version} Obsoletes: libzfs4-devel <= %{version} Obsoletes: libzfs5-devel <= %{version} -%description -n libzfs6-devel +%description -n libzfs7-devel This package contains the header files needed for building additional applications against the ZFS libraries. @@ -305,7 +307,7 @@ Summary: Python %{python_version} wrapper for libzfs_core Group: Development/Languages/Python License: Apache-2.0 BuildArch: noarch -Requires: libzfs6 = %{version}-%{release} +Requires: libzfs7 = %{version}-%{release} Requires: libnvpair3 = %{version}-%{release} Requires: libffi Requires: python%{__python_pkg_version} @@ -548,7 +550,7 @@ systemctl --system daemon-reload >/dev/null || true %config(noreplace) %{_bashcompletiondir}/zfs %config(noreplace) %{_bashcompletiondir}/zpool -%files -n libzpool6 +%files -n libzpool7 %{_libdir}/libzpool.so.* %files -n libnvpair3 @@ -557,10 +559,10 @@ systemctl --system daemon-reload >/dev/null || true %files -n libuutil3 %{_libdir}/libuutil.so.* -%files -n libzfs6 +%files -n libzfs7 %{_libdir}/libzfs*.so.* -%files -n libzfs6-devel +%files -n libzfs7-devel %{_pkgconfigdir}/libzfs.pc %{_pkgconfigdir}/libzfsbootenv.pc %{_pkgconfigdir}/libzfs_core.pc diff --git a/sys/contrib/openzfs/scripts/Makefile.am b/sys/contrib/openzfs/scripts/Makefile.am index f623526307b4..bff5f8b78a85 100644 --- a/sys/contrib/openzfs/scripts/Makefile.am +++ b/sys/contrib/openzfs/scripts/Makefile.am @@ -28,9 +28,7 @@ endif dist_noinst_DATA += \ %D%/cstyle.pl \ - %D%/update_authors.pl \ - %D%/zfs2zol-patch.sed \ - %D%/zol2zfs-patch.sed + %D%/update_authors.pl SHELLCHECKSCRIPTS += $(dist_scripts_SCRIPTS) $(dist_noinst_SCRIPTS) diff --git a/sys/contrib/openzfs/scripts/spdxcheck.pl b/sys/contrib/openzfs/scripts/spdxcheck.pl index 4d4e14368beb..e1af3150bccd 100755 --- a/sys/contrib/openzfs/scripts/spdxcheck.pl +++ b/sys/contrib/openzfs/scripts/spdxcheck.pl @@ -124,14 +124,12 @@ my $untagged_patterns = q( include/os/freebsd/spl/sys/inttypes.h include/os/freebsd/spl/sys/mode.h include/os/freebsd/spl/sys/trace.h - include/os/freebsd/spl/sys/trace_zfs.h + include/os/freebsd/zfs/sys/trace_zfs.h include/os/freebsd/zfs/sys/zpl.h include/os/linux/kernel/linux/page_compat.h - lib/libspl/include/os/freebsd/sys/sysmacros.h lib/libspl/include/sys/string.h - lib/libspl/include/sys/trace_spl.h - lib/libspl/include/sys/trace_zfs.h lib/libzdb/libzdb.c + lib/libzpool/include/sys/trace_zfs.h module/lua/setjmp/setjmp.S module/lua/setjmp/setjmp_ppc.S module/zstd/include/sparc_compat.h diff --git a/sys/contrib/openzfs/scripts/zfs2zol-patch.sed b/sys/contrib/openzfs/scripts/zfs2zol-patch.sed deleted file mode 100755 index 2d744cd5de52..000000000000 --- a/sys/contrib/openzfs/scripts/zfs2zol-patch.sed +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sed -f - -s:usr/src/uts/common/fs/zfs/sys:include/sys:g -s:usr/src/uts/common/fs/zfs:module/zfs:g -s:usr/src/lib/libzpool:lib/libzpool:g -s:usr/src/cmd:cmd:g -s:usr/src/common/nvpair:module/nvpair:g -s:usr/src/lib/libzfs/common/libzfs.h:include/libzfs.h:g -s:usr/src/man/man1m/zfs.1m:man/man8/zfs.8:g -s:usr/src/uts/common/sys:include/sys:g -s:usr/src/lib/libzfs_core/common/libzfs_core.h:include/libzfs_core.h:g -s:usr/src/lib/libzfs/common:lib/libzfs:g -s:usr/src/lib/libzfs_core/common:lib/libzfs_core:g -s:lib/libzpool/common/sys:include/sys:g -s:lib/libzpool/common:lib/libzpool:g - -s:usr/src/test/zfs-tests/include:tests/zfs-tests/include:g -s:usr/src/test/zfs-tests/runfiles:tests/runfiles:g -s:usr/src/test/zfs-tests/tests/functional:tests/zfs-tests/tests/functional:g -s:usr/src/test/zfs-tests/tests/perf:tests/zfs-tests/tests/perf:g -s:usr/src/test/test-runner/cmd/run.py:tests/test-runner/cmd/test-runner.py:g -s:usr/src/common/zfs/\(.*\)\.c:module/zcommon/\1.c:g - -# crypto framework -s:usr/src/common/crypto:module/icp/algs:g -s:usr/src/uts/common/crypto/io:module/icp/io:g - -# Headers -s:usr/src/common/zfs/\(.*\)\.h:include/\1.h:g - -# Man pages -s:usr/src/man:man:g diff --git a/sys/contrib/openzfs/scripts/zol2zfs-patch.sed b/sys/contrib/openzfs/scripts/zol2zfs-patch.sed deleted file mode 100755 index 0ca4b6cd6b7e..000000000000 --- a/sys/contrib/openzfs/scripts/zol2zfs-patch.sed +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sed -f - -s:cmd:usr/src/cmd:g -s:include/libzfs.h:usr/src/lib/libzfs/common/libzfs.h:g -s:include/libzfs_core.h:usr/src/lib/libzfs_core/common/libzfs_core.h:g -s:include/sys:lib/libzpool/common/sys:g -s:include/sys:usr/src/uts/common/fs/zfs/sys:g -s:include/sys:usr/src/uts/common/sys:g -s:include/zfs_fletcher.h:usr/src/common/zfs/zfs_fletcher.h:g -s:include:usr/src/common/zfs:g -s:lib/libzfs:usr/src/lib/libzfs/common:g -s:lib/libzfs_core:usr/src/lib/libzfs_core/common:g -s:lib/libzpool:lib/libzpool/common:g -s:lib/libzpool:usr/src/lib/libzpool:g -s:man/man7/zpool-features.7:usr/src/man/man5/zpool-features.5:g -s:man/man8/zfs.8:usr/src/man/man1m/zfs.1m:g -s:module/nvpair:usr/src/common/nvpair:g -s:module/zcommon:usr/src/common/zfs/:g -s:module/zfs:usr/src/uts/common/fs/zfs:g -s:tests/zfs-tests:test/zfs-tests:g diff --git a/sys/contrib/openzfs/tests/runfiles/common.run b/sys/contrib/openzfs/tests/runfiles/common.run index 9f531411fbe1..a69c6e3c8dd7 100644 --- a/sys/contrib/openzfs/tests/runfiles/common.run +++ b/sys/contrib/openzfs/tests/runfiles/common.run @@ -215,7 +215,7 @@ tests = ['zfs_create_001_pos', 'zfs_create_002_pos', 'zfs_create_003_pos', tags = ['functional', 'cli_root', 'zfs_create'] [tests/functional/cli_root/zpool_prefetch] -tests = ['zpool_prefetch_001_pos'] +tests = ['zpool_prefetch_001_pos', 'zpool_prefetch_002_pos'] tags = ['functional', 'cli_root', 'zpool_prefetch'] [tests/functional/cli_root/zfs_destroy] diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am index 85c3cf3c35a8..b4efefdb7ab7 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am +++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am @@ -60,7 +60,6 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/file_append %D%/file_check %D%/file_trunc scripts_zfs_tests_bin_PROGRAMS += %D%/libzfs_input_check -%C%_libzfs_input_check_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/include/os/@ac_system_l@/zfs %C%_libzfs_input_check_LDADD = \ libzfs_core.la \ libnvpair.la @@ -117,9 +116,7 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/edonr_test %D%/skein_test \ %C%_edonr_test_SOURCES = %D%/checksum/edonr_test.c %C%_blake3_test_SOURCES = %D%/checksum/blake3_test.c %C%_skein_test_LDADD = \ - libicp.la \ - libspl.la \ - libspl_assert.la + libzpool.la %C%_sha2_test_LDADD = $(%C%_skein_test_LDADD) %C%_edonr_test_LDADD = $(%C%_skein_test_LDADD) %C%_blake3_test_LDADD = $(%C%_skein_test_LDADD) diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/ereports.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/ereports.c index f981d5b34438..a28495b762cd 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/cmd/ereports.c +++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/ereports.c @@ -22,11 +22,12 @@ #include <fcntl.h> #include <stdio.h> #include <libzfs.h> -#include <sys/zfs_ioctl.h> #include <sys/nvpair.h> #include <sys/fm/protocol.h> #include <sys/fm/fs/zfs.h> +#define ZEVENT_NONBLOCK 0x1 + /* * Command to output io and checksum ereport values, one per line. * Used by zpool_events_duplicates.ksh to check for duplicate events. diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am index 678c01b58f94..23284234cdf7 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/Makefile.am @@ -1217,6 +1217,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \ functional/cli_root/zpool_prefetch/cleanup.ksh \ functional/cli_root/zpool_prefetch/setup.ksh \ functional/cli_root/zpool_prefetch/zpool_prefetch_001_pos.ksh \ + functional/cli_root/zpool_prefetch/zpool_prefetch_002_pos.ksh \ functional/cli_root/zpool_reguid/cleanup.ksh \ functional/cli_root/zpool_reguid/setup.ksh \ functional/cli_root/zpool_reguid/zpool_reguid_001_pos.ksh \ diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_get/vdev_get.cfg b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_get/vdev_get.cfg index ccb5e9c15809..6d9aa28681c7 100644 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_get/vdev_get.cfg +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_get/vdev_get.cfg @@ -71,6 +71,7 @@ typeset -a properties=( checksum_t io_n io_t + slow_io_events slow_io_n slow_io_t trim_support diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_001_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_001_pos.ksh index 8ef3a66ad0d9..fd446e46e96c 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_001_pos.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_001_pos.ksh @@ -42,6 +42,15 @@ verify_runnable "both" log_assert "'zpool prefetch -t ddt <pool>' can successfully load the DDT for a pool." +DATASET=$TESTPOOL/ddt + +function cleanup +{ + datasetexists $DATASET && destroy_dataset $DATASET -f +} + +log_onexit cleanup + function getddtstats { typeset -n gds=$1 @@ -75,9 +84,8 @@ log_must zpool prefetch -t ddt $TESTPOOL # Build up the deduplicated dataset. This consists of creating enough files # to generate a reasonable size DDT for testing purposes. -DATASET=$TESTPOOL/ddt log_must zfs create -o compression=off -o dedup=on $DATASET -MNTPOINT=$(get_prop mountpoint $TESTPOOL/ddt) +MNTPOINT=$(get_prop mountpoint $DATASET) log_note "Generating dataset ..." typeset -i i=0 diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_002_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_002_pos.ksh new file mode 100755 index 000000000000..f34f8c36e592 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_prefetch/zpool_prefetch_002_pos.ksh @@ -0,0 +1,95 @@ +#!/bin/ksh -p +# SPDX-License-Identifier: CDDL-1.0 +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2025 by iXsystems, Inc. +# + +. $STF_SUITE/include/libtest.shlib + +# +# DESCRIPTION: +# 'zpool prefetch -t brt <pool>' can successfully load a pool's BRT on demand. +# 'zpool prefetch <pool>' without -t prefetches both DDT and BRT. +# +# STRATEGY: +# 1. Create a dataset with block cloning enabled. +# 2. Create files and clone them to populate the BRT. +# 3. Export and import the pool to flush caches. +# 4. Use zpool prefetch -t brt to load BRT. +# 5. Test zpool prefetch without -t to prefetch all types. +# + +verify_runnable "both" + +if ! command -v clonefile > /dev/null ; then + log_unsupported "clonefile program required to test block cloning" +fi + +log_assert "'zpool prefetch' can successfully load BRT and prefetch all types" + +DATASET=$TESTPOOL/brt + +function cleanup +{ + datasetexists $DATASET && destroy_dataset $DATASET -f +} + +log_onexit cleanup +log_must zfs create $DATASET +MNTPOINT=$(get_prop mountpoint $DATASET) + +log_note "Generating cloned blocks for BRT ..." + +# Create source file +log_must dd if=/dev/urandom of=$MNTPOINT/source bs=1M count=100 + +# Create clones using clonefile +typeset -i i=0 +while (( i < 50 )); do + log_must clonefile -f $MNTPOINT/source $MNTPOINT/clone.$i + ((i += 1)) +done + +sync_pool $TESTPOOL + +# Verify BRT has entries (non-zero saved space) +brt_saved=$(zpool get -Hp -o value bclone_saved $TESTPOOL) +log_note "BRT saved space: $brt_saved" +log_must test "$brt_saved" -gt "0" + +# Export/import to flush caches +log_must zpool export $TESTPOOL +log_must zpool import $TESTPOOL + +# Test BRT prefetch - verify command succeeds +# Note: BRT does not expose cache statistics like DDT, so we can only +# verify the prefetch command completes successfully +log_must zpool prefetch -t brt $TESTPOOL + +# Test prefetch without -t (should prefetch all types including BRT) +log_must zpool export $TESTPOOL +log_must zpool import $TESTPOOL +log_must zpool prefetch $TESTPOOL + +log_pass "'zpool prefetch' successfully loads BRT and all types" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_slow_io.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_slow_io.ksh index 0c68530ee9ef..570c3b0c62b6 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_slow_io.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/events/zed_slow_io.ksh @@ -23,6 +23,7 @@ # # Copyright (c) 2023, Klara Inc. +# Copyright (c) 2025, Mariusz Zaborski <oshogbo@FreeBSD.org> # # DESCRIPTION: @@ -140,8 +141,8 @@ function slow_io_degrade { do_setup - zpool set slow_io_n=5 $TESTPOOL $VDEV - zpool set slow_io_t=60 $TESTPOOL $VDEV + log_must zpool set slow_io_n=5 $TESTPOOL $VDEV + log_must zpool set slow_io_t=60 $TESTPOOL $VDEV start_slow_io for i in {1..16}; do @@ -193,6 +194,44 @@ function slow_io_no_degrade do_clean } +# Change slow_io_n, slow_io_t to 5 events in 60 seconds +# fire more than 5 events. Disable slow io events. +# Should not degrade. +function slow_io_degrade_disabled +{ + do_setup + + log_must zpool set slow_io_n=5 $TESTPOOL $VDEV + log_must zpool set slow_io_t=60 $TESTPOOL $VDEV + log_must zpool set slow_io_events=off $TESTPOOL $VDEV + + start_slow_io + for i in {1..16}; do + dd if=${FILEPATH}$i of=/dev/null count=1 bs=512 2>/dev/null + sleep 0.5 + done + stop_slow_io + zpool sync + + # + # wait 60 seconds to confirm that zfs.delay was not generated. + # + typeset -i i=0 + typeset -i events=0 + while [[ $i -lt 60 ]]; do + events=$(zpool events | grep "ereport\.fs\.zfs.delay" | wc -l) + i=$((i+1)) + sleep 1 + done + log_note "$events delay events found" + + [ $events -eq "0" ] || \ + log_fail "expecting no delay events, found $events" + + log_mustnot wait_vdev_state $TESTPOOL $VDEV "DEGRADED" 45 + do_clean +} + log_assert "Test ZED slow io configurability" log_onexit cleanup @@ -202,5 +241,6 @@ log_must zed_start default_degrade slow_io_degrade slow_io_no_degrade +slow_io_degrade_disabled log_pass "Test ZED slow io configurability" diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh index 8d4340e47bf9..a8deedfb8c3c 100755 --- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh +++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh @@ -88,7 +88,7 @@ for type in "" "mirror" "raidz2" "draid"; do fi log_must truncate -s $((4 * MINVDEVSIZE)) $VDEVS - log_must zpool create -f $TESTPOOL $VDEVS + log_must zpool create -f $TESTPOOL $type $VDEVS log_must zpool set autotrim=on $TESTPOOL typeset availspace=$(get_prop available $TESTPOOL) diff --git a/sys/contrib/vchiq/interface/compat/vchi_bsd.c b/sys/contrib/vchiq/interface/compat/vchi_bsd.c index 8f47b3dc02d6..08f2f66dfc54 100644 --- a/sys/contrib/vchiq/interface/compat/vchi_bsd.c +++ b/sys/contrib/vchiq/interface/compat/vchi_bsd.c @@ -340,7 +340,6 @@ down_interruptible(struct semaphore *s) int ret ; ret = 0; - mtx_lock(&s->mtx); while (s->value == 0) { @@ -348,13 +347,11 @@ down_interruptible(struct semaphore *s) ret = cv_wait_sig(&s->cv, &s->mtx); s->waiters--; - if (ret == EINTR) { + /* XXXMDC As per its semaphore.c, linux can only return EINTR */ + if (ret) { mtx_unlock(&s->mtx); - return (-EINTR); + return -EINTR; } - - if (ret == ERESTART) - continue; } s->value--; @@ -441,8 +438,7 @@ flush_signals(VCHIQ_THREAD_T thr) int fatal_signal_pending(VCHIQ_THREAD_T thr) { - printf("Implement ME: %s\n", __func__); - return (0); + return (curproc_sigkilled()); } /* diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c index 185e81e71bdc..7e105a6b3b77 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c @@ -65,9 +65,24 @@ MALLOC_DEFINE(M_VCPAGELIST, "vcpagelist", "VideoCore pagelist memory"); #define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2) +/* + * XXXMDC + * Do this less ad-hoc-y -- e.g. + * https://github.com/raspberrypi/linux/commit/c683db8860a80562a2bb5b451d77b3e471d24f36 + */ +#if defined(__aarch64__) +int g_cache_line_size = 64; +#else int g_cache_line_size = 32; +#endif static int g_fragment_size; +unsigned int g_long_bulk_space = 0; +#define VM_PAGE_TO_VC_BULK_PAGE(x) (\ + g_long_bulk_space ? VM_PAGE_TO_PHYS(x)\ + : PHYS_TO_VCBUS(VM_PAGE_TO_PHYS(x))\ +) + typedef struct vchiq_2835_state_struct { int inited; VCHIQ_ARM_STATE_T arm_state; @@ -113,6 +128,54 @@ vchiq_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err) *addr = PHYS_TO_VCBUS(segs[0].ds_addr); } +#if defined(__aarch64__) /* See comment in free_pagelist */ +static int +invalidate_cachelines_in_range_of_ppage( + vm_page_t p, + size_t offset, + size_t count +) +{ + if(offset + count > PAGE_SIZE){ return EINVAL; } + uint8_t *dst = (uint8_t*)pmap_quick_enter_page(p); + if (!dst){ + return ENOMEM; + } + cpu_dcache_inv_range((void *)((vm_offset_t)dst + offset), count); + pmap_quick_remove_page((vm_offset_t)dst); + return 0; +} + +/* XXXMDC bulk instead of loading and invalidating single pages? */ +static void +invalidate_cachelines_in_range_of_ppage_seq(vm_page_t *p, size_t start, + size_t count) +{ + if (start >= PAGE_SIZE) + goto invalid_input; + +#define _NEXT_AT(x,_m) (((x)+((_m)-1)) & ~((_m)-1)) /* for power of two m */ + size_t offset = _NEXT_AT(start,g_cache_line_size); +#undef _NEXT_AT + count = (offset < start + count) ? count - (offset - start) : 0; + offset = offset & (PAGE_SIZE - 1); + for (size_t done = 0; count > done; + p++, done += PAGE_SIZE - offset, offset = 0) { + size_t in_page = PAGE_SIZE - offset; + size_t todo = (count-done > in_page) ? in_page : count-done; + int e = invalidate_cachelines_in_range_of_ppage(*p, offset, todo); + if (e != 0) + goto problem_in_loop; + } + return; + +problem_in_loop: +invalid_input: + WARN_ON(1); + return; +} +#endif + static int copyout_page(vm_page_t p, size_t offset, void *kaddr, size_t size) { @@ -171,7 +234,7 @@ vchiq_platform_init(VCHIQ_STATE_T *state) goto failed_load; } - WARN_ON(((int)g_slot_mem & (PAGE_SIZE - 1)) != 0); + WARN_ON(((size_t)g_slot_mem & (PAGE_SIZE - 1)) != 0); vchiq_slot_zero = vchiq_init_slots(g_slot_mem, g_slot_mem_size); if (!vchiq_slot_zero) { @@ -391,13 +454,14 @@ pagelist_page_free(vm_page_t pp) ** from increased speed as a result. */ + static int create_pagelist(char __user *buf, size_t count, unsigned short type, struct proc *p, BULKINFO_T *bi) { PAGELIST_T *pagelist; vm_page_t* pages; - unsigned long *addrs; + uint32_t *addrs; unsigned int num_pages, i; vm_offset_t offset; int pagelist_size; @@ -434,7 +498,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, err = bus_dmamem_alloc(bi->pagelist_dma_tag, (void **)&pagelist, BUS_DMA_COHERENT | BUS_DMA_WAITOK, &bi->pagelist_dma_map); - if (err) { + if (err || !pagelist) { vchiq_log_error(vchiq_core_log_level, "Unable to allocate pagelist memory"); err = -ENOMEM; goto failed_alloc; @@ -447,6 +511,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, if (err) { vchiq_log_error(vchiq_core_log_level, "cannot load DMA map for pagelist memory"); err = -ENOMEM; + bi->pagelist = pagelist; goto failed_load; } @@ -463,8 +528,9 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, if (actual_pages != num_pages) { if (actual_pages > 0) vm_page_unhold_pages(pages, actual_pages); - free(pagelist, M_VCPAGELIST); - return (-ENOMEM); + err = -ENOMEM; + bi->pagelist = pagelist; + goto failed_hold; } pagelist->length = count; @@ -473,27 +539,28 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, /* Group the pages into runs of contiguous pages */ - base_addr = (void *)PHYS_TO_VCBUS(VM_PAGE_TO_PHYS(pages[0])); + size_t run_ceil = g_long_bulk_space ? 0x100 : PAGE_SIZE; + unsigned int pg_addr_rshift = g_long_bulk_space ? 4 : 0; + base_addr = (void *) VM_PAGE_TO_VC_BULK_PAGE(pages[0]); next_addr = base_addr + PAGE_SIZE; addridx = 0; run = 0; - +#define _PG_BLOCK(base,run) \ + ((((size_t) (base)) >> pg_addr_rshift) & ~(run_ceil-1)) + (run) for (i = 1; i < num_pages; i++) { - addr = (void *)PHYS_TO_VCBUS(VM_PAGE_TO_PHYS(pages[i])); - if ((addr == next_addr) && (run < (PAGE_SIZE - 1))) { + addr = (void *)VM_PAGE_TO_VC_BULK_PAGE(pages[i]); + if ((addr == next_addr) && (run < run_ceil - 1)) { next_addr += PAGE_SIZE; run++; } else { - addrs[addridx] = (unsigned long)base_addr + run; - addridx++; + addrs[addridx++] = (uint32_t) _PG_BLOCK(base_addr,run); base_addr = addr; next_addr = addr + PAGE_SIZE; run = 0; } } - - addrs[addridx] = (unsigned long)base_addr + run; - addridx++; + addrs[addridx++] = _PG_BLOCK(base_addr, run); +#undef _PG_BLOCK /* Partial cache lines (fragments) require special measures */ if ((type == PAGELIST_READ) && @@ -514,20 +581,35 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, WARN_ON(fragments == NULL); g_free_fragments = *(char **) g_free_fragments; up(&g_free_fragments_mutex); - pagelist->type = - PAGELIST_READ_WITH_FRAGMENTS + - (fragments - g_fragments_base)/g_fragment_size; + pagelist->type = PAGELIST_READ_WITH_FRAGMENTS + + (fragments - g_fragments_base)/g_fragment_size; +#if defined(__aarch64__) + bus_dmamap_sync(bcm_slots_dma_tag, bcm_slots_dma_map, + BUS_DMASYNC_PREREAD); +#endif } +#if defined(__aarch64__) + if(type == PAGELIST_READ) { + cpu_dcache_wbinv_range(buf, count); + } else { + cpu_dcache_wb_range(buf, count); + } + dsb(sy); +#else pa = pmap_extract(PCPU_GET(curpmap), (vm_offset_t)buf); dcache_wbinv_poc((vm_offset_t)buf, pa, count); +#endif - bus_dmamap_sync(bi->pagelist_dma_tag, bi->pagelist_dma_map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(bi->pagelist_dma_tag, bi->pagelist_dma_map, + BUS_DMASYNC_PREWRITE); bi->pagelist = pagelist; return 0; +failed_hold: + bus_dmamap_unload(bi->pagelist_dma_tag,bi->pagelist_dma_map); failed_load: bus_dmamem_free(bi->pagelist_dma_tag, bi->pagelist, bi->pagelist_dma_map); failed_alloc: @@ -556,6 +638,24 @@ free_pagelist(BULKINFO_T *bi, int actual) pages = (vm_page_t*)(pagelist->addrs + num_pages); +#if defined(__aarch64__) + /* + * On arm64, even if the user keeps their end of the bargain + * -- do NOT touch the buffers sent to VC -- but reads around the + * pagelist after the invalidation above, the arm might preemptively + * load (and validate) cache lines for areas inside the page list, + * so we must invalidate them again. + * + * The functional test does it and without this it doesn't pass. + * + * XXXMDC might it be enough to invalidate a couple of pages at + * the ends of the page list? + */ + if(pagelist->type >= PAGELIST_READ && actual > 0) + invalidate_cachelines_in_range_of_ppage_seq(pages, + pagelist->offset, actual); +#endif + /* Deal with any partial cache lines (fragments) */ if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) { char *fragments = g_fragments_base + @@ -592,13 +692,18 @@ free_pagelist(BULKINFO_T *bi, int actual) up(&g_free_fragments_sema); } - for (i = 0; i < num_pages; i++) { - if (pagelist->type != PAGELIST_WRITE) { + if (pagelist->type != PAGELIST_WRITE) { + for (i = 0; i < num_pages; i++) { vm_page_dirty(pages[i]); pagelist_page_free(pages[i]); } } +#if defined(__aarch64__) + /* XXXMDC necessary? */ + dsb(sy); +#endif + bus_dmamap_unload(bi->pagelist_dma_tag, bi->pagelist_dma_map); bus_dmamem_free(bi->pagelist_dma_tag, bi->pagelist, bi->pagelist_dma_map); bus_dma_tag_destroy(bi->pagelist_dma_tag); diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c index e25c4d738922..d780f3807cee 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c @@ -386,7 +386,7 @@ static void user_service_free(void *userdata) { USER_SERVICE_T *user_service = userdata; - + _sema_destroy(&user_service->insert_event); _sema_destroy(&user_service->remove_event); @@ -410,7 +410,7 @@ static void close_delivered(USER_SERVICE_T *user_service) /* Wake the user-thread blocked in close_ or remove_service */ up(&user_service->close_event); - + user_service->close_pending = 0; } } @@ -448,6 +448,22 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, (_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ? ioctl_names[_IOC_NR(cmd)] : "<invalid>", arg); +#ifdef COMPAT_FREEBSD32 +/* A fork in the road to freebsd32 compatibilty */ +#define _CF32_FORK(compat_c, native_c) { \ + int _____dont_call_your_vars_this = 0; \ + switch (cmd) { \ + _CF32_CASE {_____dont_call_your_vars_this = 1;} \ + break; \ + } \ + if (_____dont_call_your_vars_this) \ + { compat_c } \ + else \ + { native_c } \ + } +#else +#define _CF32_FORK(compat_c, native_c) { native_c } +#endif switch (cmd) { case VCHIQ_IOC_SHUTDOWN: if (!instance->connected) @@ -496,13 +512,33 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, "vchiq: could not connect: %d", status); break; +#ifdef COMPAT_FREEBSD32 +#define _CF32_CASE \ + case VCHIQ_IOC_CREATE_SERVICE32: + _CF32_CASE +#endif case VCHIQ_IOC_CREATE_SERVICE: { VCHIQ_CREATE_SERVICE_T args; USER_SERVICE_T *user_service = NULL; void *userdata; int srvstate; +_CF32_FORK( + VCHIQ_CREATE_SERVICE32_T args32; + memcpy(&args32, (const void*)arg, sizeof(args32)); + args.params.fourcc = args32.params.fourcc; + /* XXXMDC not actually used? overwritten straight away */ + args.params.callback = + (VCHIQ_CALLBACK_T)(uintptr_t) args32.params.callback; + args.params.userdata = (void*)(uintptr_t)args32.params.userdata; + args.params.version = args32.params.version; + args.params.version_min = args32.params.version_min; + args.is_open = args32.is_open; + args.is_vchi = args32.is_vchi; + args.handle = args32.handle; +, memcpy(&args, (const void*)arg, sizeof(args)); +) user_service = kmalloc(sizeof(USER_SERVICE_T), GFP_KERNEL); if (!user_service) { @@ -558,15 +594,22 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, break; } } - #ifdef VCHIQ_IOCTL_DEBUG printf("%s: [CREATE SERVICE] handle = %08x\n", __func__, service->handle); #endif +_CF32_FORK( + memcpy((void *) + &(((VCHIQ_CREATE_SERVICE32_T*) + arg)->handle), + (const void *)&service->handle, + sizeof(service->handle)); +, memcpy((void *) &(((VCHIQ_CREATE_SERVICE_T*) arg)->handle), (const void *)&service->handle, sizeof(service->handle)); +); service = NULL; } else { @@ -574,6 +617,7 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, kfree(user_service); } } break; +#undef _CF32_CASE case VCHIQ_IOC_CLOSE_SERVICE: { VCHIQ_SERVICE_HANDLE_T handle; @@ -673,9 +717,22 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, ret = -EINVAL; } break; +#ifdef COMPAT_FREEBSD32 +#define _CF32_CASE \ + case VCHIQ_IOC_QUEUE_MESSAGE32: + _CF32_CASE +#endif case VCHIQ_IOC_QUEUE_MESSAGE: { VCHIQ_QUEUE_MESSAGE_T args; +_CF32_FORK( + VCHIQ_QUEUE_MESSAGE32_T args32; + memcpy(&args32, (const void*)arg, sizeof(args32)); + args.handle = args32.handle; + args.count = args32.count; + args.elements = (VCHIQ_ELEMENT_T *)(uintptr_t)args32.elements; +, memcpy(&args, (const void*)arg, sizeof(args)); +) #ifdef VCHIQ_IOCTL_DEBUG printf("%s: [QUEUE MESSAGE] handle = %08x\n", __func__, args.handle); @@ -686,8 +743,22 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, if ((service != NULL) && (args.count <= MAX_ELEMENTS)) { /* Copy elements into kernel space */ VCHIQ_ELEMENT_T elements[MAX_ELEMENTS]; - if (copy_from_user(elements, args.elements, - args.count * sizeof(VCHIQ_ELEMENT_T)) == 0) + long cp_ret; +_CF32_FORK( + VCHIQ_ELEMENT32_T elements32[MAX_ELEMENTS]; + cp_ret = copy_from_user(elements32, args.elements, + args.count * sizeof(VCHIQ_ELEMENT32_T)); + for(int i=0;cp_ret == 0 && i < args.count;++i){ + elements[i].data = + (void *)(uintptr_t)elements32[i].data; + elements[i].size = elements32[i].size; + } + +, + cp_ret = copy_from_user(elements, args.elements, + args.count * sizeof(VCHIQ_ELEMENT_T)); +) + if (cp_ret == 0) status = vchiq_queue_message (args.handle, elements, args.count); @@ -697,16 +768,38 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, ret = -EINVAL; } } break; +#undef _CF32_CASE +#ifdef COMPAT_FREEBSD32 +#define _CF32_CASE \ + case VCHIQ_IOC_QUEUE_BULK_TRANSMIT32: \ + case VCHIQ_IOC_QUEUE_BULK_RECEIVE32: + _CF32_CASE +#endif case VCHIQ_IOC_QUEUE_BULK_TRANSMIT: case VCHIQ_IOC_QUEUE_BULK_RECEIVE: { VCHIQ_QUEUE_BULK_TRANSFER_T args; + struct bulk_waiter_node *waiter = NULL; VCHIQ_BULK_DIR_T dir = - (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ? - VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE; - + (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) || + (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT32)? + VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE; + +_CF32_FORK( + VCHIQ_QUEUE_BULK_TRANSFER32_T args32; + memcpy(&args32, (const void*)arg, sizeof(args32)); + /* XXXMDC parens needed (macro parsing?) */ + args = ((VCHIQ_QUEUE_BULK_TRANSFER_T) { + .handle = args32.handle, + .data = (void *)(uintptr_t) args32.data, + .size = args32.size, + .userdata = (void *)(uintptr_t) args32.userdata, + .mode = args32.mode, + }); +, memcpy(&args, (const void*)arg, sizeof(args)); +) service = find_service_for_instance(instance, args.handle); if (!service) { @@ -734,7 +827,6 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, list_del(pos); break; } - } lmutex_unlock(&instance->bulk_waiter_list_mutex); if (!waiter) { @@ -749,6 +841,7 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, (size_t)waiter, current->p_pid); args.userdata = &waiter->bulk_waiter; } + status = vchiq_bulk_transfer (args.handle, VCHI_MEM_HANDLE_INVALID, @@ -779,14 +872,28 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, "saved bulk_waiter %zx for pid %d", (size_t)waiter, current->p_pid); +_CF32_FORK( + memcpy((void *) + &(((VCHIQ_QUEUE_BULK_TRANSFER32_T *) + arg)->mode), + (const void *)&mode_waiting, + sizeof(mode_waiting)); +, memcpy((void *) &(((VCHIQ_QUEUE_BULK_TRANSFER_T *) arg)->mode), (const void *)&mode_waiting, sizeof(mode_waiting)); +) } } break; +#undef _CF32_CASE +#ifdef COMPAT_FREEBSD32 +#define _CF32_CASE \ + case VCHIQ_IOC_AWAIT_COMPLETION32: + _CF32_CASE +#endif case VCHIQ_IOC_AWAIT_COMPLETION: { VCHIQ_AWAIT_COMPLETION_T args; int count = 0; @@ -797,7 +904,17 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, break; } +_CF32_FORK( + VCHIQ_AWAIT_COMPLETION32_T args32; + memcpy(&args32, (const void*)arg, sizeof(args32)); + args.count = args32.count; + args.buf = (VCHIQ_COMPLETION_DATA_T *)(uintptr_t)args32.buf; + args.msgbufsize = args32.msgbufsize; + args.msgbufcount = args32.msgbufcount; + args.msgbufs = (void **)(uintptr_t)args32.msgbufs; +, memcpy(&args, (const void*)arg, sizeof(args)); +) lmutex_lock(&instance->completion_mutex); @@ -877,6 +994,20 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, break; /* Get the pointer from user space */ msgbufcount--; +_CF32_FORK( + uint32_t *msgbufs32 = + (uint32_t *) args.msgbufs; + uint32_t msgbuf32 = 0; + if (copy_from_user(&msgbuf32, + (const uint32_t __user *) + &msgbufs32[msgbufcount], + sizeof(msgbuf32)) != 0) { + if (count == 0) + ret = -EFAULT; + break; + } + msgbuf = (void __user *)(uintptr_t)msgbuf32; +, if (copy_from_user(&msgbuf, (const void __user *) &args.msgbufs[msgbufcount], @@ -885,6 +1016,7 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, ret = -EFAULT; break; } +) /* Copy the message to user space */ if (copy_to_user(msgbuf, header, @@ -908,7 +1040,30 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, VCHIQ_SERVICE_CLOSED) && !instance->use_close_delivered) unlock_service(service1); - +_CF32_FORK( + VCHIQ_COMPLETION_DATA32_T comp32 = {0}; + comp32.reason = + (uint32_t)(size_t) completion->reason; + comp32.service_userdata = + (uint32_t)(size_t) + completion->service_userdata; + comp32.bulk_userdata = + (uint32_t)(size_t) + completion->bulk_userdata; + comp32.header = + (uint32_t)(size_t)completion->header; + + VCHIQ_COMPLETION_DATA32_T __user *buf_loc; + buf_loc = (VCHIQ_COMPLETION_DATA32_T __user *) + args.buf; + buf_loc += count; + if (copy_to_user( + buf_loc, &comp32, sizeof(comp32) + ) != 0) { + if (ret == 0) + ret = -EFAULT; + } +, if (copy_to_user((void __user *)( (size_t)args.buf + count * sizeof(VCHIQ_COMPLETION_DATA_T)), @@ -918,6 +1073,7 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, ret = -EFAULT; break; } +) /* Ensure that the above copy has completed ** before advancing the remove pointer. */ @@ -927,18 +1083,33 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, } if (msgbufcount != args.msgbufcount) { +_CF32_FORK( + memcpy( + (void __user *) + &((VCHIQ_AWAIT_COMPLETION32_T *)arg)-> + msgbufcount, + &msgbufcount, + sizeof(msgbufcount)); +, memcpy((void __user *) &((VCHIQ_AWAIT_COMPLETION_T *)arg)-> msgbufcount, &msgbufcount, sizeof(msgbufcount)); +) } if (count != args.count) { +_CF32_FORK( + memcpy((void __user *) + &((VCHIQ_AWAIT_COMPLETION32_T *)arg)->count, + &count, sizeof(count)); +, memcpy((void __user *) &((VCHIQ_AWAIT_COMPLETION_T *)arg)->count, &count, sizeof(count)); +) } } @@ -947,9 +1118,9 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, if ((ret == 0) && instance->closing) ret = -ENOTCONN; - /* + /* * XXXBSD: ioctl return codes are not negative as in linux, so - * we can not indicate success with positive number of passed + * we can not indicate success with positive number of passed * messages */ if (ret > 0) @@ -958,14 +1129,29 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, lmutex_unlock(&instance->completion_mutex); DEBUG_TRACE(AWAIT_COMPLETION_LINE); } break; +#undef _CF32_CASE +#ifdef COMPAT_FREEBSD32 +#define _CF32_CASE \ + case VCHIQ_IOC_DEQUEUE_MESSAGE32: + _CF32_CASE +#endif case VCHIQ_IOC_DEQUEUE_MESSAGE: { VCHIQ_DEQUEUE_MESSAGE_T args; USER_SERVICE_T *user_service; VCHIQ_HEADER_T *header; DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); +_CF32_FORK( + VCHIQ_DEQUEUE_MESSAGE32_T args32; + memcpy(&args32, (const void*)arg, sizeof(args32)); + args.handle = args32.handle; + args.blocking = args32.blocking; + args.bufsize = args32.bufsize; + args.buf = (void *)(uintptr_t)args32.buf; +, memcpy(&args, (const void*)arg, sizeof(args)); +) service = find_service_for_instance(instance, args.handle); if (!service) { ret = -EINVAL; @@ -1022,8 +1208,19 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, header->data, header->size) == 0)) { args.bufsize = header->size; +_CF32_FORK( + VCHIQ_DEQUEUE_MESSAGE32_T args32; + args32.handle = args.handle; + args32.blocking = args.blocking; + args32.bufsize = args.bufsize; + args32.buf = (uintptr_t)(void *)args.buf; + + memcpy((void *)arg, &args32, + sizeof(args32)); +, memcpy((void *)arg, &args, sizeof(args)); +) vchiq_release_message( service->handle, header); @@ -1039,6 +1236,7 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, } DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); } break; +#undef _CF32_CASE case VCHIQ_IOC_GET_CLIENT_ID: { VCHIQ_SERVICE_HANDLE_T handle; @@ -1048,11 +1246,24 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, ret = vchiq_get_client_id(handle); } break; +#ifdef COMPAT_FREEBSD32 +#define _CF32_CASE \ + case VCHIQ_IOC_GET_CONFIG32: + _CF32_CASE +#endif case VCHIQ_IOC_GET_CONFIG: { VCHIQ_GET_CONFIG_T args; VCHIQ_CONFIG_T config; - +_CF32_FORK( + VCHIQ_GET_CONFIG32_T args32; + + memcpy(&args32, (const void*)arg, sizeof(args32)); + args.config_size = args32.config_size; + args.pconfig = (VCHIQ_CONFIG_T *) + (uintptr_t)args32.pconfig; +, memcpy(&args, (const void*)arg, sizeof(args)); +) if (args.config_size > sizeof(config)) { ret = -EINVAL; break; @@ -1066,6 +1277,7 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, } } } break; +#undef _CF32_CASE case VCHIQ_IOC_SET_SERVICE_OPTION: { VCHIQ_SET_SERVICE_OPTION_T args; @@ -1082,18 +1294,31 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, args.handle, args.option, args.value); } break; +#ifdef COMPAT_FREEBSD32 +#define _CF32_CASE \ + case VCHIQ_IOC_DUMP_PHYS_MEM32: + _CF32_CASE +#endif case VCHIQ_IOC_DUMP_PHYS_MEM: { VCHIQ_DUMP_MEM_T args; +_CF32_FORK( + VCHIQ_DUMP_MEM32_T args32; + memcpy(&args32, (const void*)arg, sizeof(args32)); + args.virt_addr = (void *)(uintptr_t)args32.virt_addr; + args.num_bytes = (size_t)args32.num_bytes; +, memcpy(&args, (const void*)arg, sizeof(args)); +) printf("IMPLEMENT ME: %s:%d\n", __FILE__, __LINE__); #if 0 dump_phys_mem(args.virt_addr, args.num_bytes); #endif } break; +#undef _CF32_CASE case VCHIQ_IOC_LIB_VERSION: { - unsigned int lib_version = (unsigned int)arg; + size_t lib_version = (size_t)arg; if (lib_version < VCHIQ_VERSION_MIN) ret = -EINVAL; @@ -1119,6 +1344,7 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, ret = -ENOTTY; break; } +#undef _CF32_FORK if (service) unlock_service(service); @@ -1155,18 +1381,14 @@ vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, return ret; } -static void -instance_dtr(void *data) -{ - kfree(data); -} /**************************************************************************** * * vchiq_open * ***************************************************************************/ +static void instance_dtr(void *data); static int vchiq_open(struct cdev *dev, int flags, int fmt __unused, struct thread *td) @@ -1206,7 +1428,7 @@ vchiq_open(struct cdev *dev, int flags, int fmt __unused, struct thread *td) INIT_LIST_HEAD(&instance->bulk_waiter_list); devfs_set_cdevpriv(instance, instance_dtr); - } + } else { vchiq_log_error(vchiq_arm_log_level, "Unknown minor device"); @@ -1222,143 +1444,151 @@ vchiq_open(struct cdev *dev, int flags, int fmt __unused, struct thread *td) * ***************************************************************************/ + static int -vchiq_close(struct cdev *dev, int flags __unused, int fmt __unused, - struct thread *td) +_vchiq_close_instance(VCHIQ_INSTANCE_T instance) { int ret = 0; - if (1) { - VCHIQ_INSTANCE_T instance; - VCHIQ_STATE_T *state = vchiq_get_state(); - VCHIQ_SERVICE_T *service; - int i; - - if ((ret = devfs_get_cdevpriv((void**)&instance))) { - printf("devfs_get_cdevpriv failed: error %d\n", ret); - return (ret); - } - - vchiq_log_info(vchiq_arm_log_level, - "vchiq_release: instance=%lx", - (unsigned long)instance); - - if (!state) { - ret = -EPERM; - goto out; - } + VCHIQ_STATE_T *state = vchiq_get_state(); + VCHIQ_SERVICE_T *service; + int i; - /* Ensure videocore is awake to allow termination. */ - vchiq_use_internal(instance->state, NULL, - USE_TYPE_VCHIQ); + vchiq_log_info(vchiq_arm_log_level, + "vchiq_release: instance=%lx", + (unsigned long)instance); - lmutex_lock(&instance->completion_mutex); + if (!state) { + ret = -EPERM; + goto out; + } - /* Wake the completion thread and ask it to exit */ - instance->closing = 1; - up(&instance->insert_event); + /* Ensure videocore is awake to allow termination. */ + vchiq_use_internal(instance->state, NULL, + USE_TYPE_VCHIQ); - lmutex_unlock(&instance->completion_mutex); + lmutex_lock(&instance->completion_mutex); - /* Wake the slot handler if the completion queue is full. */ - up(&instance->remove_event); + /* Wake the completion thread and ask it to exit */ + instance->closing = 1; + up(&instance->insert_event); - /* Mark all services for termination... */ - i = 0; - while ((service = next_service_by_instance(state, instance, - &i)) != NULL) { - USER_SERVICE_T *user_service = service->base.userdata; + lmutex_unlock(&instance->completion_mutex); - /* Wake the slot handler if the msg queue is full. */ - up(&user_service->remove_event); + /* Wake the slot handler if the completion queue is full. */ + up(&instance->remove_event); - vchiq_terminate_service_internal(service); - unlock_service(service); - } + /* Mark all services for termination... */ + i = 0; + while ((service = next_service_by_instance(state, instance, + &i)) != NULL) { + USER_SERVICE_T *user_service = service->base.userdata; - /* ...and wait for them to die */ - i = 0; - while ((service = next_service_by_instance(state, instance, &i)) - != NULL) { - USER_SERVICE_T *user_service = service->base.userdata; + /* Wake the slot handler if the msg queue is full. */ + up(&user_service->remove_event); - down(&service->remove_event); + vchiq_terminate_service_internal(service); + unlock_service(service); + } - BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE); + /* ...and wait for them to die */ + i = 0; + while ((service = next_service_by_instance(state, instance, &i)) + != NULL) { + USER_SERVICE_T *user_service = service->base.userdata; - spin_lock(&msg_queue_spinlock); + down(&service->remove_event); - while (user_service->msg_remove != - user_service->msg_insert) { - VCHIQ_HEADER_T *header = user_service-> - msg_queue[user_service->msg_remove & - (MSG_QUEUE_SIZE - 1)]; - user_service->msg_remove++; - spin_unlock(&msg_queue_spinlock); + BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE); - if (header) - vchiq_release_message( - service->handle, - header); - spin_lock(&msg_queue_spinlock); - } + spin_lock(&msg_queue_spinlock); + while (user_service->msg_remove != + user_service->msg_insert) { + VCHIQ_HEADER_T *header = user_service-> + msg_queue[user_service->msg_remove & + (MSG_QUEUE_SIZE - 1)]; + user_service->msg_remove++; spin_unlock(&msg_queue_spinlock); - unlock_service(service); + if (header) + vchiq_release_message( + service->handle, + header); + spin_lock(&msg_queue_spinlock); } - /* Release any closed services */ - while (instance->completion_remove != - instance->completion_insert) { - VCHIQ_COMPLETION_DATA_T *completion; - VCHIQ_SERVICE_T *service1; - completion = &instance->completions[ - instance->completion_remove & - (MAX_COMPLETIONS - 1)]; - service1 = completion->service_userdata; - if (completion->reason == VCHIQ_SERVICE_CLOSED) - { - USER_SERVICE_T *user_service = - service->base.userdata; - - /* Wake any blocked user-thread */ - if (instance->use_close_delivered) - up(&user_service->close_event); - unlock_service(service1); - } - instance->completion_remove++; - } + spin_unlock(&msg_queue_spinlock); - /* Release the PEER service count. */ - vchiq_release_internal(instance->state, NULL); + unlock_service(service); + } + /* Release any closed services */ + while (instance->completion_remove != + instance->completion_insert) { + VCHIQ_COMPLETION_DATA_T *completion; + VCHIQ_SERVICE_T *service; + completion = &instance->completions[ + instance->completion_remove & + (MAX_COMPLETIONS - 1)]; + service = completion->service_userdata; + if (completion->reason == VCHIQ_SERVICE_CLOSED) { - struct list_head *pos, *next; - list_for_each_safe(pos, next, - &instance->bulk_waiter_list) { - struct bulk_waiter_node *waiter; - waiter = list_entry(pos, - struct bulk_waiter_node, - list); - list_del(pos); - vchiq_log_info(vchiq_arm_log_level, - "bulk_waiter - cleaned up %x " - "for pid %d", - (unsigned int)waiter, waiter->pid); - _sema_destroy(&waiter->bulk_waiter.event); - kfree(waiter); - } - } + USER_SERVICE_T *user_service = + service->base.userdata; + /* Wake any blocked user-thread */ + if (instance->use_close_delivered) + up(&user_service->close_event); + + unlock_service(service); + } + instance->completion_remove++; } - else { - vchiq_log_error(vchiq_arm_log_level, - "Unknown minor device"); - ret = -ENXIO; + + /* Release the PEER service count. */ + vchiq_release_internal(instance->state, NULL); + + { + struct list_head *pos, *next; + list_for_each_safe(pos, next, + &instance->bulk_waiter_list) { + struct bulk_waiter_node *waiter; + waiter = list_entry(pos, + struct bulk_waiter_node, + list); + list_del(pos); + vchiq_log_info(vchiq_arm_log_level, + "bulk_waiter - cleaned up %zx " + "for pid %d", + (size_t)waiter, waiter->pid); + _sema_destroy(&waiter->bulk_waiter.event); + kfree(waiter); + } } out: return ret; + +} + +static void +instance_dtr(void *data) +{ + VCHIQ_INSTANCE_T instance = data; + _vchiq_close_instance(instance); + kfree(data); +} + +static int +vchiq_close(struct cdev *dev, int flags __unused, int fmt __unused, + struct thread *td) +{ + + /* XXXMDC it's privdata that tracks opens */ + /* XXXMDC only get closes when there are no more open fds on a vnode */ + + return(0); + } /**************************************************************************** diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.c index e7459a5553e4..923cf56f10ee 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.c @@ -417,13 +417,15 @@ vchiq_set_conn_state(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T newstate) vchiq_platform_conn_state_changed(state, oldstate, newstate); } +#define ACTUAL_EVENT_SEM_ADDR(ref,offset)\ + ((struct semaphore *)(((size_t) ref) + ((size_t) offset))) static inline void -remote_event_create(REMOTE_EVENT_T *event) +remote_event_create(VCHIQ_STATE_T *ref, REMOTE_EVENT_T *event) { event->armed = 0; /* Don't clear the 'fired' flag because it may already have been set ** by the other side. */ - _sema_init(event->event, 0); + _sema_init(ACTUAL_EVENT_SEM_ADDR(ref,event->event), 0); } __unused static inline void @@ -433,13 +435,18 @@ remote_event_destroy(REMOTE_EVENT_T *event) } static inline int -remote_event_wait(REMOTE_EVENT_T *event) +remote_event_wait(VCHIQ_STATE_T *ref, REMOTE_EVENT_T *event) { if (!event->fired) { event->armed = 1; +#if defined(__aarch64__) + dsb(sy); +#else dsb(); +#endif + if (!event->fired) { - if (down_interruptible(event->event) != 0) { + if (down_interruptible(ACTUAL_EVENT_SEM_ADDR(ref,event->event)) != 0) { event->armed = 0; return 0; } @@ -453,26 +460,32 @@ remote_event_wait(REMOTE_EVENT_T *event) } static inline void -remote_event_signal_local(REMOTE_EVENT_T *event) +remote_event_signal_local(VCHIQ_STATE_T *ref, REMOTE_EVENT_T *event) { +/* + * Mirror + * https://github.com/raspberrypi/linux/commit/a50c4c9a65779ca835746b5fd79d3d5278afbdbe + * for extra safety + */ + event->fired = 1; event->armed = 0; - up(event->event); + up(ACTUAL_EVENT_SEM_ADDR(ref,event->event)); } static inline void -remote_event_poll(REMOTE_EVENT_T *event) +remote_event_poll(VCHIQ_STATE_T *ref, REMOTE_EVENT_T *event) { if (event->fired && event->armed) - remote_event_signal_local(event); + remote_event_signal_local(ref,event); } void remote_event_pollall(VCHIQ_STATE_T *state) { - remote_event_poll(&state->local->sync_trigger); - remote_event_poll(&state->local->sync_release); - remote_event_poll(&state->local->trigger); - remote_event_poll(&state->local->recycle); + remote_event_poll(state , &state->local->sync_trigger); + remote_event_poll(state , &state->local->sync_release); + remote_event_poll(state , &state->local->trigger); + remote_event_poll(state , &state->local->recycle); } /* Round up message sizes so that any space at the end of a slot is always big @@ -553,7 +566,7 @@ request_poll(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int poll_type) wmb(); /* ... and ensure the slot handler runs. */ - remote_event_signal_local(&state->local->trigger); + remote_event_signal_local(state, &state->local->trigger); } /* Called from queue_message, by the slot handler and application threads, @@ -1016,7 +1029,7 @@ queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, (lmutex_lock_interruptible(&state->sync_mutex) != 0)) return VCHIQ_RETRY; - remote_event_wait(&local->sync_release); + remote_event_wait(state, &local->sync_release); rmb(); @@ -1097,9 +1110,6 @@ queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, size); } - /* Make sure the new header is visible to the peer. */ - wmb(); - remote_event_signal(&state->remote->sync_trigger); if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_PAUSE) @@ -1824,8 +1834,17 @@ parse_rx_slots(VCHIQ_STATE_T *state) state->slot_data)->version; up(&state->connect); break; +/* + * XXXMDC Apparently nothing uses this + * https://github.com/raspberrypi/linux/commit/14f4d72fb799a9b3170a45ab80d4a3ddad541960 + * but taking out the master bits is a whole new job + */ case VCHIQ_MSG_BULK_RX: - case VCHIQ_MSG_BULK_TX: { + case VCHIQ_MSG_BULK_TX: + WARN_ON(1); + break; +#if 0 + { VCHIQ_BULK_QUEUE_T *queue; WARN_ON(!state->is_master); queue = (type == VCHIQ_MSG_BULK_RX) ? @@ -1887,9 +1906,11 @@ parse_rx_slots(VCHIQ_STATE_T *state) lmutex_unlock(&service->bulk_mutex); if (resolved) notify_bulks(service, queue, - 1/*retry_poll*/); + 1//retry_poll + ); } - } break; + } +#endif case VCHIQ_MSG_BULK_RX_DONE: case VCHIQ_MSG_BULK_TX_DONE: WARN_ON(state->is_master); @@ -2050,7 +2071,7 @@ slot_handler_func(void *v) while (1) { DEBUG_COUNT(SLOT_HANDLER_COUNT); DEBUG_TRACE(SLOT_HANDLER_LINE); - remote_event_wait(&local->trigger); + remote_event_wait(state, &local->trigger); rmb(); @@ -2140,8 +2161,7 @@ recycle_func(void *v) VCHIQ_SHARED_STATE_T *local = state->local; while (1) { - remote_event_wait(&local->recycle); - + remote_event_wait(state, &local->recycle); process_free_queue(state); } return 0; @@ -2164,7 +2184,7 @@ sync_func(void *v) int type; unsigned int localport, remoteport; - remote_event_wait(&local->sync_trigger); + remote_event_wait(state, &local->sync_trigger); rmb(); @@ -2281,7 +2301,7 @@ get_conn_state_name(VCHIQ_CONNSTATE_T conn_state) VCHIQ_SLOT_ZERO_T * vchiq_init_slots(void *mem_base, int mem_size) { - int mem_align = (VCHIQ_SLOT_SIZE - (int)mem_base) & VCHIQ_SLOT_MASK; + int mem_align = (int)((VCHIQ_SLOT_SIZE - (long)mem_base) & VCHIQ_SLOT_MASK); VCHIQ_SLOT_ZERO_T *slot_zero = (VCHIQ_SLOT_ZERO_T *)((char *)mem_base + mem_align); int num_slots = (mem_size - mem_align)/VCHIQ_SLOT_SIZE; @@ -2477,24 +2497,24 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, state->data_use_count = 0; state->data_quota = state->slot_queue_available - 1; - local->trigger.event = &state->trigger_event; - remote_event_create(&local->trigger); + local->trigger.event = offsetof(VCHIQ_STATE_T, trigger_event); + remote_event_create(state, &local->trigger); local->tx_pos = 0; - local->recycle.event = &state->recycle_event; - remote_event_create(&local->recycle); + local->recycle.event = offsetof(VCHIQ_STATE_T, recycle_event); + remote_event_create(state, &local->recycle); local->slot_queue_recycle = state->slot_queue_available; - local->sync_trigger.event = &state->sync_trigger_event; - remote_event_create(&local->sync_trigger); + local->sync_trigger.event = offsetof(VCHIQ_STATE_T, sync_trigger_event); + remote_event_create(state, &local->sync_trigger); - local->sync_release.event = &state->sync_release_event; - remote_event_create(&local->sync_release); + local->sync_release.event = offsetof(VCHIQ_STATE_T, sync_release_event); + remote_event_create(state, &local->sync_release); /* At start-of-day, the slot is empty and available */ ((VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state, local->slot_sync))->msgid = VCHIQ_MSGID_PADDING; - remote_event_signal_local(&local->sync_release); + remote_event_signal_local(state, &local->sync_release); local->debug[DEBUG_ENTRIES] = DEBUG_MAX; @@ -3381,7 +3401,7 @@ vchiq_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, (dir == VCHIQ_BULK_TRANSMIT) ? VCHIQ_POLL_TXNOTIFY : VCHIQ_POLL_RXNOTIFY); } else { - int payload[2] = { (int)bulk->data, bulk->size }; + uint32_t payload[2] = { (uint32_t)(uintptr_t)bulk->data, bulk->size }; VCHIQ_ELEMENT_T element = { payload, sizeof(payload) }; status = queue_message(state, NULL, @@ -3525,7 +3545,6 @@ static void release_message_sync(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header) { header->msgid = VCHIQ_MSGID_PADDING; - wmb(); remote_event_signal(&state->remote->sync_release); } diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.h index 38ede407f4f4..4e3f41203bc4 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.h @@ -184,12 +184,21 @@ enum { #if VCHIQ_ENABLE_DEBUG #define DEBUG_INITIALISE(local) int *debug_ptr = (local)->debug; +#if defined(__aarch64__) +#define DEBUG_TRACE(d) \ + do { debug_ptr[DEBUG_ ## d] = __LINE__; dsb(sy); } while (0) +#define DEBUG_VALUE(d, v) \ + do { debug_ptr[DEBUG_ ## d] = (v); dsb(sy); } while (0) +#define DEBUG_COUNT(d) \ + do { debug_ptr[DEBUG_ ## d]++; dsb(sy); } while (0) +#else #define DEBUG_TRACE(d) \ do { debug_ptr[DEBUG_ ## d] = __LINE__; dsb(); } while (0) #define DEBUG_VALUE(d, v) \ do { debug_ptr[DEBUG_ ## d] = (v); dsb(); } while (0) #define DEBUG_COUNT(d) \ do { debug_ptr[DEBUG_ ## d]++; dsb(); } while (0) +#endif #else /* VCHIQ_ENABLE_DEBUG */ @@ -265,7 +274,7 @@ typedef struct vchiq_bulk_queue_struct { typedef struct remote_event_struct { int armed; int fired; - struct semaphore *event; + uint32_t event; } REMOTE_EVENT_T; typedef struct opaque_platform_state_t *VCHIQ_PLATFORM_STATE_T; diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h index 617479eff136..90348ca4b0d0 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h @@ -127,4 +127,125 @@ typedef struct { #define VCHIQ_IOC_CLOSE_DELIVERED _IO(VCHIQ_IOC_MAGIC, 17) #define VCHIQ_IOC_MAX 17 + +/* + * COMPAT_FREEBSD32 + */ + +typedef struct { + unsigned int config_size; + /*VCHIQ_CONFIG_T * */ uint32_t pconfig; +} VCHIQ_GET_CONFIG32_T; + +typedef struct { + unsigned int handle; + /*void * */ uint32_t data; + unsigned int size; + /*void * */ uint32_t userdata; + VCHIQ_BULK_MODE_T mode; +} VCHIQ_QUEUE_BULK_TRANSFER32_T; + +typedef struct { + unsigned int handle; + unsigned int count; + const /*VCHIQ_ELEMENT_T * */ uint32_t elements; +} VCHIQ_QUEUE_MESSAGE32_T; + +typedef struct { + unsigned int handle; + int blocking; + unsigned int bufsize; + /*void * */ uint32_t buf; +} VCHIQ_DEQUEUE_MESSAGE32_T; + +typedef struct { + /*void * */ uint32_t virt_addr; + /*size_t*/ uint32_t num_bytes; +} VCHIQ_DUMP_MEM32_T; + +typedef struct { + VCHIQ_REASON_T reason; + /* VCHIQ_HEADER_T * */ uint32_t header; + /* void * */ uint32_t service_userdata; + /* void * */ uint32_t bulk_userdata; +} VCHIQ_COMPLETION_DATA32_T; + +typedef struct { + unsigned int count; + /* VCHIQ_COMPLETION_DATA32_T * */ uint32_t buf; + unsigned int msgbufsize; + unsigned int msgbufcount; /* IN/OUT */ + /* void ** */ uint32_t msgbufs; +} VCHIQ_AWAIT_COMPLETION32_T; + +typedef struct vchiq_service_params32_struct { + int fourcc; + /* VCHIQ_CALLBACK_T */ uint32_t callback; + /*void * */ uint32_t userdata; + short version; /* Increment for non-trivial changes */ + short version_min; /* Update for incompatible changes */ +} VCHIQ_SERVICE_PARAMS32_T; + +typedef struct { + VCHIQ_SERVICE_PARAMS32_T params; + int is_open; + int is_vchi; + unsigned int handle; /* OUT */ +} VCHIQ_CREATE_SERVICE32_T; + +typedef struct { + const /*void */ uint32_t data; + unsigned int size; +} VCHIQ_ELEMENT32_T; + + +#define VCHIQ_IOC_GET_CONFIG32 \ + _IOC_NEWTYPE( \ + VCHIQ_IOC_GET_CONFIG, \ + VCHIQ_GET_CONFIG32_T \ + ) + +#define VCHIQ_IOC_QUEUE_BULK_TRANSMIT32 \ + _IOC_NEWTYPE( \ + VCHIQ_IOC_QUEUE_BULK_TRANSMIT, \ + VCHIQ_QUEUE_BULK_TRANSFER32_T \ + ) + +#define VCHIQ_IOC_QUEUE_BULK_RECEIVE32 \ + _IOC_NEWTYPE( \ + VCHIQ_IOC_QUEUE_BULK_RECEIVE, \ + VCHIQ_QUEUE_BULK_TRANSFER32_T \ + ) + +#define VCHIQ_IOC_QUEUE_MESSAGE32 \ + _IOC_NEWTYPE( \ + VCHIQ_IOC_QUEUE_MESSAGE, \ + VCHIQ_QUEUE_MESSAGE32_T \ + ) + +#define VCHIQ_IOC_DEQUEUE_MESSAGE32 \ + _IOC_NEWTYPE( \ + VCHIQ_IOC_DEQUEUE_MESSAGE, \ + VCHIQ_DEQUEUE_MESSAGE32_T \ + ) + +#define VCHIQ_IOC_DUMP_PHYS_MEM32 \ + _IOC_NEWTYPE( \ + VCHIQ_IOC_DUMP_PHYS_MEM, \ + VCHIQ_DUMP_MEM32_T \ + ) + +#define VCHIQ_IOC_AWAIT_COMPLETION32 \ + _IOC_NEWTYPE( \ + VCHIQ_IOC_AWAIT_COMPLETION, \ + VCHIQ_AWAIT_COMPLETION32_T \ + ) + +#define VCHIQ_IOC_CREATE_SERVICE32 \ + _IOC_NEWTYPE( \ + VCHIQ_IOC_CREATE_SERVICE, \ + VCHIQ_CREATE_SERVICE32_T \ + ) + + #endif diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c index 190b6d16781e..9fcc0e7c2051 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c @@ -47,7 +47,11 @@ __FBSDID("$FreeBSD$"); #include <dev/ofw/ofw_bus_subr.h> #include <machine/bus.h> +/* XXXMDC Is this necessary at all? */ +#if defined(__aarch64__) +#else #include <machine/fdt.h> +#endif #include "vchiq_arm.h" #include "vchiq_2835.h" @@ -78,13 +82,31 @@ struct bcm_vchiq_softc { static struct bcm_vchiq_softc *bcm_vchiq_sc = NULL; -#define BSD_DTB 1 -#define UPSTREAM_DTB 2 + +#define CONFIG_INVALID 0 +#define CONFIG_VALID 1 << 0 +#define BSD_REG_ADDRS 1 << 1 +#define LONG_BULK_SPACE 1 << 2 + +/* + * Also controls the use of the standard VC address offset for bulk data DMA + * (normal bulks use that offset; bulks for long address spaces use physical + * page addresses) + */ +extern unsigned int g_long_bulk_space; + + +/* + * XXXMDC + * The man page for ofw_bus_is_compatible describes ``features'' + * as ``can be used''. Here we use understand them as ``must be used'' + */ + static struct ofw_compat_data compat_data[] = { - {"broadcom,bcm2835-vchiq", BSD_DTB}, - {"brcm,bcm2835-vchiq", UPSTREAM_DTB}, - {"brcm,bcm2711-vchiq", UPSTREAM_DTB}, - {NULL, 0} + {"broadcom,bcm2835-vchiq", BSD_REG_ADDRS | CONFIG_VALID}, + {"brcm,bcm2835-vchiq", CONFIG_VALID}, + {"brcm,bcm2711-vchiq", LONG_BULK_SPACE | CONFIG_VALID}, + {NULL, CONFIG_INVALID} }; #define vchiq_read_4(reg) \ @@ -119,13 +141,23 @@ bcm_vchiq_intr(void *arg) void remote_event_signal(REMOTE_EVENT_T *event) { - event->fired = 1; + wmb(); + + event->fired = 1; /* The test on the next line also ensures the write on the previous line has completed */ + /* UPDATE: not on arm64, it would seem... */ +#if defined(__aarch64__) + dsb(sy); +#endif if (event->armed) { /* trigger vc interrupt */ +#if defined(__aarch64__) + dsb(sy); +#else dsb(); +#endif vchiq_write_4(0x48, 0); } } @@ -134,13 +166,17 @@ static int bcm_vchiq_probe(device_t dev) { - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + if ((ofw_bus_search_compatible(dev, compat_data)->ocd_data & CONFIG_VALID) == 0) return (ENXIO); device_set_desc(dev, "BCM2835 VCHIQ"); return (BUS_PROBE_DEFAULT); } +/* debug_sysctl */ +extern int vchiq_core_log_level; +extern int vchiq_arm_log_level; + static int bcm_vchiq_attach(device_t dev) { @@ -168,14 +204,36 @@ bcm_vchiq_attach(device_t dev) return (ENXIO); } - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == UPSTREAM_DTB) + uintptr_t dev_compat_d = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + /* XXXMDC: shouldn't happen (checked for in probe)--but, for symmetry */ + if ((dev_compat_d & CONFIG_VALID) == 0){ + device_printf(dev, "attempting to attach using invalid config.\n"); + bus_release_resource(dev, SYS_RES_IRQ, rid, sc->irq_res); + return (EINVAL); + } + if ((dev_compat_d & BSD_REG_ADDRS) == 0) sc->regs_offset = -0x40; + if(dev_compat_d & LONG_BULK_SPACE) + g_long_bulk_space = 1; node = ofw_bus_get_node(dev); if ((OF_getencprop(node, "cache-line-size", &cell, sizeof(cell))) > 0) g_cache_line_size = cell; vchiq_core_initialize(); + + /* debug_sysctl */ + struct sysctl_ctx_list *ctx_l = device_get_sysctl_ctx(dev); + struct sysctl_oid *tree_node = device_get_sysctl_tree(dev); + struct sysctl_oid_list *tree = SYSCTL_CHILDREN(tree_node); + SYSCTL_ADD_INT( + ctx_l, tree, OID_AUTO, "log", CTLFLAG_RW, + &vchiq_core_log_level, vchiq_core_log_level, "log level" + ); + SYSCTL_ADD_INT( + ctx_l, tree, OID_AUTO, "arm_log", CTLFLAG_RW, + &vchiq_arm_log_level, vchiq_arm_log_level, "arm log level" + ); /* Setup and enable the timer */ if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h index 72c362464cc2..d1cb9f1e1658 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h @@ -42,10 +42,10 @@ #define PAGELIST_READ_WITH_FRAGMENTS 2 typedef struct pagelist_struct { - unsigned long length; - unsigned short type; - unsigned short offset; - unsigned long addrs[1]; /* N.B. 12 LSBs hold the number of following + uint32_t length; + uint16_t type; + uint16_t offset; + uint32_t addrs[1]; /* N.B. 12 LSBs hold the number of following pages at consecutive addresses. */ } PAGELIST_T; diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_shim.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_shim.c index cc8ef2e071f8..f33c545cea45 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_shim.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_shim.c @@ -398,7 +398,7 @@ EXPORT_SYMBOL(vchi_msg_queuev); ***********************************************************/ int32_t vchi_held_msg_release(VCHI_HELD_MSG_T *message) { - vchiq_release_message((VCHIQ_SERVICE_HANDLE_T)message->service, + vchiq_release_message((VCHIQ_SERVICE_HANDLE_T)(size_t)message->service, (VCHIQ_HEADER_T *)message->message); return 0; @@ -444,7 +444,7 @@ int32_t vchi_msg_hold(VCHI_SERVICE_HANDLE_T handle, *msg_size = header->size; message_handle->service = - (struct opaque_vchi_service_t *)service->handle; + (struct opaque_vchi_service_t *)(unsigned long)service->handle; message_handle->message = header; return 0; diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index f9b9a386c0c5..2cd6c8bd4758 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -92,6 +92,7 @@ struct acpi_cpu_softc { int cpu_non_c2; /* Index of lowest non-C2 state. */ int cpu_non_c3; /* Index of lowest non-C3 state. */ u_int cpu_cx_stats[MAX_CX_STATES];/* Cx usage history. */ + uint64_t cpu_cx_duration[MAX_CX_STATES];/* Cx cumulative sleep */ /* Values for sysctl. */ struct sysctl_ctx_list cpu_sysctl_ctx; struct sysctl_oid *cpu_sysctl_tree; @@ -185,6 +186,7 @@ static void acpi_cpu_quirks(void); static void acpi_cpu_quirks_piix4(void); static int acpi_cpu_usage_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_cpu_usage_counters_sysctl(SYSCTL_HANDLER_ARGS); +static int acpi_cpu_duration_counters_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_cpu_set_cx_lowest(struct acpi_cpu_softc *sc); static int acpi_cpu_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_cpu_global_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS); @@ -1055,6 +1057,12 @@ acpi_cpu_startup_cx(struct acpi_cpu_softc *sc) "cx_usage_counters", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, (void *)sc, 0, acpi_cpu_usage_counters_sysctl, "A", "Cx sleep state counters"); + SYSCTL_ADD_PROC(&sc->cpu_sysctl_ctx, + SYSCTL_CHILDREN(device_get_sysctl_tree(sc->cpu_dev)), OID_AUTO, + "cx_duration_counters", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, + (void *)sc, 0, acpi_cpu_duration_counters_sysctl, "A", + "Cx sleep duration cumulative time"); + #if defined(__i386__) || defined(__amd64__) SYSCTL_ADD_PROC(&sc->cpu_sysctl_ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(sc->cpu_dev)), OID_AUTO, @@ -1168,6 +1176,7 @@ acpi_cpu_idle(sbintime_t sbt) if (!cx_next->do_mwait && curthread->td_critnest == 0) end_time = min(end_time, 500000 / hz); sc->cpu_prev_sleep = (sc->cpu_prev_sleep * 3 + end_time) / 4; + sc->cpu_cx_duration[cx_next_idx] += end_time; return; } @@ -1224,6 +1233,7 @@ acpi_cpu_idle(sbintime_t sbt) else end_time = ((end_ticks - start_ticks) << 20) / cpu_tickrate(); sc->cpu_prev_sleep = (sc->cpu_prev_sleep * 3 + end_time) / 4; + sc->cpu_cx_duration[cx_next_idx] += end_time; } #endif @@ -1408,6 +1418,26 @@ acpi_cpu_usage_counters_sysctl(SYSCTL_HANDLER_ARGS) return (error); } +static int +acpi_cpu_duration_counters_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct acpi_cpu_softc *sc = (struct acpi_cpu_softc *)arg1; + struct sbuf sb; + char buf[128]; + int error, i; + + sbuf_new_for_sysctl(&sb, buf, sizeof(buf), req); + for (i = 0; i < sc->cpu_cx_count; i++) { + if (i > 0) + sbuf_putc(&sb, ' '); + sbuf_printf(&sb, "%ju", (uintmax_t) sc->cpu_cx_duration[i]); + } + error = sbuf_finish(&sb); + sbuf_delete(&sb); + return (error); +} + + #if defined(__i386__) || defined(__amd64__) static int acpi_cpu_method_sysctl(SYSCTL_HANDLER_ARGS) diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index 55f09fefb7e3..38875b535067 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -184,7 +184,16 @@ enum { DF_LOAD_FW_ANYTIME = (1 << 1), /* Allow LOAD_FW after init */ DF_DISABLE_TCB_CACHE = (1 << 2), /* Disable TCB cache (T6+) */ DF_DISABLE_CFG_RETRY = (1 << 3), /* Disable fallback config */ - DF_VERBOSE_SLOWINTR = (1 << 4), /* Chatty slow intr handler */ + + /* adapter intr handler flags */ + IHF_INTR_CLEAR_ON_INIT = (1 << 0), /* Driver calls t4_intr_clear */ + IHF_NO_SHOW = (1 << 1), /* Do not display intr info */ + IHF_VERBOSE = (1 << 2), /* Display extra intr info */ + IHF_FATAL_IFF_ENABLED = (1 << 3), /* Fatal only if enabled */ + IHF_IGNORE_IF_DISABLED = (1 << 4), /* Ignore if disabled */ + IHF_CLR_ALL_SET = (1 << 5), /* Clear all set bits */ + IHF_CLR_ALL_UNIGNORED = (1 << 6), /* Clear all unignored bits */ + IHF_RUN_ALL_ACTIONS = (1 << 7), /* As if all cause are set */ }; #define IS_DETACHING(vi) ((vi)->flags & VI_DETACHING) @@ -723,6 +732,16 @@ struct sge_ofld_rxq { uint64_t rx_iscsi_padding_errors; uint64_t rx_iscsi_header_digest_errors; uint64_t rx_iscsi_data_digest_errors; + counter_u64_t rx_nvme_ddp_setup_ok; + counter_u64_t rx_nvme_ddp_setup_no_stag; + counter_u64_t rx_nvme_ddp_setup_error; + counter_u64_t rx_nvme_ddp_pdus; + counter_u64_t rx_nvme_ddp_octets; + counter_u64_t rx_nvme_fl_pdus; + counter_u64_t rx_nvme_fl_octets; + counter_u64_t rx_nvme_invalid_headers; + counter_u64_t rx_nvme_header_digest_errors; + counter_u64_t rx_nvme_data_digest_errors; uint64_t rx_aio_ddp_jobs; uint64_t rx_aio_ddp_octets; u_long rx_toe_tls_records; @@ -795,6 +814,9 @@ struct sge_ofld_txq { counter_u64_t tx_iscsi_pdus; counter_u64_t tx_iscsi_octets; counter_u64_t tx_iscsi_iso_wrs; + counter_u64_t tx_nvme_pdus; + counter_u64_t tx_nvme_octets; + counter_u64_t tx_nvme_iso_wrs; counter_u64_t tx_aio_jobs; counter_u64_t tx_aio_octets; counter_u64_t tx_toe_tls_records; @@ -997,6 +1019,7 @@ struct adapter { void *iwarp_softc; /* (struct c4iw_dev *) */ struct iw_tunables iwt; void *iscsi_ulp_softc; /* (struct cxgbei_data *) */ + void *nvme_ulp_softc; /* (struct nvmf_che_adapter *) */ struct l2t_data *l2t; /* L2 table */ struct smt_data *smt; /* Source MAC Table */ struct tid_info tids; @@ -1013,6 +1036,7 @@ struct adapter { int flags; int debug_flags; int error_flags; /* Used by error handler and live reset. */ + int intr_flags; /* Used by interrupt setup/handlers. */ char ifp_lockname[16]; struct mtx ifp_lock; diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h index 6b36832a7464..2033967ffb94 100644 --- a/sys/dev/cxgbe/common/common.h +++ b/sys/dev/cxgbe/common/common.h @@ -684,9 +684,10 @@ u32 t4_hw_pci_read_cfg4(adapter_t *adapter, int reg); struct fw_filter_wr; +void t4_intr_clear(struct adapter *adapter); void t4_intr_enable(struct adapter *adapter); void t4_intr_disable(struct adapter *adapter); -bool t4_slow_intr_handler(struct adapter *adapter, bool verbose); +bool t4_slow_intr_handler(struct adapter *adapter, int flags); int t4_hash_mac_addr(const u8 *addr); int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port, diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index eb7ea9acc108..65292486cbc8 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -84,6 +84,41 @@ static inline int t4_wait_op_done(struct adapter *adapter, int reg, u32 mask, delay, NULL); } + /** + * t7_wait_sram_done - wait until an operation is completed + * @adapter: the adapter performing the operation + * @reg: the register to check for completion + * @result_reg: register that holds the result value + * @attempts: number of check iterations + * @delay: delay in usecs between iterations + * @valp: where to store the value of the result register at completion time + * + * Waits until a specific bit in @reg is cleared, checking up to + * @attempts times.Once the bit is cleared, reads from @result_reg + * and stores the value in @valp if it is not NULL. Returns 0 if the + * operation completes successfully and -EAGAIN if it times out. + */ +static int t7_wait_sram_done(struct adapter *adap, int reg, int result_reg, + int attempts, int delay, u32 *valp) +{ + while (1) { + u32 val = t4_read_reg(adap, reg); + + /* Check if SramStart (bit 19) is cleared */ + if (!(val & (1 << 19))) { + if (valp) + *valp = t4_read_reg(adap, result_reg); + return 0; + } + + if (--attempts == 0) + return -EAGAIN; + + if (delay) + udelay(delay); + } +} + /** * t4_set_reg_field - set a register field to a value * @adapter: the adapter to program @@ -535,11 +570,11 @@ static int t4_edc_err_read(struct adapter *adap, int idx) edc_bist_status_rdata_reg = EDC_T5_REG(A_EDC_H_BIST_STATUS_RDATA, idx); CH_WARN(adap, - "edc%d err addr 0x%x: 0x%x.\n", + " edc%d err addr 0x%x: 0x%x.\n", idx, edc_ecc_err_addr_reg, t4_read_reg(adap, edc_ecc_err_addr_reg)); CH_WARN(adap, - "bist: 0x%x, status %llx %llx %llx %llx %llx %llx %llx %llx %llx.\n", + " bist: 0x%x, status %llx %llx %llx %llx %llx %llx %llx %llx %llx.\n", edc_bist_status_rdata_reg, (unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg), (unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 8), @@ -578,14 +613,15 @@ int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) mc_bist_cmd_len_reg = A_MC_BIST_CMD_LEN; mc_bist_status_rdata_reg = A_MC_BIST_STATUS_RDATA; mc_bist_data_pattern_reg = A_MC_BIST_DATA_PATTERN; - } else { + } else if (chip_id(adap) < CHELSIO_T7) { mc_bist_cmd_reg = MC_REG(A_MC_P_BIST_CMD, idx); mc_bist_cmd_addr_reg = MC_REG(A_MC_P_BIST_CMD_ADDR, idx); mc_bist_cmd_len_reg = MC_REG(A_MC_P_BIST_CMD_LEN, idx); - mc_bist_status_rdata_reg = MC_REG(A_MC_P_BIST_STATUS_RDATA, - idx); - mc_bist_data_pattern_reg = MC_REG(A_MC_P_BIST_DATA_PATTERN, - idx); + mc_bist_status_rdata_reg = MC_REG(A_MC_P_BIST_STATUS_RDATA, idx); + mc_bist_data_pattern_reg = MC_REG(A_MC_P_BIST_DATA_PATTERN, idx); + } else { + /* Need to figure out split mode and the rest. */ + return (-ENOTSUP); } if (t4_read_reg(adap, mc_bist_cmd_reg) & F_START_BIST) @@ -636,21 +672,13 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) edc_bist_status_rdata_reg = EDC_REG(A_EDC_BIST_STATUS_RDATA, idx); } else { -/* - * These macro are missing in t4_regs.h file. - * Added temporarily for testing. - */ -#define EDC_STRIDE_T5 (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR) -#define EDC_REG_T5(reg, idx) (reg + EDC_STRIDE_T5 * idx) - edc_bist_cmd_reg = EDC_REG_T5(A_EDC_H_BIST_CMD, idx); - edc_bist_cmd_addr_reg = EDC_REG_T5(A_EDC_H_BIST_CMD_ADDR, idx); - edc_bist_cmd_len_reg = EDC_REG_T5(A_EDC_H_BIST_CMD_LEN, idx); - edc_bist_cmd_data_pattern = EDC_REG_T5(A_EDC_H_BIST_DATA_PATTERN, + edc_bist_cmd_reg = EDC_T5_REG(A_EDC_H_BIST_CMD, idx); + edc_bist_cmd_addr_reg = EDC_T5_REG(A_EDC_H_BIST_CMD_ADDR, idx); + edc_bist_cmd_len_reg = EDC_T5_REG(A_EDC_H_BIST_CMD_LEN, idx); + edc_bist_cmd_data_pattern = EDC_T5_REG(A_EDC_H_BIST_DATA_PATTERN, idx); - edc_bist_status_rdata_reg = EDC_REG_T5(A_EDC_H_BIST_STATUS_RDATA, + edc_bist_status_rdata_reg = EDC_T5_REG(A_EDC_H_BIST_STATUS_RDATA, idx); -#undef EDC_REG_T5 -#undef EDC_STRIDE_T5 } if (t4_read_reg(adap, edc_bist_cmd_reg) & F_START_BIST) @@ -2662,10 +2690,9 @@ void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size) 0x173c, 0x1760, 0x1800, 0x18fc, 0x3000, 0x3044, - 0x3060, 0x3064, 0x30a4, 0x30b0, 0x30b8, 0x30d8, - 0x30e0, 0x30fc, + 0x30e0, 0x30e8, 0x3140, 0x357c, 0x35a8, 0x35cc, 0x35e0, 0x35ec, @@ -2680,7 +2707,7 @@ void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size) 0x480c, 0x4814, 0x4890, 0x489c, 0x48a4, 0x48ac, - 0x48b8, 0x48c4, + 0x48b8, 0x48bc, 0x4900, 0x4924, 0x4ffc, 0x4ffc, 0x5500, 0x5624, @@ -2698,8 +2725,10 @@ void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size) 0x5a60, 0x5a6c, 0x5a80, 0x5a8c, 0x5a94, 0x5a9c, - 0x5b94, 0x5bfc, - 0x5c10, 0x5e48, + 0x5b94, 0x5bec, + 0x5bf8, 0x5bfc, + 0x5c10, 0x5c40, + 0x5c4c, 0x5e48, 0x5e50, 0x5e94, 0x5ea0, 0x5eb0, 0x5ec0, 0x5ec0, @@ -2708,7 +2737,8 @@ void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size) 0x5ef0, 0x5ef0, 0x5f00, 0x5f04, 0x5f0c, 0x5f10, - 0x5f20, 0x5f88, + 0x5f20, 0x5f78, + 0x5f84, 0x5f88, 0x5f90, 0x5fd8, 0x6000, 0x6020, 0x6028, 0x6030, @@ -3084,7 +3114,7 @@ void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size) 0x38140, 0x38140, 0x38150, 0x38154, 0x38160, 0x381c4, - 0x381f0, 0x38204, + 0x381d0, 0x38204, 0x3820c, 0x38214, 0x3821c, 0x3822c, 0x38244, 0x38244, @@ -3156,6 +3186,10 @@ void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size) 0x3a000, 0x3a004, 0x3a050, 0x3a084, 0x3a090, 0x3a09c, + 0x3a93c, 0x3a93c, + 0x3b93c, 0x3b93c, + 0x3c93c, 0x3c93c, + 0x3d93c, 0x3d93c, 0x3e000, 0x3e020, 0x3e03c, 0x3e05c, 0x3e100, 0x3e120, @@ -4743,10 +4777,9 @@ struct intr_details { struct intr_action { u32 mask; int arg; - bool (*action)(struct adapter *, int, bool); + bool (*action)(struct adapter *, int, int); }; -#define NONFATAL_IF_DISABLED 1 struct intr_info { const char *name; /* name of the INT_CAUSE register */ int cause_reg; /* INT_CAUSE register */ @@ -4769,73 +4802,78 @@ intr_alert_char(u32 cause, u32 enable, u32 fatal) } static void -t4_show_intr_info(struct adapter *adap, const struct intr_info *ii, u32 cause) +show_intr_info(struct adapter *sc, const struct intr_info *ii, uint32_t cause, + uint32_t ucause, uint32_t enabled, uint32_t fatal, int flags) { - u32 enable, fatal, leftover; + uint32_t leftover, msgbits; const struct intr_details *details; char alert; + const bool verbose = flags & IHF_VERBOSE; - enable = t4_read_reg(adap, ii->enable_reg); - if (ii->flags & NONFATAL_IF_DISABLED) - fatal = ii->fatal & t4_read_reg(adap, ii->enable_reg); - else - fatal = ii->fatal; - alert = intr_alert_char(cause, enable, fatal); - CH_ALERT(adap, "%c %s 0x%x = 0x%08x, E 0x%08x, F 0x%08x\n", - alert, ii->name, ii->cause_reg, cause, enable, fatal); + if (verbose || ucause != 0 || flags & IHF_RUN_ALL_ACTIONS) { + alert = intr_alert_char(cause, enabled, fatal); + CH_ALERT(sc, "%c %s 0x%x = 0x%08x, E 0x%08x, F 0x%08x\n", alert, + ii->name, ii->cause_reg, cause, enabled, fatal); + } - leftover = cause; + leftover = verbose ? cause : ucause; for (details = ii->details; details && details->mask != 0; details++) { - u32 msgbits = details->mask & cause; + msgbits = details->mask & leftover; if (msgbits == 0) continue; - alert = intr_alert_char(msgbits, enable, ii->fatal); - CH_ALERT(adap, " %c [0x%08x] %s\n", alert, msgbits, - details->msg); + alert = intr_alert_char(msgbits, enabled, fatal); + CH_ALERT(sc, " %c [0x%08x] %s\n", alert, msgbits, details->msg); leftover &= ~msgbits; } - if (leftover != 0 && leftover != cause) - CH_ALERT(adap, " ? [0x%08x]\n", leftover); + if (leftover != 0 && leftover != (verbose ? cause : ucause)) + CH_ALERT(sc, " ? [0x%08x]\n", leftover); } /* * Returns true for fatal error. */ static bool -t4_handle_intr(struct adapter *adap, const struct intr_info *ii, - u32 additional_cause, bool verbose) +t4_handle_intr(struct adapter *sc, const struct intr_info *ii, uint32_t acause, + int flags) { - u32 cause, fatal; + uint32_t cause, ucause, enabled, fatal; bool rc; const struct intr_action *action; - /* - * Read and display cause. Note that the top level PL_INT_CAUSE is a - * bit special and we need to completely ignore the bits that are not in - * PL_INT_ENABLE. - */ - cause = t4_read_reg(adap, ii->cause_reg); - if (ii->cause_reg == A_PL_INT_CAUSE) - cause &= t4_read_reg(adap, ii->enable_reg); - if (verbose || cause != 0) - t4_show_intr_info(adap, ii, cause); - fatal = cause & ii->fatal; - if (fatal != 0 && ii->flags & NONFATAL_IF_DISABLED) - fatal &= t4_read_reg(adap, ii->enable_reg); - cause |= additional_cause; - if (cause == 0) - return (false); + cause = t4_read_reg(sc, ii->cause_reg); + enabled = t4_read_reg(sc, ii->enable_reg); + flags |= ii->flags; + fatal = ii->fatal & cause; + if (flags & IHF_FATAL_IFF_ENABLED) + fatal &= enabled; + ucause = cause; + if (flags & IHF_IGNORE_IF_DISABLED) + ucause &= enabled; + if (!(flags & IHF_NO_SHOW)) + show_intr_info(sc, ii, cause, ucause, enabled, fatal, flags); rc = fatal != 0; for (action = ii->actions; action && action->mask != 0; action++) { - if (!(action->mask & cause)) + if (action->action == NULL) continue; - rc |= (action->action)(adap, action->arg, verbose); + if (action->mask & (ucause | acause) || + flags & IHF_RUN_ALL_ACTIONS) { + bool rc1 = (action->action)(sc, action->arg, flags); + if (action->mask & ucause) + rc |= rc1; + } } /* clear */ - t4_write_reg(adap, ii->cause_reg, cause); - (void)t4_read_reg(adap, ii->cause_reg); + if (cause != 0) { + if (flags & IHF_CLR_ALL_SET) { + t4_write_reg(sc, ii->cause_reg, cause); + (void)t4_read_reg(sc, ii->cause_reg); + } else if (ucause != 0 && flags & IHF_CLR_ALL_UNIGNORED) { + t4_write_reg(sc, ii->cause_reg, ucause); + (void)t4_read_reg(sc, ii->cause_reg); + } + } return (rc); } @@ -4843,7 +4881,7 @@ t4_handle_intr(struct adapter *adap, const struct intr_info *ii, /* * Interrupt handler for the PCIE module. */ -static bool pcie_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool pcie_intr_handler(struct adapter *adap, int arg, int flags) { static const struct intr_details sysbus_intr_details[] = { { F_RNPP, "RXNP array parity error" }, @@ -4956,21 +4994,43 @@ static bool pcie_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_PCIE_INT_CAUSE, .enable_reg = A_PCIE_INT_ENABLE, .fatal = 0xffffffff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + struct intr_info pcie_int_cause_ext = { + .name = "PCIE_INT_CAUSE_EXT", + .cause_reg = A_PCIE_INT_CAUSE_EXT, + .enable_reg = A_PCIE_INT_ENABLE_EXT, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; + struct intr_info pcie_int_cause_x8 = { + .name = "PCIE_INT_CAUSE_X8", + .cause_reg = A_PCIE_INT_CAUSE_X8, + .enable_reg = A_PCIE_INT_ENABLE_X8, + .fatal = 0, + .flags = 0, .details = NULL, .actions = NULL, }; bool fatal = false; if (is_t4(adap)) { - fatal |= t4_handle_intr(adap, &sysbus_intr_info, 0, verbose); - fatal |= t4_handle_intr(adap, &pcie_port_intr_info, 0, verbose); + fatal |= t4_handle_intr(adap, &sysbus_intr_info, 0, flags); + fatal |= t4_handle_intr(adap, &pcie_port_intr_info, 0, flags); pcie_intr_info.details = pcie_intr_details; } else { pcie_intr_info.details = t5_pcie_intr_details; } - fatal |= t4_handle_intr(adap, &pcie_intr_info, 0, verbose); + fatal |= t4_handle_intr(adap, &pcie_intr_info, 0, flags); + if (chip_id(adap) > CHELSIO_T6) { + fatal |= t4_handle_intr(adap, &pcie_int_cause_ext, 0, flags); + fatal |= t4_handle_intr(adap, &pcie_int_cause_x8, 0, flags); + } return (fatal); } @@ -4978,7 +5038,7 @@ static bool pcie_intr_handler(struct adapter *adap, int arg, bool verbose) /* * TP interrupt handler. */ -static bool tp_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool tp_intr_handler(struct adapter *adap, int arg, int flags) { static const struct intr_details tp_intr_details[] = { { 0x3fffffff, "TP parity error" }, @@ -4990,25 +5050,90 @@ static bool tp_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_TP_INT_CAUSE, .enable_reg = A_TP_INT_ENABLE, .fatal = 0x7fffffff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = tp_intr_details, .actions = NULL, }; + static const struct intr_info tp_inic_perr_cause = { + .name = "TP_INIC_PERR_CAUSE", + .cause_reg = A_TP_INIC_PERR_CAUSE, + .enable_reg = A_TP_INIC_PERR_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info tp_c_perr_cause = { + .name = "TP_C_PERR_CAUSE", + .cause_reg = A_TP_C_PERR_CAUSE, + .enable_reg = A_TP_C_PERR_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info tp_e_eg_perr_cause = { + .name = "TP_E_EG_PERR_CAUSE", + .cause_reg = A_TP_E_EG_PERR_CAUSE, + .enable_reg = A_TP_E_EG_PERR_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info tp_e_in0_perr_cause = { + .name = "TP_E_IN0_PERR_CAUSE", + .cause_reg = A_TP_E_IN0_PERR_CAUSE, + .enable_reg = A_TP_E_IN0_PERR_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info tp_e_in1_perr_cause = { + .name = "TP_E_IN1_PERR_CAUSE", + .cause_reg = A_TP_E_IN1_PERR_CAUSE, + .enable_reg = A_TP_E_IN1_PERR_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info tp_o_perr_cause = { + .name = "TP_O_PERR_CAUSE", + .cause_reg = A_TP_O_PERR_CAUSE, + .enable_reg = A_TP_O_PERR_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + bool fatal; + + fatal = t4_handle_intr(adap, &tp_intr_info, 0, flags); + if (chip_id(adap) > CHELSIO_T6) { + fatal |= t4_handle_intr(adap, &tp_inic_perr_cause, 0, flags); + fatal |= t4_handle_intr(adap, &tp_c_perr_cause, 0, flags); + fatal |= t4_handle_intr(adap, &tp_e_eg_perr_cause, 0, flags); + fatal |= t4_handle_intr(adap, &tp_e_in0_perr_cause, 0, flags); + fatal |= t4_handle_intr(adap, &tp_e_in1_perr_cause, 0, flags); + fatal |= t4_handle_intr(adap, &tp_o_perr_cause, 0, flags); + } - return (t4_handle_intr(adap, &tp_intr_info, 0, verbose)); + return (fatal); } /* * SGE interrupt handler. */ -static bool sge_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool sge_intr_handler(struct adapter *adap, int arg, int flags) { static const struct intr_info sge_int1_info = { .name = "SGE_INT_CAUSE1", .cause_reg = A_SGE_INT_CAUSE1, .enable_reg = A_SGE_INT_ENABLE1, .fatal = 0xffffffff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = NULL, .actions = NULL, }; @@ -5017,7 +5142,7 @@ static bool sge_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_SGE_INT_CAUSE2, .enable_reg = A_SGE_INT_ENABLE2, .fatal = 0xffffffff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = NULL, .actions = NULL, }; @@ -5115,7 +5240,7 @@ static bool sge_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_SGE_INT_CAUSE5, .enable_reg = A_SGE_INT_ENABLE5, .fatal = 0xffffffff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = NULL, .actions = NULL, }; @@ -5128,7 +5253,24 @@ static bool sge_intr_handler(struct adapter *adap, int arg, bool verbose) .details = NULL, .actions = NULL, }; - + static const struct intr_info sge_int7_info = { + .name = "SGE_INT_CAUSE7", + .cause_reg = A_SGE_INT_CAUSE7, + .enable_reg = A_SGE_INT_ENABLE7, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info sge_int8_info = { + .name = "SGE_INT_CAUSE8", + .cause_reg = A_SGE_INT_CAUSE8, + .enable_reg = A_SGE_INT_ENABLE8, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; bool fatal; u32 v; @@ -5139,14 +5281,18 @@ static bool sge_intr_handler(struct adapter *adap, int arg, bool verbose) } fatal = false; - fatal |= t4_handle_intr(adap, &sge_int1_info, 0, verbose); - fatal |= t4_handle_intr(adap, &sge_int2_info, 0, verbose); - fatal |= t4_handle_intr(adap, &sge_int3_info, 0, verbose); - fatal |= t4_handle_intr(adap, &sge_int4_info, 0, verbose); + fatal |= t4_handle_intr(adap, &sge_int1_info, 0, flags); + fatal |= t4_handle_intr(adap, &sge_int2_info, 0, flags); + fatal |= t4_handle_intr(adap, &sge_int3_info, 0, flags); + fatal |= t4_handle_intr(adap, &sge_int4_info, 0, flags); if (chip_id(adap) >= CHELSIO_T5) - fatal |= t4_handle_intr(adap, &sge_int5_info, 0, verbose); + fatal |= t4_handle_intr(adap, &sge_int5_info, 0, flags); if (chip_id(adap) >= CHELSIO_T6) - fatal |= t4_handle_intr(adap, &sge_int6_info, 0, verbose); + fatal |= t4_handle_intr(adap, &sge_int6_info, 0, flags); + if (chip_id(adap) >= CHELSIO_T7) { + fatal |= t4_handle_intr(adap, &sge_int7_info, 0, flags); + fatal |= t4_handle_intr(adap, &sge_int8_info, 0, flags); + } v = t4_read_reg(adap, A_SGE_ERROR_STATS); if (v & F_ERROR_QID_VALID) { @@ -5163,7 +5309,7 @@ static bool sge_intr_handler(struct adapter *adap, int arg, bool verbose) /* * CIM interrupt handler. */ -static bool cim_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool cim_intr_handler(struct adapter *adap, int arg, int flags) { static const struct intr_details cim_host_intr_details[] = { /* T6+ */ @@ -5208,7 +5354,7 @@ static bool cim_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_CIM_HOST_INT_CAUSE, .enable_reg = A_CIM_HOST_INT_ENABLE, .fatal = 0x007fffe6, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = cim_host_intr_details, .actions = NULL, }; @@ -5259,7 +5405,7 @@ static bool cim_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_CIM_HOST_UPACC_INT_CAUSE, .enable_reg = A_CIM_HOST_UPACC_INT_ENABLE, .fatal = 0x3fffeeff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = cim_host_upacc_intr_details, .actions = NULL, }; @@ -5272,6 +5418,15 @@ static bool cim_intr_handler(struct adapter *adap, int arg, bool verbose) .details = NULL, .actions = NULL, }; + static const struct intr_info cim_perr_cause = { + .name = "CIM_PERR_CAUSE", + .cause_reg = A_CIM_PERR_CAUSE, + .enable_reg = A_CIM_PERR_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; u32 val, fw_err; bool fatal; @@ -5290,9 +5445,11 @@ static bool cim_intr_handler(struct adapter *adap, int arg, bool verbose) } fatal = (fw_err & F_PCIE_FW_ERR) != 0; - fatal |= t4_handle_intr(adap, &cim_host_intr_info, 0, verbose); - fatal |= t4_handle_intr(adap, &cim_host_upacc_intr_info, 0, verbose); - fatal |= t4_handle_intr(adap, &cim_pf_host_intr_info, 0, verbose); + fatal |= t4_handle_intr(adap, &cim_host_intr_info, 0, flags); + fatal |= t4_handle_intr(adap, &cim_host_upacc_intr_info, 0, flags); + fatal |= t4_handle_intr(adap, &cim_pf_host_intr_info, 0, flags); + if (chip_id(adap) > CHELSIO_T6) + fatal |= t4_handle_intr(adap, &cim_perr_cause, 0, flags); if (fatal) t4_os_cim_err(adap); @@ -5302,7 +5459,7 @@ static bool cim_intr_handler(struct adapter *adap, int arg, bool verbose) /* * ULP RX interrupt handler. */ -static bool ulprx_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool ulprx_intr_handler(struct adapter *adap, int arg, int flags) { static const struct intr_details ulprx_intr_details[] = { /* T5+ */ @@ -5320,7 +5477,7 @@ static bool ulprx_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_ULP_RX_INT_CAUSE, .enable_reg = A_ULP_RX_INT_ENABLE, .fatal = 0x07ffffff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = ulprx_intr_details, .actions = NULL, }; @@ -5333,10 +5490,53 @@ static bool ulprx_intr_handler(struct adapter *adap, int arg, bool verbose) .details = NULL, .actions = NULL, }; + static const struct intr_info ulprx_int_cause_pcmd = { + .name = "ULP_RX_INT_CAUSE_PCMD", + .cause_reg = A_ULP_RX_INT_CAUSE_PCMD, + .enable_reg = A_ULP_RX_INT_ENABLE_PCMD, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info ulprx_int_cause_data = { + .name = "ULP_RX_INT_CAUSE_DATA", + .cause_reg = A_ULP_RX_INT_CAUSE_DATA, + .enable_reg = A_ULP_RX_INT_ENABLE_DATA, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info ulprx_int_cause_arb = { + .name = "ULP_RX_INT_CAUSE_ARB", + .cause_reg = A_ULP_RX_INT_CAUSE_ARB, + .enable_reg = A_ULP_RX_INT_ENABLE_ARB, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info ulprx_int_cause_intf = { + .name = "ULP_RX_INT_CAUSE_INTERFACE", + .cause_reg = A_ULP_RX_INT_CAUSE_INTERFACE, + .enable_reg = A_ULP_RX_INT_ENABLE_INTERFACE, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; bool fatal = false; - fatal |= t4_handle_intr(adap, &ulprx_intr_info, 0, verbose); - fatal |= t4_handle_intr(adap, &ulprx_intr2_info, 0, verbose); + fatal |= t4_handle_intr(adap, &ulprx_intr_info, 0, flags); + if (chip_id(adap) < CHELSIO_T7) + fatal |= t4_handle_intr(adap, &ulprx_intr2_info, 0, flags); + else { + fatal |= t4_handle_intr(adap, &ulprx_int_cause_pcmd, 0, flags); + fatal |= t4_handle_intr(adap, &ulprx_int_cause_data, 0, flags); + fatal |= t4_handle_intr(adap, &ulprx_int_cause_arb, 0, flags); + fatal |= t4_handle_intr(adap, &ulprx_int_cause_intf, 0, flags); + } return (fatal); } @@ -5344,7 +5544,7 @@ static bool ulprx_intr_handler(struct adapter *adap, int arg, bool verbose) /* * ULP TX interrupt handler. */ -static bool ulptx_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool ulptx_intr_handler(struct adapter *adap, int arg, int flags) { static const struct intr_details ulptx_intr_details[] = { { F_PBL_BOUND_ERR_CH3, "ULPTX channel 3 PBL out of bounds" }, @@ -5359,32 +5559,98 @@ static bool ulptx_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_ULP_TX_INT_CAUSE, .enable_reg = A_ULP_TX_INT_ENABLE, .fatal = 0x0fffffff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = ulptx_intr_details, .actions = NULL, }; - static const struct intr_info ulptx_intr2_info = { + static const struct intr_info ulptx_intr_info2 = { .name = "ULP_TX_INT_CAUSE_2", .cause_reg = A_ULP_TX_INT_CAUSE_2, .enable_reg = A_ULP_TX_INT_ENABLE_2, - .fatal = 0xf0, - .flags = NONFATAL_IF_DISABLED, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info ulptx_intr_info3 = { + .name = "ULP_TX_INT_CAUSE_3", + .cause_reg = A_ULP_TX_INT_CAUSE_3, + .enable_reg = A_ULP_TX_INT_ENABLE_3, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info ulptx_intr_info4 = { + .name = "ULP_TX_INT_CAUSE_4", + .cause_reg = A_ULP_TX_INT_CAUSE_4, + .enable_reg = A_ULP_TX_INT_ENABLE_4, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info ulptx_intr_info5 = { + .name = "ULP_TX_INT_CAUSE_5", + .cause_reg = A_ULP_TX_INT_CAUSE_5, + .enable_reg = A_ULP_TX_INT_ENABLE_5, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info ulptx_intr_info6 = { + .name = "ULP_TX_INT_CAUSE_6", + .cause_reg = A_ULP_TX_INT_CAUSE_6, + .enable_reg = A_ULP_TX_INT_ENABLE_6, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info ulptx_intr_info7 = { + .name = "ULP_TX_INT_CAUSE_7", + .cause_reg = A_ULP_TX_INT_CAUSE_7, + .enable_reg = A_ULP_TX_INT_ENABLE_7, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info ulptx_intr_info8 = { + .name = "ULP_TX_INT_CAUSE_8", + .cause_reg = A_ULP_TX_INT_CAUSE_8, + .enable_reg = A_ULP_TX_INT_ENABLE_8, + .fatal = 0, + .flags = 0, .details = NULL, .actions = NULL, }; bool fatal = false; - fatal |= t4_handle_intr(adap, &ulptx_intr_info, 0, verbose); - fatal |= t4_handle_intr(adap, &ulptx_intr2_info, 0, verbose); + fatal |= t4_handle_intr(adap, &ulptx_intr_info, 0, flags); + if (chip_id(adap) > CHELSIO_T4) + fatal |= t4_handle_intr(adap, &ulptx_intr_info2, 0, flags); + if (chip_id(adap) > CHELSIO_T6) { + fatal |= t4_handle_intr(adap, &ulptx_intr_info3, 0, flags); + fatal |= t4_handle_intr(adap, &ulptx_intr_info4, 0, flags); + fatal |= t4_handle_intr(adap, &ulptx_intr_info5, 0, flags); + fatal |= t4_handle_intr(adap, &ulptx_intr_info6, 0, flags); + fatal |= t4_handle_intr(adap, &ulptx_intr_info7, 0, flags); + fatal |= t4_handle_intr(adap, &ulptx_intr_info8, 0, flags); + } return (fatal); } -static bool pmtx_dump_dbg_stats(struct adapter *adap, int arg, bool verbose) +static bool pmtx_dump_dbg_stats(struct adapter *adap, int arg, int flags) { int i; u32 data[17]; + if (flags & IHF_NO_SHOW) + return (false); + t4_read_indirect(adap, A_PM_TX_DBG_CTRL, A_PM_TX_DBG_DATA, &data[0], ARRAY_SIZE(data), A_PM_TX_DBG_STAT0); for (i = 0; i < ARRAY_SIZE(data); i++) { @@ -5398,13 +5664,9 @@ static bool pmtx_dump_dbg_stats(struct adapter *adap, int arg, bool verbose) /* * PM TX interrupt handler. */ -static bool pmtx_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool pmtx_intr_handler(struct adapter *adap, int arg, int flags) { - static const struct intr_action pmtx_intr_actions[] = { - { 0xffffffff, 0, pmtx_dump_dbg_stats }, - { 0 }, - }; - static const struct intr_details pmtx_intr_details[] = { + static const struct intr_details pmtx_int_cause_fields[] = { { F_PCMD_LEN_OVFL0, "PMTX channel 0 pcmd too large" }, { F_PCMD_LEN_OVFL1, "PMTX channel 1 pcmd too large" }, { F_PCMD_LEN_OVFL2, "PMTX channel 2 pcmd too large" }, @@ -5421,25 +5683,29 @@ static bool pmtx_intr_handler(struct adapter *adap, int arg, bool verbose) { F_C_PCMD_PAR_ERROR, "PMTX c_pcmd parity error" }, { 0 } }; - static const struct intr_info pmtx_intr_info = { + static const struct intr_action pmtx_int_cause_actions[] = { + { 0xffffffff, -1, pmtx_dump_dbg_stats }, + { 0 }, + }; + static const struct intr_info pmtx_int_cause = { .name = "PM_TX_INT_CAUSE", .cause_reg = A_PM_TX_INT_CAUSE, .enable_reg = A_PM_TX_INT_ENABLE, .fatal = 0xffffffff, .flags = 0, - .details = pmtx_intr_details, - .actions = pmtx_intr_actions, + .details = pmtx_int_cause_fields, + .actions = pmtx_int_cause_actions, }; - return (t4_handle_intr(adap, &pmtx_intr_info, 0, verbose)); + return (t4_handle_intr(adap, &pmtx_int_cause, 0, flags)); } /* * PM RX interrupt handler. */ -static bool pmrx_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool pmrx_intr_handler(struct adapter *adap, int arg, int flags) { - static const struct intr_details pmrx_intr_details[] = { + static const struct intr_details pmrx_int_cause_fields[] = { /* T6+ */ { 0x18000000, "PMRX ospi overflow" }, { F_MA_INTF_SDC_ERR, "PMRX MA interface SDC parity error" }, @@ -5461,25 +5727,25 @@ static bool pmrx_intr_handler(struct adapter *adap, int arg, bool verbose) { F_E_PCMD_PAR_ERROR, "PMRX e_pcmd parity error"}, { 0 } }; - static const struct intr_info pmrx_intr_info = { + static const struct intr_info pmrx_int_cause = { .name = "PM_RX_INT_CAUSE", .cause_reg = A_PM_RX_INT_CAUSE, .enable_reg = A_PM_RX_INT_ENABLE, .fatal = 0x1fffffff, - .flags = NONFATAL_IF_DISABLED, - .details = pmrx_intr_details, + .flags = IHF_FATAL_IFF_ENABLED, + .details = pmrx_int_cause_fields, .actions = NULL, }; - return (t4_handle_intr(adap, &pmrx_intr_info, 0, verbose)); + return (t4_handle_intr(adap, &pmrx_int_cause, 0, flags)); } /* * CPL switch interrupt handler. */ -static bool cplsw_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool cplsw_intr_handler(struct adapter *adap, int arg, int flags) { - static const struct intr_details cplsw_intr_details[] = { + static const struct intr_details cplsw_int_cause_fields[] = { /* T5+ */ { F_PERR_CPL_128TO128_1, "CPLSW 128TO128 FIFO1 parity error" }, { F_PERR_CPL_128TO128_0, "CPLSW 128TO128 FIFO0 parity error" }, @@ -5493,17 +5759,17 @@ static bool cplsw_intr_handler(struct adapter *adap, int arg, bool verbose) { F_ZERO_SWITCH_ERROR, "CPLSW no-switch error" }, { 0 } }; - static const struct intr_info cplsw_intr_info = { + static const struct intr_info cplsw_int_cause = { .name = "CPL_INTR_CAUSE", .cause_reg = A_CPL_INTR_CAUSE, .enable_reg = A_CPL_INTR_ENABLE, - .fatal = 0xff, - .flags = NONFATAL_IF_DISABLED, - .details = cplsw_intr_details, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = cplsw_int_cause_fields, .actions = NULL, }; - return (t4_handle_intr(adap, &cplsw_intr_info, 0, verbose)); + return (t4_handle_intr(adap, &cplsw_int_cause, 0, flags)); } #define T4_LE_FATAL_MASK (F_PARITYERR | F_UNKNOWNCMD | F_REQQPARERR) @@ -5515,11 +5781,12 @@ static bool cplsw_intr_handler(struct adapter *adap, int arg, bool verbose) #define T6_LE_FATAL_MASK (T6_LE_PERRCRC_MASK | F_T6_UNKNOWNCMD | \ F_TCAMACCFAIL | F_HASHTBLACCFAIL | F_CMDTIDERR | F_CMDPRSRINTERR | \ F_TOTCNTERR | F_CLCAMFIFOERR | F_CLIPSUBERR) +#define T7_LE_FATAL_MASK (T6_LE_FATAL_MASK | F_CACHESRAMPERR | F_CACHEINTPERR) /* * LE interrupt handler. */ -static bool le_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool le_intr_handler(struct adapter *adap, int arg, int flags) { static const struct intr_details le_intr_details[] = { { F_REQQPARERR, "LE request queue parity error" }, @@ -5556,7 +5823,7 @@ static bool le_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_LE_DB_INT_CAUSE, .enable_reg = A_LE_DB_INT_ENABLE, .fatal = 0, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = NULL, .actions = NULL, }; @@ -5566,16 +5833,19 @@ static bool le_intr_handler(struct adapter *adap, int arg, bool verbose) le_intr_info.fatal = T5_LE_FATAL_MASK; } else { le_intr_info.details = t6_le_intr_details; - le_intr_info.fatal = T6_LE_FATAL_MASK; + if (chip_id(adap) < CHELSIO_T7) + le_intr_info.fatal = T6_LE_FATAL_MASK; + else + le_intr_info.fatal = T7_LE_FATAL_MASK; } - return (t4_handle_intr(adap, &le_intr_info, 0, verbose)); + return (t4_handle_intr(adap, &le_intr_info, 0, flags)); } /* * MPS interrupt handler. */ -static bool mps_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool mps_intr_handler(struct adapter *adap, int arg, int flags) { static const struct intr_details mps_rx_perr_intr_details[] = { { 0xffffffff, "MPS Rx parity error" }, @@ -5586,10 +5856,55 @@ static bool mps_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_MPS_RX_PERR_INT_CAUSE, .enable_reg = A_MPS_RX_PERR_INT_ENABLE, .fatal = 0xffffffff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = mps_rx_perr_intr_details, .actions = NULL, }; + static const struct intr_info mps_rx_perr_intr_info2 = { + .name = "MPS_RX_PERR_INT_CAUSE2", + .cause_reg = A_MPS_RX_PERR_INT_CAUSE2, + .enable_reg = A_MPS_RX_PERR_INT_ENABLE2, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info mps_rx_perr_intr_info3 = { + .name = "MPS_RX_PERR_INT_CAUSE3", + .cause_reg = A_MPS_RX_PERR_INT_CAUSE3, + .enable_reg = A_MPS_RX_PERR_INT_ENABLE3, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info mps_rx_perr_intr_info4 = { + .name = "MPS_RX_PERR_INT_CAUSE4", + .cause_reg = A_MPS_RX_PERR_INT_CAUSE4, + .enable_reg = A_MPS_RX_PERR_INT_ENABLE4, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info mps_rx_perr_intr_info5 = { + .name = "MPS_RX_PERR_INT_CAUSE5", + .cause_reg = A_MPS_RX_PERR_INT_CAUSE5, + .enable_reg = A_MPS_RX_PERR_INT_ENABLE5, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info mps_rx_perr_intr_info6 = { + .name = "MPS_RX_PERR_INT_CAUSE6", + .cause_reg = A_MPS_RX_PERR_INT_CAUSE6, + .enable_reg = A_MPS_RX_PERR_INT_ENABLE6, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; static const struct intr_details mps_tx_intr_details[] = { { F_PORTERR, "MPS Tx destination port is disabled" }, { F_FRMERR, "MPS Tx framing error" }, @@ -5606,10 +5921,37 @@ static bool mps_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_MPS_TX_INT_CAUSE, .enable_reg = A_MPS_TX_INT_ENABLE, .fatal = 0x1ffff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = mps_tx_intr_details, .actions = NULL, }; + static const struct intr_info mps_tx_intr_info2 = { + .name = "MPS_TX_INT2_CAUSE", + .cause_reg = A_MPS_TX_INT2_CAUSE, + .enable_reg = A_MPS_TX_INT2_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info mps_tx_intr_info3 = { + .name = "MPS_TX_INT3_CAUSE", + .cause_reg = A_MPS_TX_INT3_CAUSE, + .enable_reg = A_MPS_TX_INT3_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info mps_tx_intr_info4 = { + .name = "MPS_TX_INT4_CAUSE", + .cause_reg = A_MPS_TX_INT4_CAUSE, + .enable_reg = A_MPS_TX_INT4_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; static const struct intr_details mps_trc_intr_details[] = { { F_MISCPERR, "MPS TRC misc parity error" }, { V_PKTFIFO(M_PKTFIFO), "MPS TRC packet FIFO parity error" }, @@ -5626,14 +5968,23 @@ static bool mps_intr_handler(struct adapter *adap, int arg, bool verbose) .actions = NULL, }; static const struct intr_info t7_mps_trc_intr_info = { - .name = "T7_MPS_TRC_INT_CAUSE", + .name = "MPS_TRC_INT_CAUSE", .cause_reg = A_T7_MPS_TRC_INT_CAUSE, .enable_reg = A_T7_MPS_TRC_INT_ENABLE, - .fatal = F_MISCPERR | V_PKTFIFO(M_PKTFIFO) | V_FILTMEM(M_FILTMEM), - .flags = 0, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, .details = mps_trc_intr_details, .actions = NULL, }; + static const struct intr_info t7_mps_trc_intr_info2 = { + .name = "MPS_TRC_INT_CAUSE2", + .cause_reg = A_MPS_TRC_INT_CAUSE2, + .enable_reg = A_MPS_TRC_INT_ENABLE2, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; static const struct intr_details mps_stat_sram_intr_details[] = { { 0xffffffff, "MPS statistics SRAM parity error" }, { 0 } @@ -5643,7 +5994,7 @@ static bool mps_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_MPS_STAT_PERR_INT_CAUSE_SRAM, .enable_reg = A_MPS_STAT_PERR_INT_ENABLE_SRAM, .fatal = 0x1fffffff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = mps_stat_sram_intr_details, .actions = NULL, }; @@ -5656,7 +6007,7 @@ static bool mps_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_MPS_STAT_PERR_INT_CAUSE_TX_FIFO, .enable_reg = A_MPS_STAT_PERR_INT_ENABLE_TX_FIFO, .fatal = 0xffffff, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = mps_stat_tx_intr_details, .actions = NULL, }; @@ -5701,24 +6052,31 @@ static bool mps_intr_handler(struct adapter *adap, int arg, bool verbose) .details = mps_stat_sram1_intr_details, .actions = NULL, }; + bool fatal = false; - bool fatal; - - fatal = false; - fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info, 0, verbose); - fatal |= t4_handle_intr(adap, &mps_tx_intr_info, 0, verbose); - if (chip_id(adap) > CHELSIO_T6) - fatal |= t4_handle_intr(adap, &t7_mps_trc_intr_info, 0, verbose); - else - fatal |= t4_handle_intr(adap, &mps_trc_intr_info, 0, verbose); - fatal |= t4_handle_intr(adap, &mps_stat_sram_intr_info, 0, verbose); - fatal |= t4_handle_intr(adap, &mps_stat_tx_intr_info, 0, verbose); - fatal |= t4_handle_intr(adap, &mps_stat_rx_intr_info, 0, verbose); - fatal |= t4_handle_intr(adap, &mps_cls_intr_info, 0, verbose); - if (chip_id(adap) > CHELSIO_T4) { - fatal |= t4_handle_intr(adap, &mps_stat_sram1_intr_info, 0, - verbose); + fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info, 0, flags); + if (chip_id(adap) > CHELSIO_T6) { + fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info2, 0, flags); + fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info3, 0, flags); + fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info4, 0, flags); + fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info5, 0, flags); + fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info6, 0, flags); } + fatal |= t4_handle_intr(adap, &mps_tx_intr_info, 0, flags); + if (chip_id(adap) > CHELSIO_T6) { + fatal |= t4_handle_intr(adap, &mps_tx_intr_info2, 0, flags); + fatal |= t4_handle_intr(adap, &mps_tx_intr_info3, 0, flags); + fatal |= t4_handle_intr(adap, &mps_tx_intr_info4, 0, flags); + fatal |= t4_handle_intr(adap, &t7_mps_trc_intr_info, 0, flags); + fatal |= t4_handle_intr(adap, &t7_mps_trc_intr_info2, 0, flags); + } else + fatal |= t4_handle_intr(adap, &mps_trc_intr_info, 0, flags); + fatal |= t4_handle_intr(adap, &mps_stat_sram_intr_info, 0, flags); + fatal |= t4_handle_intr(adap, &mps_stat_tx_intr_info, 0, flags); + fatal |= t4_handle_intr(adap, &mps_stat_rx_intr_info, 0, flags); + fatal |= t4_handle_intr(adap, &mps_cls_intr_info, 0, flags); + if (chip_id(adap) > CHELSIO_T4) + fatal |= t4_handle_intr(adap, &mps_stat_sram1_intr_info, 0, flags); t4_write_reg(adap, A_MPS_INT_CAUSE, is_t4(adap) ? 0 : 0xffffffff); t4_read_reg(adap, A_MPS_INT_CAUSE); /* flush */ @@ -5730,7 +6088,7 @@ static bool mps_intr_handler(struct adapter *adap, int arg, bool verbose) /* * EDC/MC interrupt handler. */ -static bool mem_intr_handler(struct adapter *adap, int idx, bool verbose) +static bool mem_intr_handler(struct adapter *adap, int idx, int flags) { static const char name[4][5] = { "EDC0", "EDC1", "MC0", "MC1" }; unsigned int count_reg, v; @@ -5740,61 +6098,106 @@ static bool mem_intr_handler(struct adapter *adap, int idx, bool verbose) { F_PERR_INT_CAUSE, "FIFO parity error" }, { 0 } }; + char rname[32]; struct intr_info ii = { + .name = &rname[0], .fatal = F_PERR_INT_CAUSE | F_ECC_UE_INT_CAUSE, .details = mem_intr_details, .flags = 0, .actions = NULL, }; - bool fatal; + bool fatal = false; + int i = 0; switch (idx) { + case MEM_EDC1: i = 1; + /* fall through */ case MEM_EDC0: - ii.name = "EDC0_INT_CAUSE"; - ii.cause_reg = EDC_REG(A_EDC_INT_CAUSE, 0); - ii.enable_reg = EDC_REG(A_EDC_INT_ENABLE, 0); - count_reg = EDC_REG(A_EDC_ECC_STATUS, 0); - break; - case MEM_EDC1: - ii.name = "EDC1_INT_CAUSE"; - ii.cause_reg = EDC_REG(A_EDC_INT_CAUSE, 1); - ii.enable_reg = EDC_REG(A_EDC_INT_ENABLE, 1); - count_reg = EDC_REG(A_EDC_ECC_STATUS, 1); + snprintf(rname, sizeof(rname), "EDC%u_INT_CAUSE", i); + if (is_t4(adap)) { + ii.cause_reg = EDC_REG(A_EDC_INT_CAUSE, i); + ii.enable_reg = EDC_REG(A_EDC_INT_ENABLE, i); + count_reg = EDC_REG(A_EDC_ECC_STATUS, i); + } else { + ii.cause_reg = EDC_T5_REG(A_EDC_H_INT_CAUSE, i); + ii.enable_reg = EDC_T5_REG(A_EDC_H_INT_ENABLE, i); + count_reg = EDC_T5_REG(A_EDC_H_ECC_STATUS, i); + } + fatal |= t4_handle_intr(adap, &ii, 0, flags); + if (chip_id(adap) > CHELSIO_T6) { + snprintf(rname, sizeof(rname), "EDC%u_PAR_CAUSE", i); + ii.cause_reg = EDC_T5_REG(A_EDC_H_PAR_CAUSE, i); + ii.enable_reg = EDC_T5_REG(A_EDC_H_PAR_ENABLE, i); + ii.fatal = 0xffffffff; + ii.details = NULL; + ii.flags = IHF_FATAL_IFF_ENABLED; + fatal |= t4_handle_intr(adap, &ii, 0, flags); + } break; + case MEM_MC1: + if (is_t4(adap) || is_t6(adap)) + return (false); + i = 1; + /* fall through */ case MEM_MC0: - ii.name = "MC0_INT_CAUSE"; + snprintf(rname, sizeof(rname), "MC%u_INT_CAUSE", i); if (is_t4(adap)) { ii.cause_reg = A_MC_INT_CAUSE; ii.enable_reg = A_MC_INT_ENABLE; count_reg = A_MC_ECC_STATUS; + } else if (chip_id(adap) < CHELSIO_T7) { + ii.cause_reg = MC_REG(A_MC_P_INT_CAUSE, i); + ii.enable_reg = MC_REG(A_MC_P_INT_ENABLE, i); + count_reg = MC_REG(A_MC_P_ECC_STATUS, i); } else { - ii.cause_reg = A_MC_P_INT_CAUSE; - ii.enable_reg = A_MC_P_INT_ENABLE; - count_reg = A_MC_P_ECC_STATUS; + ii.cause_reg = MC_T7_REG(A_T7_MC_P_INT_CAUSE, i); + ii.enable_reg = MC_T7_REG(A_T7_MC_P_INT_ENABLE, i); + count_reg = MC_T7_REG(A_T7_MC_P_ECC_STATUS, i); + } + fatal |= t4_handle_intr(adap, &ii, 0, flags); + + snprintf(rname, sizeof(rname), "MC%u_PAR_CAUSE", i); + if (is_t4(adap)) { + ii.cause_reg = A_MC_PAR_CAUSE; + ii.enable_reg = A_MC_PAR_ENABLE; + } else if (chip_id(adap) < CHELSIO_T7) { + ii.cause_reg = MC_REG(A_MC_P_PAR_CAUSE, i); + ii.enable_reg = MC_REG(A_MC_P_PAR_ENABLE, i); + } else { + ii.cause_reg = MC_T7_REG(A_T7_MC_P_PAR_CAUSE, i); + ii.enable_reg = MC_T7_REG(A_T7_MC_P_PAR_ENABLE, i); + } + ii.fatal = 0xffffffff; + ii.details = NULL; + ii.flags = IHF_FATAL_IFF_ENABLED; + fatal |= t4_handle_intr(adap, &ii, 0, flags); + + if (chip_id(adap) > CHELSIO_T6) { + snprintf(rname, sizeof(rname), "MC%u_DDRCTL_INT_CAUSE", i); + ii.cause_reg = MC_T7_REG(A_MC_P_DDRCTL_INT_CAUSE, i); + ii.enable_reg = MC_T7_REG(A_MC_P_DDRCTL_INT_ENABLE, i); + fatal |= t4_handle_intr(adap, &ii, 0, flags); + + snprintf(rname, sizeof(rname), "MC%u_ECC_UE_INT_CAUSE", i); + ii.cause_reg = MC_T7_REG(A_MC_P_ECC_UE_INT_CAUSE, i); + ii.enable_reg = MC_T7_REG(A_MC_P_ECC_UE_INT_ENABLE, i); + fatal |= t4_handle_intr(adap, &ii, 0, flags); } - break; - case MEM_MC1: - ii.name = "MC1_INT_CAUSE"; - ii.cause_reg = MC_REG(A_MC_P_INT_CAUSE, 1); - ii.enable_reg = MC_REG(A_MC_P_INT_ENABLE, 1); - count_reg = MC_REG(A_MC_P_ECC_STATUS, 1); break; } - fatal = t4_handle_intr(adap, &ii, 0, verbose); - v = t4_read_reg(adap, count_reg); if (v != 0) { - if (G_ECC_UECNT(v) != 0) { + if (G_ECC_UECNT(v) != 0 && !(flags & IHF_NO_SHOW)) { CH_ALERT(adap, - "%s: %u uncorrectable ECC data error(s)\n", + " %s: %u uncorrectable ECC data error(s)\n", name[idx], G_ECC_UECNT(v)); } - if (G_ECC_CECNT(v) != 0) { + if (G_ECC_CECNT(v) != 0 && !(flags & IHF_NO_SHOW)) { if (idx <= MEM_EDC1) t4_edc_err_read(adap, idx); CH_WARN_RATELIMIT(adap, - "%s: %u correctable ECC data error(s)\n", + " %s: %u correctable ECC data error(s)\n", name[idx], G_ECC_CECNT(v)); } t4_write_reg(adap, count_reg, 0xffffffff); @@ -5803,14 +6206,16 @@ static bool mem_intr_handler(struct adapter *adap, int idx, bool verbose) return (fatal); } -static bool ma_wrap_status(struct adapter *adap, int arg, bool verbose) +static bool ma_wrap_status(struct adapter *adap, int arg, int flags) { u32 v; v = t4_read_reg(adap, A_MA_INT_WRAP_STATUS); - CH_ALERT(adap, - "MA address wrap-around error by client %u to address %#x\n", - G_MEM_WRAP_CLIENT_NUM(v), G_MEM_WRAP_ADDRESS(v) << 4); + if (!(flags & IHF_NO_SHOW)) { + CH_ALERT(adap, + " MA address wrap-around by client %u to address %#x\n", + G_MEM_WRAP_CLIENT_NUM(v), G_MEM_WRAP_ADDRESS(v) << 4); + } t4_write_reg(adap, A_MA_INT_WRAP_STATUS, v); return (false); @@ -5820,7 +6225,7 @@ static bool ma_wrap_status(struct adapter *adap, int arg, bool verbose) /* * MA interrupt handler. */ -static bool ma_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool ma_intr_handler(struct adapter *adap, int arg, int flags) { static const struct intr_action ma_intr_actions[] = { { F_MEM_WRAP_INT_CAUSE, 0, ma_wrap_status }, @@ -5831,7 +6236,7 @@ static bool ma_intr_handler(struct adapter *adap, int arg, bool verbose) .cause_reg = A_MA_INT_CAUSE, .enable_reg = A_MA_INT_ENABLE, .fatal = F_MEM_PERR_INT_CAUSE | F_MEM_TO_INT_CAUSE, - .flags = NONFATAL_IF_DISABLED, + .flags = IHF_FATAL_IFF_ENABLED, .details = NULL, .actions = ma_intr_actions, }; @@ -5856,10 +6261,10 @@ static bool ma_intr_handler(struct adapter *adap, int arg, bool verbose) bool fatal; fatal = false; - fatal |= t4_handle_intr(adap, &ma_intr_info, 0, verbose); - fatal |= t4_handle_intr(adap, &ma_perr_status1, 0, verbose); + fatal |= t4_handle_intr(adap, &ma_intr_info, 0, flags); + fatal |= t4_handle_intr(adap, &ma_perr_status1, 0, flags); if (chip_id(adap) > CHELSIO_T4) - fatal |= t4_handle_intr(adap, &ma_perr_status2, 0, verbose); + fatal |= t4_handle_intr(adap, &ma_perr_status2, 0, flags); return (fatal); } @@ -5867,58 +6272,115 @@ static bool ma_intr_handler(struct adapter *adap, int arg, bool verbose) /* * SMB interrupt handler. */ -static bool smb_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool smb_intr_handler(struct adapter *adap, int arg, int flags) { - static const struct intr_details smb_intr_details[] = { + static const struct intr_details smb_int_cause_fields[] = { { F_MSTTXFIFOPARINT, "SMB master Tx FIFO parity error" }, { F_MSTRXFIFOPARINT, "SMB master Rx FIFO parity error" }, { F_SLVFIFOPARINT, "SMB slave FIFO parity error" }, { 0 } }; - static const struct intr_info smb_intr_info = { + static const struct intr_info smb_int_cause = { .name = "SMB_INT_CAUSE", .cause_reg = A_SMB_INT_CAUSE, .enable_reg = A_SMB_INT_ENABLE, .fatal = F_SLVFIFOPARINT | F_MSTRXFIFOPARINT | F_MSTTXFIFOPARINT, .flags = 0, - .details = smb_intr_details, + .details = smb_int_cause_fields, .actions = NULL, }; - - return (t4_handle_intr(adap, &smb_intr_info, 0, verbose)); + return (t4_handle_intr(adap, &smb_int_cause, 0, flags)); } /* * NC-SI interrupt handler. */ -static bool ncsi_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool ncsi_intr_handler(struct adapter *adap, int arg, int flags) { - static const struct intr_details ncsi_intr_details[] = { + static const struct intr_details ncsi_int_cause_fields[] = { { F_CIM_DM_PRTY_ERR, "NC-SI CIM parity error" }, { F_MPS_DM_PRTY_ERR, "NC-SI MPS parity error" }, { F_TXFIFO_PRTY_ERR, "NC-SI Tx FIFO parity error" }, { F_RXFIFO_PRTY_ERR, "NC-SI Rx FIFO parity error" }, { 0 } }; - static const struct intr_info ncsi_intr_info = { + static const struct intr_info ncsi_int_cause = { .name = "NCSI_INT_CAUSE", .cause_reg = A_NCSI_INT_CAUSE, .enable_reg = A_NCSI_INT_ENABLE, .fatal = F_RXFIFO_PRTY_ERR | F_TXFIFO_PRTY_ERR | F_MPS_DM_PRTY_ERR | F_CIM_DM_PRTY_ERR, .flags = 0, - .details = ncsi_intr_details, + .details = ncsi_int_cause_fields, + .actions = NULL, + }; + static const struct intr_info ncsi_xgmac0_int_cause = { + .name = "NCSI_XGMAC0_INT_CAUSE", + .cause_reg = A_NCSI_XGMAC0_INT_CAUSE, + .enable_reg = A_NCSI_XGMAC0_INT_ENABLE, + .fatal = 0, + .flags = 0, + .details = NULL, .actions = NULL, }; + bool fatal = false; - return (t4_handle_intr(adap, &ncsi_intr_info, 0, verbose)); + fatal |= t4_handle_intr(adap, &ncsi_int_cause, 0, flags); + if (chip_id(adap) > CHELSIO_T6) + fatal |= t4_handle_intr(adap, &ncsi_xgmac0_int_cause, 0, flags); + return (fatal); } /* * MAC interrupt handler. */ -static bool mac_intr_handler(struct adapter *adap, int port, bool verbose) +static bool mac_intr_handler(struct adapter *adap, int port, int flags) { + static const struct intr_info mac_int_cause_cmn = { + .name = "MAC_INT_CAUSE_CMN", + .cause_reg = A_MAC_INT_CAUSE_CMN, + .enable_reg = A_MAC_INT_EN_CMN, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info mac_perr_cause_mtip = { + .name = "MAC_PERR_INT_CAUSE_MTIP", + .cause_reg = A_MAC_PERR_INT_CAUSE_MTIP, + .enable_reg = A_MAC_PERR_INT_EN_MTIP, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED | IHF_IGNORE_IF_DISABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info mac_cerr_cause_mtip = { + .name = "MAC_CERR_INT_CAUSE_MTIP", + .cause_reg = A_MAC_CERR_INT_CAUSE_MTIP, + .enable_reg = A_MAC_CERR_INT_EN_MTIP, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info mac_ios_int_cause_quad0 = { + .name = "MAC_IOS_INTR_CAUSE_QUAD0", + .cause_reg = A_MAC_IOS_INTR_CAUSE_QUAD0, + .enable_reg = A_MAC_IOS_INTR_EN_QUAD0, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info mac_ios_int_cause_quad1 = { + .name = "MAC_IOS_INTR_CAUSE_QUAD1", + .cause_reg = A_MAC_IOS_INTR_CAUSE_QUAD1, + .enable_reg = A_MAC_IOS_INTR_EN_QUAD1, + .fatal = 0, + .flags = 0, + .details = NULL, + .actions = NULL, + }; static const struct intr_details mac_intr_details[] = { { F_TXFIFO_PRTY_ERR, "MAC Tx FIFO parity error" }, { F_RXFIFO_PRTY_ERR, "MAC Rx FIFO parity error" }, @@ -5928,6 +6390,9 @@ static bool mac_intr_handler(struct adapter *adap, int port, bool verbose) struct intr_info ii; bool fatal = false; + if (port > 1 && is_t6(adap)) + return (false); + if (is_t4(adap)) { snprintf(name, sizeof(name), "XGMAC_PORT%u_INT_CAUSE", port); ii.name = &name[0]; @@ -5947,66 +6412,79 @@ static bool mac_intr_handler(struct adapter *adap, int port, bool verbose) ii.details = mac_intr_details; ii.actions = NULL; } else { - snprintf(name, sizeof(name), "T7_MAC_PORT%u_INT_CAUSE", port); + snprintf(name, sizeof(name), "MAC_PORT%u_INT_CAUSE", port); ii.name = &name[0]; ii.cause_reg = T7_PORT_REG(port, A_T7_MAC_PORT_INT_CAUSE); ii.enable_reg = T7_PORT_REG(port, A_T7_MAC_PORT_INT_EN); - ii.fatal = F_TXFIFO_PRTY_ERR | F_RXFIFO_PRTY_ERR; - ii.flags = 0; - ii.details = mac_intr_details; + ii.fatal = 0xffffffff; + ii.flags = IHF_FATAL_IFF_ENABLED; + ii.details = NULL; ii.actions = NULL; } - fatal |= t4_handle_intr(adap, &ii, 0, verbose); + fatal |= t4_handle_intr(adap, &ii, 0, flags); + if (is_t4(adap)) + return (fatal); + MPASS(chip_id(adap) >= CHELSIO_T5); + snprintf(name, sizeof(name), "MAC_PORT%u_PERR_INT_CAUSE", port); if (chip_id(adap) > CHELSIO_T6) { - snprintf(name, sizeof(name), "T7_MAC_PORT%u_PERR_INT_CAUSE", port); ii.name = &name[0]; ii.cause_reg = T7_PORT_REG(port, A_T7_MAC_PORT_PERR_INT_CAUSE); ii.enable_reg = T7_PORT_REG(port, A_T7_MAC_PORT_PERR_INT_EN); - ii.fatal = 0; - ii.flags = 0; + ii.fatal = 0xffffffff; + ii.flags = IHF_FATAL_IFF_ENABLED; ii.details = NULL; ii.actions = NULL; - fatal |= t4_handle_intr(adap, &ii, 0, verbose); - } else if (chip_id(adap) >= CHELSIO_T5) { - snprintf(name, sizeof(name), "MAC_PORT%u_PERR_INT_CAUSE", port); + } else { ii.name = &name[0]; ii.cause_reg = T5_PORT_REG(port, A_MAC_PORT_PERR_INT_CAUSE); ii.enable_reg = T5_PORT_REG(port, A_MAC_PORT_PERR_INT_EN); - ii.fatal = 0; - ii.flags = 0; + ii.fatal = 0xffffffff; + ii.flags = IHF_FATAL_IFF_ENABLED; ii.details = NULL; ii.actions = NULL; - fatal |= t4_handle_intr(adap, &ii, 0, verbose); } + fatal |= t4_handle_intr(adap, &ii, 0, flags); + if (is_t5(adap)) + return (fatal); + MPASS(chip_id(adap) >= CHELSIO_T6); + snprintf(name, sizeof(name), "MAC_PORT%u_PERR_INT_CAUSE_100G", port); if (chip_id(adap) > CHELSIO_T6) { - snprintf(name, sizeof(name), "T7_MAC_PORT%u_PERR_INT_CAUSE_100G", port); ii.name = &name[0]; ii.cause_reg = T7_PORT_REG(port, A_T7_MAC_PORT_PERR_INT_CAUSE_100G); ii.enable_reg = T7_PORT_REG(port, A_T7_MAC_PORT_PERR_INT_EN_100G); - ii.fatal = 0; - ii.flags = 0; + ii.fatal = 0xffffffff; + ii.flags = IHF_FATAL_IFF_ENABLED; ii.details = NULL; ii.actions = NULL; - fatal |= t4_handle_intr(adap, &ii, 0, verbose); - } else if (is_t6(adap)) { - snprintf(name, sizeof(name), "MAC_PORT%u_PERR_INT_CAUSE_100G", port); + } else { ii.name = &name[0]; ii.cause_reg = T5_PORT_REG(port, A_MAC_PORT_PERR_INT_CAUSE_100G); ii.enable_reg = T5_PORT_REG(port, A_MAC_PORT_PERR_INT_EN_100G); - ii.fatal = 0; - ii.flags = 0; + ii.fatal = 0xffffffff; + ii.flags = IHF_FATAL_IFF_ENABLED; ii.details = NULL; ii.actions = NULL; - fatal |= t4_handle_intr(adap, &ii, 0, verbose); } + fatal |= t4_handle_intr(adap, &ii, 0, flags); + if (is_t6(adap)) + return (fatal); + + MPASS(chip_id(adap) >= CHELSIO_T7); + fatal |= t4_handle_intr(adap, &mac_int_cause_cmn, 0, flags); + fatal |= t4_handle_intr(adap, &mac_perr_cause_mtip, 0, flags); + fatal |= t4_handle_intr(adap, &mac_cerr_cause_mtip, 0, flags); + fatal |= t4_handle_intr(adap, &mac_ios_int_cause_quad0, 0, flags); + fatal |= t4_handle_intr(adap, &mac_ios_int_cause_quad1, 0, flags); return (fatal); } -static bool pl_timeout_status(struct adapter *adap, int arg, bool verbose) +static bool pl_timeout_status(struct adapter *adap, int arg, int flags) { + if (flags & IHF_NO_SHOW) + return (false); CH_ALERT(adap, " PL_TIMEOUT_STATUS 0x%08x 0x%08x\n", t4_read_reg(adap, A_PL_TIMEOUT_STATUS0), @@ -6015,13 +6493,9 @@ static bool pl_timeout_status(struct adapter *adap, int arg, bool verbose) return (false); } -static bool plpl_intr_handler(struct adapter *adap, int arg, bool verbose) +static bool plpl_intr_handler(struct adapter *adap, int arg, int flags) { - static const struct intr_action plpl_intr_actions[] = { - { F_TIMEOUT, 0, pl_timeout_status }, - { 0 }, - }; - static const struct intr_details plpl_intr_details[] = { + static const struct intr_details plpl_int_cause_fields[] = { { F_PL_BUSPERR, "Bus parity error" }, { F_FATALPERR, "Fatal parity error" }, { F_INVALIDACCESS, "Global reserved memory access" }, @@ -6030,31 +6504,397 @@ static bool plpl_intr_handler(struct adapter *adap, int arg, bool verbose) { F_PERRVFID, "VFID_MAP parity error" }, { 0 } }; - static const struct intr_info plpl_intr_info = { + static const struct intr_action plpl_int_cause_actions[] = { + { F_TIMEOUT, -1, pl_timeout_status }, + { 0 }, + }; + static const struct intr_info plpl_int_cause = { .name = "PL_PL_INT_CAUSE", .cause_reg = A_PL_PL_INT_CAUSE, .enable_reg = A_PL_PL_INT_ENABLE, .fatal = F_FATALPERR | F_PERRVFID, - .flags = NONFATAL_IF_DISABLED, - .details = plpl_intr_details, - .actions = plpl_intr_actions, + .flags = IHF_FATAL_IFF_ENABLED | IHF_IGNORE_IF_DISABLED, + .details = plpl_int_cause_fields, + .actions = plpl_int_cause_actions, + }; + + return (t4_handle_intr(adap, &plpl_int_cause, 0, flags)); +} + +/* similar to t4_port_reg */ +static inline u32 +t7_tlstx_reg(u8 instance, u8 channel, u32 reg) +{ + MPASS(instance <= 1); + MPASS(channel < NUM_TLS_TX_CH_INSTANCES); + return (instance * (CRYPTO_1_BASE_ADDR - CRYPTO_0_BASE_ADDR) + + TLS_TX_CH_REG(reg, channel)); +} + +/* + * CRYPTO (aka TLS_TX) interrupt handler. + */ +static bool tlstx_intr_handler(struct adapter *adap, int idx, int flags) +{ + static const struct intr_details tlstx_int_cause_fields[] = { + { F_KEX_CERR, "KEX SRAM Correctable error" }, + { F_KEYLENERR, "IPsec Key length error" }, + { F_INTF1_PERR, "Input Interface1 parity error" }, + { F_INTF0_PERR, "Input Interface0 parity error" }, + { F_KEX_PERR, "KEX SRAM Parity error" }, + { 0 } + }; + struct intr_info ii = { + .fatal = F_KEX_PERR | F_INTF0_PERR | F_INTF1_PERR, + .flags = IHF_FATAL_IFF_ENABLED, + .details = tlstx_int_cause_fields, + .actions = NULL, + }; + char name[32]; + int ch; + bool fatal = false; + + for (ch = 0; ch < NUM_TLS_TX_CH_INSTANCES; ch++) { + snprintf(name, sizeof(name), "TLSTX%u_CH%u_INT_CAUSE", idx, ch); + ii.name = &name[0]; + ii.cause_reg = t7_tlstx_reg(idx, ch, A_TLS_TX_CH_INT_CAUSE); + ii.enable_reg = t7_tlstx_reg(idx, ch, A_TLS_TX_CH_INT_ENABLE); + fatal |= t4_handle_intr(adap, &ii, 0, flags); + } + + return (fatal); +} + +/* + * HMA interrupt handler. + */ +static bool hma_intr_handler(struct adapter *adap, int idx, int flags) +{ + static const struct intr_details hma_int_cause_fields[] = { + { F_GK_UF_INT_CAUSE, "Gatekeeper underflow" }, + { F_IDTF_INT_CAUSE, "Invalid descriptor fault" }, + { F_OTF_INT_CAUSE, "Offset translation fault" }, + { F_RTF_INT_CAUSE, "Region translation fault" }, + { F_PCIEMST_INT_CAUSE, "PCIe master access error" }, + { F_MAMST_INT_CAUSE, "MA master access error" }, + { 1, "FIFO parity error" }, + { 0 } + }; + static const struct intr_info hma_int_cause = { + .name = "HMA_INT_CAUSE", + .cause_reg = A_HMA_INT_CAUSE, + .enable_reg = A_HMA_INT_ENABLE, + .fatal = 7, + .flags = 0, + .details = hma_int_cause_fields, + .actions = NULL, + }; + + return (t4_handle_intr(adap, &hma_int_cause, 0, flags)); +} + +/* + * CRYPTO_KEY interrupt handler. + */ +static bool cryptokey_intr_handler(struct adapter *adap, int idx, int flags) +{ + static const struct intr_details cryptokey_int_cause_fields[] = { + { F_MA_FIFO_PERR, "MA arbiter FIFO parity error" }, + { F_MA_RSP_PERR, "MA response IF parity error" }, + { F_ING_CACHE_DATA_PERR, "Ingress key cache data parity error" }, + { F_ING_CACHE_TAG_PERR, "Ingress key cache tag parity error" }, + { F_LKP_KEY_REQ_PERR, "Ingress key req parity error" }, + { F_LKP_CLIP_TCAM_PERR, "Ingress LKP CLIP TCAM parity error" }, + { F_LKP_MAIN_TCAM_PERR, "Ingress LKP main TCAM parity error" }, + { F_EGR_KEY_REQ_PERR, "Egress key req or FIFO3 parity error" }, + { F_EGR_CACHE_DATA_PERR, "Egress key cache data parity error" }, + { F_EGR_CACHE_TAG_PERR, "Egress key cache tag parity error" }, + { F_CIM_PERR, "CIM interface parity error" }, + { F_MA_INV_RSP_TAG, "MA invalid response tag" }, + { F_ING_KEY_RANGE_ERR, "Ingress key range error" }, + { F_ING_MFIFO_OVFL, "Ingress MFIFO overflow" }, + { F_LKP_REQ_OVFL, "Ingress lookup FIFO overflow" }, + { F_EOK_WAIT_ERR, "EOK wait error" }, + { F_EGR_KEY_RANGE_ERR, "Egress key range error" }, + { F_EGR_MFIFO_OVFL, "Egress MFIFO overflow" }, + { F_SEQ_WRAP_HP_OVFL, "Sequence wrap (hi-pri)" }, + { F_SEQ_WRAP_LP_OVFL, "Sequence wrap (lo-pri)" }, + { F_EGR_SEQ_WRAP_HP, "Egress sequence wrap (hi-pri)" }, + { F_EGR_SEQ_WRAP_LP, "Egress sequence wrap (lo-pri)" }, + { 0 } + }; + static const struct intr_info cryptokey_int_cause = { + .name = "CRYPTO_KEY_INT_CAUSE", + .cause_reg = A_CRYPTO_KEY_INT_CAUSE, + .enable_reg = A_CRYPTO_KEY_INT_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = cryptokey_int_cause_fields, + .actions = NULL, + }; + + return (t4_handle_intr(adap, &cryptokey_int_cause, 0, flags)); +} + +/* + * GCACHE interrupt handler. + */ +static bool gcache_intr_handler(struct adapter *adap, int idx, int flags) +{ + static const struct intr_details gcache_int_cause_fields[] = { + { F_GC1_SRAM_RSP_DATAQ_PERR_INT_CAUSE, "GC1 SRAM rsp dataq perr" }, + { F_GC0_SRAM_RSP_DATAQ_PERR_INT_CAUSE, "GC0 SRAM rsp dataq perr" }, + { F_GC1_WQDATA_FIFO_PERR_INT_CAUSE, "GC1 wqdata FIFO perr" }, + { F_GC0_WQDATA_FIFO_PERR_INT_CAUSE, "GC0 wqdata FIFO perr" }, + { F_GC1_RDTAG_QUEUE_PERR_INT_CAUSE, "GC1 rdtag queue perr" }, + { F_GC0_RDTAG_QUEUE_PERR_INT_CAUSE, "GC0 rdtag queue perr" }, + { F_GC1_SRAM_RDTAG_QUEUE_PERR_INT_CAUSE, "GC1 SRAM rdtag queue perr" }, + { F_GC0_SRAM_RDTAG_QUEUE_PERR_INT_CAUSE, "GC0 SRAM rdtag queue perr" }, + { F_GC1_RSP_PERR_INT_CAUSE, "GC1 rsp perr" }, + { F_GC0_RSP_PERR_INT_CAUSE, "GC0 rsp perr" }, + { F_GC1_LRU_UERR_INT_CAUSE, "GC1 lru uerr" }, + { F_GC0_LRU_UERR_INT_CAUSE, "GC0 lru uerr" }, + { F_GC1_TAG_UERR_INT_CAUSE, "GC1 tag uerr" }, + { F_GC0_TAG_UERR_INT_CAUSE, "GC0 tag uerr" }, + { F_GC1_LRU_CERR_INT_CAUSE, "GC1 lru cerr" }, + { F_GC0_LRU_CERR_INT_CAUSE, "GC0 lru cerr" }, + { F_GC1_TAG_CERR_INT_CAUSE, "GC1 tag cerr" }, + { F_GC0_TAG_CERR_INT_CAUSE, "GC0 tag cerr" }, + { F_GC1_CE_INT_CAUSE, "GC1 correctable error" }, + { F_GC0_CE_INT_CAUSE, "GC0 correctable error" }, + { F_GC1_UE_INT_CAUSE, "GC1 uncorrectable error" }, + { F_GC0_UE_INT_CAUSE, "GC0 uncorrectable error" }, + { F_GC1_CMD_PAR_INT_CAUSE, "GC1 cmd perr" }, + { F_GC1_DATA_PAR_INT_CAUSE, "GC1 data perr" }, + { F_GC0_CMD_PAR_INT_CAUSE, "GC0 cmd perr" }, + { F_GC0_DATA_PAR_INT_CAUSE, "GC0 data perr" }, + { F_ILLADDRACCESS1_INT_CAUSE, "GC1 illegal address access" }, + { F_ILLADDRACCESS0_INT_CAUSE, "GC0 illegal address access" }, + { 0 } + }; + static const struct intr_info gcache_perr_cause = { + .name = "GCACHE_PAR_CAUSE", + .cause_reg = A_GCACHE_PAR_CAUSE, + .enable_reg = A_GCACHE_PAR_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info gcache_int_cause = { + .name = "GCACHE_INT_CAUSE", + .cause_reg = A_GCACHE_INT_CAUSE, + .enable_reg = A_GCACHE_INT_ENABLE, + .fatal = 0, + .flags = 0, + .details = gcache_int_cause_fields, + .actions = NULL, + }; + bool fatal = false; + + fatal |= t4_handle_intr(adap, &gcache_int_cause, 0, flags); + fatal |= t4_handle_intr(adap, &gcache_perr_cause, 0, flags); + + return (fatal); +} + +/* + * ARM interrupt handler. + */ +static bool arm_intr_handler(struct adapter *adap, int idx, int flags) +{ + static const struct intr_info arm_perr_cause0 = { + .name = "ARM_PERR_INT_CAUSE0", + .cause_reg = A_ARM_PERR_INT_CAUSE0, + .enable_reg = A_ARM_PERR_INT_ENB0, + .fatal = 0xffffffff, + .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info arm_perr_cause1 = { + .name = "ARM_PERR_INT_CAUSE1", + .cause_reg = A_ARM_PERR_INT_CAUSE1, + .enable_reg = A_ARM_PERR_INT_ENB1, + .fatal = 0xffffffff, + .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info arm_perr_cause2 = { + .name = "ARM_PERR_INT_CAUSE2", + .cause_reg = A_ARM_PERR_INT_CAUSE2, + .enable_reg = A_ARM_PERR_INT_ENB2, + .fatal = 0xffffffff, + .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info arm_cerr_cause0 = { + .name = "ARM_CERR_INT_CAUSE", + .cause_reg = A_ARM_CERR_INT_CAUSE0, + .enable_reg = A_ARM_CERR_INT_ENB0, + .fatal = 0, + .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, }; + static const struct intr_info arm_err_cause0 = { + .name = "ARM_ERR_INT_CAUSE", + .cause_reg = A_ARM_ERR_INT_CAUSE0, + .enable_reg = A_ARM_ERR_INT_ENB0, + .fatal = 0, + .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info arm_periph_cause = { + .name = "ARM_PERIPHERAL_INT_CAUSE", + .cause_reg = A_ARM_PERIPHERAL_INT_CAUSE, + .enable_reg = A_ARM_PERIPHERAL_INT_ENB, + .fatal = 0, + .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + static const struct intr_info arm_nvme_db_emu_cause = { + .name = "ARM_NVME_DB_EMU_INT_CAUSE", + .cause_reg = A_ARM_NVME_DB_EMU_INT_CAUSE, + .enable_reg = A_ARM_NVME_DB_EMU_INT_ENABLE, + .fatal = 0, + .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, + .details = NULL, + .actions = NULL, + }; + bool fatal = false; + + fatal |= t4_handle_intr(adap, &arm_perr_cause0, 0, flags); + fatal |= t4_handle_intr(adap, &arm_perr_cause1, 0, flags); + fatal |= t4_handle_intr(adap, &arm_perr_cause2, 0, flags); + fatal |= t4_handle_intr(adap, &arm_cerr_cause0, 0, flags); + fatal |= t4_handle_intr(adap, &arm_err_cause0, 0, flags); + fatal |= t4_handle_intr(adap, &arm_periph_cause, 0, flags); + fatal |= t4_handle_intr(adap, &arm_nvme_db_emu_cause, 0, flags); + + return (fatal); +} + +static inline uint32_t +get_perr_ucause(struct adapter *sc, const struct intr_info *ii) +{ + uint32_t cause; - return (t4_handle_intr(adap, &plpl_intr_info, 0, verbose)); + cause = t4_read_reg(sc, ii->cause_reg); + if (ii->flags & IHF_IGNORE_IF_DISABLED) + cause &= t4_read_reg(sc, ii->enable_reg); + return (cause); +} + +static uint32_t +t4_perr_to_ic(struct adapter *adap, uint32_t perr) +{ + uint32_t mask; + + if (adap->chip_params->nchan > 2) + mask = F_MAC0 | F_MAC1 | F_MAC2 | F_MAC3; + else + mask = F_MAC0 | F_MAC1; + return (perr & mask ? perr | mask : perr); +} + +static uint32_t +t7_perr_to_ic1(uint32_t perr) +{ + uint32_t cause = 0; + + if (perr & F_T7_PL_PERR_ULP_TX) + cause |= F_T7_ULP_TX; + if (perr & F_T7_PL_PERR_SGE) + cause |= F_T7_SGE; + if (perr & F_T7_PL_PERR_HMA) + cause |= F_T7_HMA; + if (perr & F_T7_PL_PERR_CPL_SWITCH) + cause |= F_T7_CPL_SWITCH; + if (perr & F_T7_PL_PERR_ULP_RX) + cause |= F_T7_ULP_RX; + if (perr & F_T7_PL_PERR_PM_RX) + cause |= F_T7_PM_RX; + if (perr & F_T7_PL_PERR_PM_TX) + cause |= F_T7_PM_TX; + if (perr & F_T7_PL_PERR_MA) + cause |= F_T7_MA; + if (perr & F_T7_PL_PERR_TP) + cause |= F_T7_TP; + if (perr & F_T7_PL_PERR_LE) + cause |= F_T7_LE; + if (perr & F_T7_PL_PERR_EDC1) + cause |= F_T7_EDC1; + if (perr & F_T7_PL_PERR_EDC0) + cause |= F_T7_EDC0; + if (perr & F_T7_PL_PERR_MC1) + cause |= F_T7_MC1; + if (perr & F_T7_PL_PERR_MC0) + cause |= F_T7_MC0; + if (perr & F_T7_PL_PERR_PCIE) + cause |= F_T7_PCIE; + if (perr & F_T7_PL_PERR_UART) + cause |= F_T7_UART; + if (perr & F_T7_PL_PERR_PMU) + cause |= F_PMU; + if (perr & F_T7_PL_PERR_MAC) + cause |= F_MAC0 | F_MAC1 | F_MAC2 | F_MAC3; + if (perr & F_T7_PL_PERR_SMB) + cause |= F_SMB; + if (perr & F_T7_PL_PERR_SF) + cause |= F_SF; + if (perr & F_T7_PL_PERR_PL) + cause |= F_PL; + if (perr & F_T7_PL_PERR_NCSI) + cause |= F_NCSI; + if (perr & F_T7_PL_PERR_MPS) + cause |= F_MPS; + if (perr & F_T7_PL_PERR_MI) + cause |= F_MI; + if (perr & F_T7_PL_PERR_DBG) + cause |= F_DBG; + if (perr & F_T7_PL_PERR_I2CM) + cause |= F_I2CM; + if (perr & F_T7_PL_PERR_CIM) + cause |= F_CIM; + + return (cause); +} + +static uint32_t +t7_perr_to_ic2(uint32_t perr) +{ + uint32_t cause = 0; + + if (perr & F_T7_PL_PERR_CRYPTO_KEY) + cause |= F_CRYPTO_KEY; + if (perr & F_T7_PL_PERR_CRYPTO1) + cause |= F_CRYPTO1; + if (perr & F_T7_PL_PERR_CRYPTO0) + cause |= F_CRYPTO0; + if (perr & F_T7_PL_PERR_GCACHE) + cause |= F_GCACHE; + if (perr & F_T7_PL_PERR_ARM) + cause |= F_ARM; + + return (cause); } /** * t4_slow_intr_handler - control path interrupt handler * @adap: the adapter - * @verbose: increased verbosity, for debug * * T4 interrupt handler for non-data global interrupt events, e.g., errors. * The designation 'slow' is because it involves register reads, while * data interrupts typically don't involve any MMIOs. */ -bool t4_slow_intr_handler(struct adapter *adap, bool verbose) +bool t4_slow_intr_handler(struct adapter *adap, int flags) { - static const struct intr_details pl_intr_details[] = { + static const struct intr_details pl_int_cause_fields[] = { { F_MC1, "MC1" }, { F_UART, "UART" }, { F_ULP_TX, "ULP TX" }, @@ -6087,10 +6927,56 @@ bool t4_slow_intr_handler(struct adapter *adap, bool verbose) { F_CIM, "CIM" }, { 0 } }; - static const struct intr_details t7_pl_intr_details[] = { - { F_T7_MC1, "MC1" }, + static const struct intr_action pl_int_cause_actions[] = { + { F_ULP_TX, -1, ulptx_intr_handler }, + { F_SGE, -1, sge_intr_handler }, + { F_CPL_SWITCH, -1, cplsw_intr_handler }, + { F_ULP_RX, -1, ulprx_intr_handler }, + { F_PM_RX, -1, pmtx_intr_handler }, + { F_PM_TX, -1, pmtx_intr_handler }, + { F_MA, -1, ma_intr_handler }, + { F_TP, -1, tp_intr_handler }, + { F_LE, -1, le_intr_handler }, + { F_EDC0, MEM_EDC0, mem_intr_handler }, + { F_EDC1, MEM_EDC1, mem_intr_handler }, + { F_MC0, MEM_MC0, mem_intr_handler }, + { F_MC1, MEM_MC1, mem_intr_handler }, + { F_PCIE, -1, pcie_intr_handler }, + { F_MAC0, 0, mac_intr_handler }, + { F_MAC1, 1, mac_intr_handler }, + { F_MAC2, 2, mac_intr_handler }, + { F_MAC3, 3, mac_intr_handler }, + { F_SMB, -1, smb_intr_handler }, + { F_PL, -1, plpl_intr_handler }, + { F_NCSI, -1, ncsi_intr_handler }, + { F_MPS, -1, mps_intr_handler }, + { F_CIM, -1, cim_intr_handler }, + { 0 } + }; + static const struct intr_info pl_int_cause = { + .name = "PL_INT_CAUSE", + .cause_reg = A_PL_INT_CAUSE, + .enable_reg = A_PL_INT_ENABLE, + .fatal = 0, + .flags = IHF_IGNORE_IF_DISABLED, + .details = pl_int_cause_fields, + .actions = pl_int_cause_actions, + }; + static const struct intr_info pl_perr_cause = { + .name = "PL_PERR_CAUSE", + .cause_reg = A_PL_PERR_CAUSE, + .enable_reg = A_PL_PERR_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, + .details = pl_int_cause_fields, + .actions = NULL, + }; + static const struct intr_details t7_pl_int_cause_fields[] = { + { F_T7_FLR, "FLR" }, + { F_T7_SW_CIM, "SW CIM" }, { F_T7_ULP_TX, "ULP TX" }, { F_T7_SGE, "SGE" }, + { F_T7_HMA, "HMA" }, { F_T7_CPL_SWITCH, "CPL Switch" }, { F_T7_ULP_RX, "ULP RX" }, { F_T7_PM_RX, "PM RX" }, @@ -6100,117 +6986,165 @@ bool t4_slow_intr_handler(struct adapter *adap, bool verbose) { F_T7_LE, "LE" }, { F_T7_EDC1, "EDC1" }, { F_T7_EDC0, "EDC0" }, + { F_T7_MC1, "MC1" }, { F_T7_MC0, "MC0" }, { F_T7_PCIE, "PCIE" }, + { F_T7_UART, "UART" }, + { F_PMU, "PMU" }, { F_MAC3, "MAC3" }, { F_MAC2, "MAC2" }, { F_MAC1, "MAC1" }, { F_MAC0, "MAC0" }, { F_SMB, "SMB" }, + { F_SF, "SF" }, { F_PL, "PL" }, { F_NCSI, "NC-SI" }, { F_MPS, "MPS" }, + { F_MI, "MI" }, { F_DBG, "DBG" }, { F_I2CM, "I2CM" }, - { F_MI, "MI" }, { F_CIM, "CIM" }, { 0 } }; - struct intr_info pl_perr_cause = { - .name = "PL_PERR_CAUSE", - .cause_reg = A_PL_PERR_CAUSE, - .enable_reg = A_PL_PERR_ENABLE, - .fatal = 0xffffffff, - .flags = NONFATAL_IF_DISABLED, - .details = NULL, - .actions = NULL, - }; - static const struct intr_action pl_intr_action[] = { - { F_MC1, MEM_MC1, mem_intr_handler }, - { F_ULP_TX, -1, ulptx_intr_handler }, - { F_SGE, -1, sge_intr_handler }, - { F_CPL_SWITCH, -1, cplsw_intr_handler }, - { F_ULP_RX, -1, ulprx_intr_handler }, - { F_PM_RX, -1, pmrx_intr_handler}, - { F_PM_TX, -1, pmtx_intr_handler}, - { F_MA, -1, ma_intr_handler }, - { F_TP, -1, tp_intr_handler }, - { F_LE, -1, le_intr_handler }, - { F_EDC1, MEM_EDC1, mem_intr_handler }, - { F_EDC0, MEM_EDC0, mem_intr_handler }, - { F_MC0, MEM_MC0, mem_intr_handler }, - { F_PCIE, -1, pcie_intr_handler }, - { F_MAC3, 3, mac_intr_handler}, - { F_MAC2, 2, mac_intr_handler}, - { F_MAC1, 1, mac_intr_handler}, - { F_MAC0, 0, mac_intr_handler}, - { F_SMB, -1, smb_intr_handler}, - { F_PL, -1, plpl_intr_handler }, - { F_NCSI, -1, ncsi_intr_handler}, - { F_MPS, -1, mps_intr_handler }, - { F_CIM, -1, cim_intr_handler }, - { 0 } - }; - static const struct intr_action t7_pl_intr_action[] = { + static const struct intr_action t7_pl_int_cause_actions[] = { { F_T7_ULP_TX, -1, ulptx_intr_handler }, { F_T7_SGE, -1, sge_intr_handler }, + { F_T7_HMA, -1, hma_intr_handler }, { F_T7_CPL_SWITCH, -1, cplsw_intr_handler }, { F_T7_ULP_RX, -1, ulprx_intr_handler }, - { F_T7_PM_RX, -1, pmrx_intr_handler}, - { F_T7_PM_TX, -1, pmtx_intr_handler}, + { F_T7_PM_RX, -1, pmrx_intr_handler }, + { F_T7_PM_TX, -1, pmtx_intr_handler }, { F_T7_MA, -1, ma_intr_handler }, { F_T7_TP, -1, tp_intr_handler }, { F_T7_LE, -1, le_intr_handler }, - { F_T7_EDC1, MEM_EDC1, mem_intr_handler }, { F_T7_EDC0, MEM_EDC0, mem_intr_handler }, - { F_T7_MC1, MEM_MC1, mem_intr_handler }, + { F_T7_EDC1, MEM_EDC1, mem_intr_handler }, { F_T7_MC0, MEM_MC0, mem_intr_handler }, + { F_T7_MC1, MEM_MC1, mem_intr_handler }, { F_T7_PCIE, -1, pcie_intr_handler }, - { F_MAC3, 3, mac_intr_handler}, - { F_MAC2, 2, mac_intr_handler}, - { F_MAC1, 1, mac_intr_handler}, - { F_MAC0, 0, mac_intr_handler}, - { F_SMB, -1, smb_intr_handler}, + { F_MAC0, 0, mac_intr_handler }, + { F_MAC1, 1, mac_intr_handler }, + { F_MAC2, 2, mac_intr_handler }, + { F_MAC3, 3, mac_intr_handler }, + { F_SMB, -1, smb_intr_handler }, { F_PL, -1, plpl_intr_handler }, - { F_NCSI, -1, ncsi_intr_handler}, + { F_NCSI, -1, ncsi_intr_handler }, { F_MPS, -1, mps_intr_handler }, { F_CIM, -1, cim_intr_handler }, { 0 } }; - struct intr_info pl_intr_info = { + static const struct intr_info t7_pl_int_cause = { .name = "PL_INT_CAUSE", .cause_reg = A_PL_INT_CAUSE, .enable_reg = A_PL_INT_ENABLE, .fatal = 0, - .flags = 0, - .details = NULL, + .flags = IHF_IGNORE_IF_DISABLED, + .details = t7_pl_int_cause_fields, + .actions = t7_pl_int_cause_actions, + }; + static const struct intr_details t7_pl_int_cause2_fields[] = { + { F_CRYPTO_KEY, "CRYPTO KEY" }, + { F_CRYPTO1, "CRYPTO1" }, + { F_CRYPTO0, "CRYPTO0" }, + { F_GCACHE, "GCACHE" }, + { F_ARM, "ARM" }, + { 0 } + }; + static const struct intr_action t7_pl_int_cause2_actions[] = { + { F_CRYPTO_KEY, -1, cryptokey_intr_handler }, + { F_CRYPTO1, 1, tlstx_intr_handler }, + { F_CRYPTO0, 0, tlstx_intr_handler }, + { F_GCACHE, -1, gcache_intr_handler }, + { F_ARM, -1, arm_intr_handler }, + { 0 } + }; + static const struct intr_info t7_pl_int_cause2 = { + .name = "PL_INT_CAUSE2", + .cause_reg = A_PL_INT_CAUSE2, + .enable_reg = A_PL_INT_ENABLE2, + .fatal = 0, + .flags = IHF_IGNORE_IF_DISABLED, + .details = t7_pl_int_cause2_fields, + .actions = t7_pl_int_cause2_actions, + }; + static const struct intr_details t7_pl_perr_cause_fields[] = { + { F_T7_PL_PERR_CRYPTO_KEY, "CRYPTO KEY" }, + { F_T7_PL_PERR_CRYPTO1, "CRYPTO1" }, + { F_T7_PL_PERR_CRYPTO0, "CRYPTO0" }, + { F_T7_PL_PERR_GCACHE, "GCACHE" }, + { F_T7_PL_PERR_ARM, "ARM" }, + { F_T7_PL_PERR_ULP_TX, "ULP TX" }, + { F_T7_PL_PERR_SGE, "SGE" }, + { F_T7_PL_PERR_HMA, "HMA" }, + { F_T7_PL_PERR_CPL_SWITCH, "CPL Switch" }, + { F_T7_PL_PERR_ULP_RX, "ULP RX" }, + { F_T7_PL_PERR_PM_RX, "PM RX" }, + { F_T7_PL_PERR_PM_TX, "PM TX" }, + { F_T7_PL_PERR_MA, "MA" }, + { F_T7_PL_PERR_TP, "TP" }, + { F_T7_PL_PERR_LE, "LE" }, + { F_T7_PL_PERR_EDC1, "EDC1" }, + { F_T7_PL_PERR_EDC0, "EDC0" }, + { F_T7_PL_PERR_MC1, "MC1" }, + { F_T7_PL_PERR_MC0, "MC0" }, + { F_T7_PL_PERR_PCIE, "PCIE" }, + { F_T7_PL_PERR_UART, "UART" }, + { F_T7_PL_PERR_PMU, "PMU" }, + { F_T7_PL_PERR_MAC, "MAC" }, + { F_T7_PL_PERR_SMB, "SMB" }, + { F_T7_PL_PERR_SF, "SF" }, + { F_T7_PL_PERR_PL, "PL" }, + { F_T7_PL_PERR_NCSI, "NC-SI" }, + { F_T7_PL_PERR_MPS, "MPS" }, + { F_T7_PL_PERR_MI, "MI" }, + { F_T7_PL_PERR_DBG, "DBG" }, + { F_T7_PL_PERR_I2CM, "I2CM" }, + { F_T7_PL_PERR_CIM, "CIM" }, + { 0 } + }; + static const struct intr_info t7_pl_perr_cause = { + .name = "PL_PERR_CAUSE", + .cause_reg = A_PL_PERR_CAUSE, + .enable_reg = A_PL_PERR_ENABLE, + .fatal = 0xffffffff, + .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, + .details = t7_pl_perr_cause_fields, .actions = NULL, }; - u32 perr; - - if (chip_id(adap) >= CHELSIO_T7) { - pl_perr_cause.details = t7_pl_intr_details; - pl_intr_info.details = t7_pl_intr_details; - pl_intr_info.actions = t7_pl_intr_action; + bool fatal = false; + uint32_t perr; + + if (chip_id(adap) < CHELSIO_T7) { + perr = get_perr_ucause(adap, &pl_perr_cause); + fatal |= t4_handle_intr(adap, &pl_perr_cause, 0, + flags & ~(IHF_CLR_ALL_SET | IHF_CLR_ALL_UNIGNORED)); + fatal |= t4_handle_intr(adap, &pl_int_cause, + t4_perr_to_ic(adap, perr), flags); + t4_write_reg(adap, pl_perr_cause.cause_reg, perr); + (void)t4_read_reg(adap, pl_perr_cause.cause_reg); } else { - pl_perr_cause.details = pl_intr_details; - pl_intr_info.details = pl_intr_details; - pl_intr_info.actions = pl_intr_action; + perr = get_perr_ucause(adap, &t7_pl_perr_cause); + fatal |= t4_handle_intr(adap, &t7_pl_perr_cause, 0, + flags & ~(IHF_CLR_ALL_SET | IHF_CLR_ALL_UNIGNORED)); + fatal |= t4_handle_intr(adap, &t7_pl_int_cause, + t7_perr_to_ic1(perr), flags); + fatal |= t4_handle_intr(adap, &t7_pl_int_cause2, + t7_perr_to_ic2(perr), flags); + t4_write_reg(adap, t7_pl_perr_cause.cause_reg, perr); + (void)t4_read_reg(adap, t7_pl_perr_cause.cause_reg); } - - perr = t4_read_reg(adap, pl_perr_cause.cause_reg); - if (verbose || perr != 0) { - t4_show_intr_info(adap, &pl_perr_cause, perr); - if (perr != 0) - t4_write_reg(adap, pl_perr_cause.cause_reg, perr); - if (verbose) - perr |= t4_read_reg(adap, pl_intr_info.enable_reg); - } - - return (t4_handle_intr(adap, &pl_intr_info, perr, verbose)); + return (fatal); } -#define PF_INTR_MASK (F_PFSW | F_PFCIM) +void t4_intr_clear(struct adapter *adap) +{ +#if 1 + if (chip_id(adap) >= CHELSIO_T7) + t4_write_reg(adap, A_SGE_INT_CAUSE8, 0xffffffff); +#endif + (void)t4_slow_intr_handler(adap, + IHF_NO_SHOW | IHF_RUN_ALL_ACTIONS | IHF_CLR_ALL_SET); +} /** * t4_intr_enable - enable interrupts @@ -6229,6 +7163,8 @@ void t4_intr_enable(struct adapter *adap) { u32 mask, val; + if (adap->intr_flags & IHF_INTR_CLEAR_ON_INIT) + t4_intr_clear(adap); if (chip_id(adap) <= CHELSIO_T5) val = F_ERR_DROPPED_DB | F_ERR_EGR_CTXT_PRIO | F_DBFIFO_HP_INT | F_DBFIFO_LP_INT; @@ -6241,8 +7177,14 @@ void t4_intr_enable(struct adapter *adap) F_ERR_BAD_DB_PIDX0 | F_ERR_ING_CTXT_PRIO | F_EGRESS_SIZE_ERR; mask = val; t4_set_reg_field(adap, A_SGE_INT_ENABLE3, mask, val); - t4_write_reg(adap, MYPF_REG(A_PL_PF_INT_ENABLE), PF_INTR_MASK); + if (chip_id(adap) >= CHELSIO_T7) + t4_write_reg(adap, A_SGE_INT_ENABLE4, 0xffffffff); + t4_write_reg(adap, MYPF_REG(A_PL_PF_INT_ENABLE), F_PFSW | F_PFCIM); t4_set_reg_field(adap, A_PL_INT_ENABLE, F_SF | F_I2CM, 0); +#if 1 + if (chip_id(adap) >= CHELSIO_T7) + t4_set_reg_field(adap, A_PL_INT_ENABLE, F_MAC0 | F_MAC1 | F_MAC2 | F_MAC3, 0); +#endif t4_set_reg_field(adap, A_PL_INT_MAP0, 0, 1 << adap->pf); } @@ -6439,9 +7381,15 @@ int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid, /* Read an RSS table row */ static int rd_rss_row(struct adapter *adap, int row, u32 *val) { - t4_write_reg(adap, A_TP_RSS_LKP_TABLE, 0xfff00000 | row); - return t4_wait_op_done_val(adap, A_TP_RSS_LKP_TABLE, F_LKPTBLROWVLD, 1, - 5, 0, val); + if (chip_id(adap) < CHELSIO_T7) { + t4_write_reg(adap, A_TP_RSS_LKP_TABLE, 0xfff00000 | row); + return t4_wait_op_done_val(adap, A_TP_RSS_LKP_TABLE, + F_LKPTBLROWVLD, 1, 5, 0, val); + } else { + t4_write_reg(adap, A_TP_RSS_CONFIG_SRAM, 0xB0000 | row); + return t7_wait_sram_done(adap, A_TP_RSS_CONFIG_SRAM, + A_TP_RSS_LKP_TABLE, 5, 0, val); + } } /** @@ -10178,7 +11126,7 @@ const struct chip_params *t4_get_chip_params(int chipid) .vfcount = 256, .sge_fl_db = 0, .sge_ctxt_size = SGE_CTXT_SIZE_T7, - .mps_tcam_size = NUM_MPS_T5_CLS_SRAM_L_INSTANCES, + .mps_tcam_size = NUM_MPS_T5_CLS_SRAM_L_INSTANCES * 3, .rss_nentries = T7_RSS_NENTRIES, .cim_la_size = CIMLA_SIZE_T6, }, diff --git a/sys/dev/cxgbe/common/t4_msg.h b/sys/dev/cxgbe/common/t4_msg.h index 0d12ccf2e910..214080964fbb 100644 --- a/sys/dev/cxgbe/common/t4_msg.h +++ b/sys/dev/cxgbe/common/t4_msg.h @@ -30,6 +30,7 @@ #define T4_MSG_H enum cpl_opcodes { + CPL_TLS_TX_SCMD_FMT = 0x0, CPL_PASS_OPEN_REQ = 0x1, CPL_PASS_ACCEPT_RPL = 0x2, CPL_ACT_OPEN_REQ = 0x3, @@ -48,6 +49,8 @@ enum cpl_opcodes { CPL_RTE_READ_REQ = 0x11, CPL_L2T_WRITE_REQ = 0x12, CPL_L2T_READ_REQ = 0x13, + CPL_GRE_TABLE_REQ = 0x1b, + CPL_GRE_TABLE_RPL = 0xbb, CPL_SMT_WRITE_REQ = 0x14, CPL_SMT_READ_REQ = 0x15, CPL_TAG_WRITE_REQ = 0x16, @@ -130,6 +133,7 @@ enum cpl_opcodes { CPL_TX_TLS_SFO = 0x89, CPL_TX_SEC_PDU = 0x8A, CPL_TX_TLS_ACK = 0x8B, + CPL_TX_QUIC_ENC = 0x8d, CPL_RCB_UPD = 0x8C, CPL_SGE_FLR_FLUSH = 0xA0, @@ -258,6 +262,7 @@ enum { ULP_MODE_TCPDDP = 5, ULP_MODE_FCOE = 6, ULP_MODE_TLS = 8, + ULP_MODE_DTLS = 9, ULP_MODE_RDMA_V2 = 10, ULP_MODE_NVMET = 11, }; @@ -1149,23 +1154,36 @@ struct cpl_get_tcb { #define V_QUEUENO(x) ((x) << S_QUEUENO) #define G_QUEUENO(x) (((x) >> S_QUEUENO) & M_QUEUENO) -#define S_T7_QUEUENO 0 -#define M_T7_QUEUENO 0xFFF -#define V_T7_QUEUENO(x) ((x) << S_T7_QUEUENO) -#define G_T7_QUEUENO(x) (((x) >> S_T7_QUEUENO) & M_T7_QUEUENO) - #define S_REPLY_CHAN 14 #define V_REPLY_CHAN(x) ((x) << S_REPLY_CHAN) #define F_REPLY_CHAN V_REPLY_CHAN(1U) +#define S_NO_REPLY 15 +#define V_NO_REPLY(x) ((x) << S_NO_REPLY) +#define F_NO_REPLY V_NO_REPLY(1U) + +struct cpl_t7_get_tcb { + WR_HDR; + union opcode_tid ot; + __be16 rxchan_queue; + __be16 cookie_pkd; +}; + #define S_T7_REPLY_CHAN 12 #define M_T7_REPLY_CHAN 0x7 #define V_T7_REPLY_CHAN(x) ((x) << S_T7_REPLY_CHAN) #define G_T7_REPLY_CHAN(x) (((x) >> S_T7_REPLY_CHAN) & M_T7_REPLY_CHAN) -#define S_NO_REPLY 15 -#define V_NO_REPLY(x) ((x) << S_NO_REPLY) -#define F_NO_REPLY V_NO_REPLY(1U) +#define S_T7_QUEUENO 0 +#define M_T7_QUEUENO 0xFFF +#define V_T7_QUEUENO(x) ((x) << S_T7_QUEUENO) +#define G_T7_QUEUENO(x) (((x) >> S_T7_QUEUENO) & M_T7_QUEUENO) + +#define S_CPL_GET_TCB_COOKIE 0 +#define M_CPL_GET_TCB_COOKIE 0xff +#define V_CPL_GET_TCB_COOKIE(x) ((x) << S_CPL_GET_TCB_COOKIE) +#define G_CPL_GET_TCB_COOKIE(x) \ + (((x) >> S_CPL_GET_TCB_COOKIE) & M_CPL_GET_TCB_COOKIE) struct cpl_get_tcb_rpl { RSS_HDR @@ -1234,6 +1252,16 @@ struct cpl_close_con_rpl { __be32 rcv_nxt; }; +struct cpl_t7_close_con_rpl { + RSS_HDR + union opcode_tid ot; + __be16 rto; + __u8 rsvd; + __u8 status; + __be32 snd_nxt; + __be32 rcv_nxt; +}; + struct cpl_close_listsvr_req { WR_HDR; union opcode_tid ot; @@ -1340,6 +1368,24 @@ struct cpl_abort_rpl_rss { __u8 status; }; +struct cpl_t7_abort_rpl_rss { + RSS_HDR + union opcode_tid ot; + __be32 idx_status; +}; + +#define S_CPL_ABORT_RPL_RSS_IDX 8 +#define M_CPL_ABORT_RPL_RSS_IDX 0xffffff +#define V_CPL_ABORT_RPL_RSS_IDX(x) ((x) << S_CPL_ABORT_RPL_RSS_IDX) +#define G_CPL_ABORT_RPL_RSS_IDX(x) \ + (((x) >> S_CPL_ABORT_RPL_RSS_IDX) & M_CPL_ABORT_RPL_RSS_IDX) + +#define S_CPL_ABORT_RPL_RSS_STATUS 0 +#define M_CPL_ABORT_RPL_RSS_STATUS 0xff +#define V_CPL_ABORT_RPL_RSS_STATUS(x) ((x) << S_CPL_ABORT_RPL_RSS_STATUS) +#define G_CPL_ABORT_RPL_RSS_STATUS(x) \ + (((x) >> S_CPL_ABORT_RPL_RSS_STATUS) & M_CPL_ABORT_RPL_RSS_STATUS) + struct cpl_abort_rpl_rss6 { RSS_HDR union opcode_tid ot; @@ -1444,6 +1490,11 @@ struct cpl_tx_data { #define V_TX_ULP_MODE(x) ((x) << S_TX_ULP_MODE) #define G_TX_ULP_MODE(x) (((x) >> S_TX_ULP_MODE) & M_TX_ULP_MODE) +#define S_T7_TX_ULP_MODE 10 +#define M_T7_TX_ULP_MODE 0xf +#define V_T7_TX_ULP_MODE(x) ((x) << S_T7_TX_ULP_MODE) +#define G_T7_TX_ULP_MODE(x) (((x) >> S_T7_TX_ULP_MODE) & M_T7_TX_ULP_MODE) + #define S_TX_FORCE 13 #define V_TX_FORCE(x) ((x) << S_TX_FORCE) #define F_TX_FORCE V_TX_FORCE(1U) @@ -1881,14 +1932,6 @@ struct cpl_tx_pkt_xt { (((x) >> S_CPL_TX_PKT_XT_ROCEIPHDRLEN_HI) & \ M_CPL_TX_PKT_XT_ROCEIPHDRLEN_HI) -#define S_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO 30 -#define M_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO 0x3 -#define V_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO(x) \ - ((x) << S_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO) -#define G_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO(x) \ - (((x) >> S_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO) & \ - M_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO) - /* cpl_tx_pkt_xt.core.ctrl2 fields */ #define S_CPL_TX_PKT_XT_CHKINSRTOFFSET_LO 30 #define M_CPL_TX_PKT_XT_CHKINSRTOFFSET_LO 0x3 @@ -1898,6 +1941,14 @@ struct cpl_tx_pkt_xt { (((x) >> S_CPL_TX_PKT_XT_CHKINSRTOFFSET_LO) & \ M_CPL_TX_PKT_XT_CHKINSRTOFFSET_LO) +#define S_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO 30 +#define M_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO 0x3 +#define V_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO(x) \ + ((x) << S_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO) +#define G_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO(x) \ + (((x) >> S_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO) & \ + M_CPL_TX_PKT_XT_ROCEIPHDRLEN_LO) + #define S_CPL_TX_PKT_XT_CHKSTARTOFFSET 20 #define M_CPL_TX_PKT_XT_CHKSTARTOFFSET 0x3ff #define V_CPL_TX_PKT_XT_CHKSTARTOFFSET(x) \ @@ -2190,7 +2241,8 @@ struct cpl_t7_tx_data_iso { __be32 num_pi_bytes_seglen_offset; __be32 datasn_offset; __be32 buffer_offset; - __be32 reserved3; + __be32 pdo_pkd; + /* encapsulated CPL_TX_DATA follows here */ }; #define S_CPL_T7_TX_DATA_ISO_OPCODE 24 @@ -2274,6 +2326,12 @@ struct cpl_t7_tx_data_iso { (((x) >> S_CPL_T7_TX_DATA_ISO_DATASEGLENOFFSET) & \ M_CPL_T7_TX_DATA_ISO_DATASEGLENOFFSET) +#define S_CPL_TX_DATA_ISO_PDO 0 +#define M_CPL_TX_DATA_ISO_PDO 0xff +#define V_CPL_TX_DATA_ISO_PDO(x) ((x) << S_CPL_TX_DATA_ISO_PDO) +#define G_CPL_TX_DATA_ISO_PDO(x) \ + (((x) >> S_CPL_TX_DATA_ISO_PDO) & M_CPL_TX_DATA_ISO_PDO) + struct cpl_iscsi_hdr { RSS_HDR union opcode_tid ot; @@ -2419,6 +2477,74 @@ struct cpl_rx_data_ack_core { #define V_RX_DACK_CHANGE(x) ((x) << S_RX_DACK_CHANGE) #define F_RX_DACK_CHANGE V_RX_DACK_CHANGE(1U) +struct cpl_rx_phys_addr { + __be32 RSS[2]; + __be32 op_to_tid; + __be32 pci_rlx_order_to_len; + __be64 phys_addr; +}; + +#define S_CPL_RX_PHYS_ADDR_OPCODE 24 +#define M_CPL_RX_PHYS_ADDR_OPCODE 0xff +#define V_CPL_RX_PHYS_ADDR_OPCODE(x) ((x) << S_CPL_RX_PHYS_ADDR_OPCODE) +#define G_CPL_RX_PHYS_ADDR_OPCODE(x) \ + (((x) >> S_CPL_RX_PHYS_ADDR_OPCODE) & M_CPL_RX_PHYS_ADDR_OPCODE) + +#define S_CPL_RX_PHYS_ADDR_ISRDMA 23 +#define M_CPL_RX_PHYS_ADDR_ISRDMA 0x1 +#define V_CPL_RX_PHYS_ADDR_ISRDMA(x) ((x) << S_CPL_RX_PHYS_ADDR_ISRDMA) +#define G_CPL_RX_PHYS_ADDR_ISRDMA(x) \ + (((x) >> S_CPL_RX_PHYS_ADDR_ISRDMA) & M_CPL_RX_PHYS_ADDR_ISRDMA) +#define F_CPL_RX_PHYS_ADDR_ISRDMA V_CPL_RX_PHYS_ADDR_ISRDMA(1U) + +#define S_CPL_RX_PHYS_ADDR_TID 0 +#define M_CPL_RX_PHYS_ADDR_TID 0xfffff +#define V_CPL_RX_PHYS_ADDR_TID(x) ((x) << S_CPL_RX_PHYS_ADDR_TID) +#define G_CPL_RX_PHYS_ADDR_TID(x) \ + (((x) >> S_CPL_RX_PHYS_ADDR_TID) & M_CPL_RX_PHYS_ADDR_TID) + +#define S_CPL_RX_PHYS_ADDR_PCIRLXORDER 31 +#define M_CPL_RX_PHYS_ADDR_PCIRLXORDER 0x1 +#define V_CPL_RX_PHYS_ADDR_PCIRLXORDER(x) \ + ((x) << S_CPL_RX_PHYS_ADDR_PCIRLXORDER) +#define G_CPL_RX_PHYS_ADDR_PCIRLXORDER(x) \ + (((x) >> S_CPL_RX_PHYS_ADDR_PCIRLXORDER) & M_CPL_RX_PHYS_ADDR_PCIRLXORDER) +#define F_CPL_RX_PHYS_ADDR_PCIRLXORDER V_CPL_RX_PHYS_ADDR_PCIRLXORDER(1U) + +#define S_CPL_RX_PHYS_ADDR_PCINOSNOOP 30 +#define M_CPL_RX_PHYS_ADDR_PCINOSNOOP 0x1 +#define V_CPL_RX_PHYS_ADDR_PCINOSNOOP(x) \ + ((x) << S_CPL_RX_PHYS_ADDR_PCINOSNOOP) +#define G_CPL_RX_PHYS_ADDR_PCINOSNOOP(x) \ + (((x) >> S_CPL_RX_PHYS_ADDR_PCINOSNOOP) & M_CPL_RX_PHYS_ADDR_PCINOSNOOP) +#define F_CPL_RX_PHYS_ADDR_PCINOSNOOP V_CPL_RX_PHYS_ADDR_PCINOSNOOP(1U) + +#define S_CPL_RX_PHYS_ADDR_PCITPHINTEN 29 +#define M_CPL_RX_PHYS_ADDR_PCITPHINTEN 0x1 +#define V_CPL_RX_PHYS_ADDR_PCITPHINTEN(x) \ + ((x) << S_CPL_RX_PHYS_ADDR_PCITPHINTEN) +#define G_CPL_RX_PHYS_ADDR_PCITPHINTEN(x) \ + (((x) >> S_CPL_RX_PHYS_ADDR_PCITPHINTEN) & M_CPL_RX_PHYS_ADDR_PCITPHINTEN) +#define F_CPL_RX_PHYS_ADDR_PCITPHINTEN V_CPL_RX_PHYS_ADDR_PCITPHINTEN(1U) + +#define S_CPL_RX_PHYS_ADDR_PCITPHINT 27 +#define M_CPL_RX_PHYS_ADDR_PCITPHINT 0x3 +#define V_CPL_RX_PHYS_ADDR_PCITPHINT(x) ((x) << S_CPL_RX_PHYS_ADDR_PCITPHINT) +#define G_CPL_RX_PHYS_ADDR_PCITPHINT(x) \ + (((x) >> S_CPL_RX_PHYS_ADDR_PCITPHINT) & M_CPL_RX_PHYS_ADDR_PCITPHINT) + +#define S_CPL_RX_PHYS_ADDR_DCAID 16 +#define M_CPL_RX_PHYS_ADDR_DCAID 0x7ff +#define V_CPL_RX_PHYS_ADDR_DCAID(x) ((x) << S_CPL_RX_PHYS_ADDR_DCAID) +#define G_CPL_RX_PHYS_ADDR_DCAID(x) \ + (((x) >> S_CPL_RX_PHYS_ADDR_DCAID) & M_CPL_RX_PHYS_ADDR_DCAID) + +#define S_CPL_RX_PHYS_ADDR_LEN 0 +#define M_CPL_RX_PHYS_ADDR_LEN 0xffff +#define V_CPL_RX_PHYS_ADDR_LEN(x) ((x) << S_CPL_RX_PHYS_ADDR_LEN) +#define G_CPL_RX_PHYS_ADDR_LEN(x) \ + (((x) >> S_CPL_RX_PHYS_ADDR_LEN) & M_CPL_RX_PHYS_ADDR_LEN) + struct cpl_rx_ddp_complete { RSS_HDR union opcode_tid ot; @@ -4059,13 +4185,6 @@ struct cpl_rdma_cqe_ext { #define G_CPL_RDMA_CQE_EXT_QPID(x) \ (((x) >> S_CPL_RDMA_CQE_EXT_QPID) & M_CPL_RDMA_CQE_EXT_QPID) -#define S_CPL_RDMA_CQE_EXT_EXTMODE 11 -#define M_CPL_RDMA_CQE_EXT_EXTMODE 0x1 -#define V_CPL_RDMA_CQE_EXT_EXTMODE(x) ((x) << S_CPL_RDMA_CQE_EXT_EXTMODE) -#define G_CPL_RDMA_CQE_EXT_EXTMODE(x) \ - (((x) >> S_CPL_RDMA_CQE_EXT_EXTMODE) & M_CPL_RDMA_CQE_EXT_EXTMODE) -#define F_CPL_RDMA_CQE_EXT_EXTMODE V_CPL_RDMA_CQE_EXT_EXTMODE(1U) - #define S_CPL_RDMA_CQE_EXT_GENERATION_BIT 10 #define M_CPL_RDMA_CQE_EXT_GENERATION_BIT 0x1 #define V_CPL_RDMA_CQE_EXT_GENERATION_BIT(x) \ @@ -4109,6 +4228,13 @@ struct cpl_rdma_cqe_ext { #define G_CPL_RDMA_CQE_EXT_WR_TYPE_EXT(x) \ (((x) >> S_CPL_RDMA_CQE_EXT_WR_TYPE_EXT) & M_CPL_RDMA_CQE_EXT_WR_TYPE_EXT) +#define S_CPL_RDMA_CQE_EXT_EXTMODE 23 +#define M_CPL_RDMA_CQE_EXT_EXTMODE 0x1 +#define V_CPL_RDMA_CQE_EXT_EXTMODE(x) ((x) << S_CPL_RDMA_CQE_EXT_EXTMODE) +#define G_CPL_RDMA_CQE_EXT_EXTMODE(x) \ + (((x) >> S_CPL_RDMA_CQE_EXT_EXTMODE) & M_CPL_RDMA_CQE_EXT_EXTMODE) +#define F_CPL_RDMA_CQE_EXT_EXTMODE V_CPL_RDMA_CQE_EXT_EXTMODE(1U) + #define S_CPL_RDMA_CQE_EXT_SRQ 0 #define M_CPL_RDMA_CQE_EXT_SRQ 0xfff #define V_CPL_RDMA_CQE_EXT_SRQ(x) ((x) << S_CPL_RDMA_CQE_EXT_SRQ) @@ -4161,14 +4287,6 @@ struct cpl_rdma_cqe_fw_ext { #define G_CPL_RDMA_CQE_FW_EXT_QPID(x) \ (((x) >> S_CPL_RDMA_CQE_FW_EXT_QPID) & M_CPL_RDMA_CQE_FW_EXT_QPID) -#define S_CPL_RDMA_CQE_FW_EXT_EXTMODE 11 -#define M_CPL_RDMA_CQE_FW_EXT_EXTMODE 0x1 -#define V_CPL_RDMA_CQE_FW_EXT_EXTMODE(x) \ - ((x) << S_CPL_RDMA_CQE_FW_EXT_EXTMODE) -#define G_CPL_RDMA_CQE_FW_EXT_EXTMODE(x) \ - (((x) >> S_CPL_RDMA_CQE_FW_EXT_EXTMODE) & M_CPL_RDMA_CQE_FW_EXT_EXTMODE) -#define F_CPL_RDMA_CQE_FW_EXT_EXTMODE V_CPL_RDMA_CQE_FW_EXT_EXTMODE(1U) - #define S_CPL_RDMA_CQE_FW_EXT_GENERATION_BIT 10 #define M_CPL_RDMA_CQE_FW_EXT_GENERATION_BIT 0x1 #define V_CPL_RDMA_CQE_FW_EXT_GENERATION_BIT(x) \ @@ -4215,6 +4333,14 @@ struct cpl_rdma_cqe_fw_ext { (((x) >> S_CPL_RDMA_CQE_FW_EXT_WR_TYPE_EXT) & \ M_CPL_RDMA_CQE_FW_EXT_WR_TYPE_EXT) +#define S_CPL_RDMA_CQE_FW_EXT_EXTMODE 23 +#define M_CPL_RDMA_CQE_FW_EXT_EXTMODE 0x1 +#define V_CPL_RDMA_CQE_FW_EXT_EXTMODE(x) \ + ((x) << S_CPL_RDMA_CQE_FW_EXT_EXTMODE) +#define G_CPL_RDMA_CQE_FW_EXT_EXTMODE(x) \ + (((x) >> S_CPL_RDMA_CQE_FW_EXT_EXTMODE) & M_CPL_RDMA_CQE_FW_EXT_EXTMODE) +#define F_CPL_RDMA_CQE_FW_EXT_EXTMODE V_CPL_RDMA_CQE_FW_EXT_EXTMODE(1U) + #define S_CPL_RDMA_CQE_FW_EXT_SRQ 0 #define M_CPL_RDMA_CQE_FW_EXT_SRQ 0xfff #define V_CPL_RDMA_CQE_FW_EXT_SRQ(x) ((x) << S_CPL_RDMA_CQE_FW_EXT_SRQ) @@ -4267,14 +4393,6 @@ struct cpl_rdma_cqe_err_ext { #define G_CPL_RDMA_CQE_ERR_EXT_QPID(x) \ (((x) >> S_CPL_RDMA_CQE_ERR_EXT_QPID) & M_CPL_RDMA_CQE_ERR_EXT_QPID) -#define S_CPL_RDMA_CQE_ERR_EXT_EXTMODE 11 -#define M_CPL_RDMA_CQE_ERR_EXT_EXTMODE 0x1 -#define V_CPL_RDMA_CQE_ERR_EXT_EXTMODE(x) \ - ((x) << S_CPL_RDMA_CQE_ERR_EXT_EXTMODE) -#define G_CPL_RDMA_CQE_ERR_EXT_EXTMODE(x) \ - (((x) >> S_CPL_RDMA_CQE_ERR_EXT_EXTMODE) & M_CPL_RDMA_CQE_ERR_EXT_EXTMODE) -#define F_CPL_RDMA_CQE_ERR_EXT_EXTMODE V_CPL_RDMA_CQE_ERR_EXT_EXTMODE(1U) - #define S_CPL_RDMA_CQE_ERR_EXT_GENERATION_BIT 10 #define M_CPL_RDMA_CQE_ERR_EXT_GENERATION_BIT 0x1 #define V_CPL_RDMA_CQE_ERR_EXT_GENERATION_BIT(x) \ @@ -4323,6 +4441,14 @@ struct cpl_rdma_cqe_err_ext { (((x) >> S_CPL_RDMA_CQE_ERR_EXT_WR_TYPE_EXT) & \ M_CPL_RDMA_CQE_ERR_EXT_WR_TYPE_EXT) +#define S_CPL_RDMA_CQE_ERR_EXT_EXTMODE 23 +#define M_CPL_RDMA_CQE_ERR_EXT_EXTMODE 0x1 +#define V_CPL_RDMA_CQE_ERR_EXT_EXTMODE(x) \ + ((x) << S_CPL_RDMA_CQE_ERR_EXT_EXTMODE) +#define G_CPL_RDMA_CQE_ERR_EXT_EXTMODE(x) \ + (((x) >> S_CPL_RDMA_CQE_ERR_EXT_EXTMODE) & M_CPL_RDMA_CQE_ERR_EXT_EXTMODE) +#define F_CPL_RDMA_CQE_ERR_EXT_EXTMODE V_CPL_RDMA_CQE_ERR_EXT_EXTMODE(1U) + #define S_CPL_RDMA_CQE_ERR_EXT_SRQ 0 #define M_CPL_RDMA_CQE_ERR_EXT_SRQ 0xfff #define V_CPL_RDMA_CQE_ERR_EXT_SRQ(x) ((x) << S_CPL_RDMA_CQE_ERR_EXT_SRQ) @@ -5040,6 +5166,58 @@ struct cpl_tx_tnl_lso { #define G_CPL_TX_TNL_LSO_SIZE(x) \ (((x) >> S_CPL_TX_TNL_LSO_SIZE) & M_CPL_TX_TNL_LSO_SIZE) +#define S_CPL_TX_TNL_LSO_BTH_OPCODE 24 +#define M_CPL_TX_TNL_LSO_BTH_OPCODE 0xff +#define V_CPL_TX_TNL_LSO_BTH_OPCODE(x) ((x) << S_CPL_TX_TNL_LSO_BTH_OPCODE) +#define G_CPL_TX_TNL_LSO_BTH_OPCODE(x) \ + (((x) >> S_CPL_TX_TNL_LSO_BTH_OPCODE) & \ + M_CPL_TX_TNL_LSO_BTH_OPCODE) + +#define S_CPL_TX_TNL_LSO_TCPSEQOFFSET_PSN 0 +#define M_CPL_TX_TNL_LSO_TCPSEQOFFSET_PSN 0xffffff +#define V_CPL_TX_TNL_LSO_TCPSEQOFFSET_PSN(x) \ + ((x) << S_CPL_TX_TNL_LSO_TCPSEQOFFSET_PSN) +#define G_CPL_TX_TNL_LSO_TCPSEQOFFSET_PSN(x) \ + (((x) >> S_CPL_TX_TNL_LSO_TCPSEQOFFSET_PSN) & \ + M_CPL_TX_TNL_LSO_TCPSEQOFFSET_PSN) + +#define S_CPL_TX_TNL_LSO_MSS_TVER 8 +#define M_CPL_TX_TNL_LSO_MSS_TVER 0xf +#define V_CPL_TX_TNL_LSO_MSS_TVER(x) ((x) << S_CPL_TX_TNL_LSO_MSS_TVER) +#define G_CPL_TX_TNL_LSO_MSS_TVER(x) \ + (((x) >> S_CPL_TX_TNL_LSO_MSS_TVER) & M_CPL_TX_TNL_LSO_MSS_TVER) + +#define S_CPL_TX_TNL_LSO_MSS_M 7 +#define M_CPL_TX_TNL_LSO_MSS_M 0x1 +#define V_CPL_TX_TNL_LSO_MSS_M(x) ((x) << S_CPL_TX_TNL_LSO_MSS_M) +#define G_CPL_TX_TNL_LSO_MSS_M(x) \ + (((x) >> S_CPL_TX_TNL_LSO_MSS_M) & M_CPL_TX_TNL_LSO_MSS_M) + +#define S_CPL_TX_TNL_LSO_MSS_PMTU 4 +#define M_CPL_TX_TNL_LSO_MSS_PMTU 0x7 +#define V_CPL_TX_TNL_LSO_MSS_PMTU(x) ((x) << S_CPL_TX_TNL_LSO_MSS_PMTU) +#define G_CPL_TX_TNL_LSO_MSS_PMTU(x) \ + (((x) >> S_CPL_TX_TNL_LSO_MSS_PMTU) & M_CPL_TX_TNL_LSO_MSS_PMTU) + +#define S_CPL_TX_TNL_LSO_MSS_RR_MSN_INCR 3 +#define M_CPL_TX_TNL_LSO_MSS_RR_MSN_INCR 0x1 +#define V_CPL_TX_TNL_LSO_MSS_RR_MSN_INCR(x) \ + ((x) << S_CPL_TX_TNL_LSO_MSS_RR_MSN_INCR) +#define G_CPL_TX_TNL_LSO_MSS_RR_MSN_INCR(x) \ + (((x) >> S_CPL_TX_TNL_LSO_MSS_RR_MSN_INCR) & M_CPL_TX_TNL_LSO_MSS_RR_MSN_INCR) + +#define S_CPL_TX_TNL_LSO_MSS_ACKREQ 1 +#define M_CPL_TX_TNL_LSO_MSS_ACKREQ 0x3 +#define V_CPL_TX_TNL_LSO_MSS_ACKREQ(x) ((x) << S_CPL_TX_TNL_LSO_MSS_ACKREQ) +#define G_CPL_TX_TNL_LSO_MSS_ACKREQ(x) \ + (((x) >> S_CPL_TX_TNL_LSO_MSS_ACKREQ) & M_CPL_TX_TNL_LSO_MSS_ACKREQ) + +#define S_CPL_TX_TNL_LSO_MSS_SE 0 +#define M_CPL_TX_TNL_LSO_MSS_SE 0x1 +#define V_CPL_TX_TNL_LSO_MSS_SE(x) ((x) << S_CPL_TX_TNL_LSO_MSS_SE) +#define G_CPL_TX_TNL_LSO_MSS_SE(x) \ + (((x) >> S_CPL_TX_TNL_LSO_MSS_SE) & M_CPL_TX_TNL_LSO_MSS_SE) + struct cpl_rx_mps_pkt { __be32 op_to_r1_hi; __be32 r1_lo_length; @@ -5839,10 +6017,10 @@ struct cpl_tx_tls_ack { #define G_CPL_TX_TLS_ACK_OPCODE(x) \ (((x) >> S_CPL_TX_TLS_ACK_OPCODE) & M_CPL_TX_TLS_ACK_OPCODE) -#define S_T7_CPL_TX_TLS_ACK_RXCHID 22 -#define M_T7_CPL_TX_TLS_ACK_RXCHID 0x3 -#define V_T7_CPL_TX_TLS_ACK_RXCHID(x) ((x) << S_T7_CPL_TX_TLS_ACK_RXCHID) -#define G_T7_CPL_TX_TLS_ACK_RXCHID(x) \ +#define S_T7_CPL_TX_TLS_ACK_RXCHID 22 +#define M_T7_CPL_TX_TLS_ACK_RXCHID 0x3 +#define V_T7_CPL_TX_TLS_ACK_RXCHID(x) ((x) << S_T7_CPL_TX_TLS_ACK_RXCHID) +#define G_T7_CPL_TX_TLS_ACK_RXCHID(x) \ (((x) >> S_T7_CPL_TX_TLS_ACK_RXCHID) & M_T7_CPL_TX_TLS_ACK_RXCHID) #define S_CPL_TX_TLS_ACK_RXCHID 22 @@ -5905,11 +6083,245 @@ struct cpl_tx_tls_ack { #define G_CPL_TX_TLS_ACK_PLDLEN(x) \ (((x) >> S_CPL_TX_TLS_ACK_PLDLEN) & M_CPL_TX_TLS_ACK_PLDLEN) +struct cpl_tx_quic_enc { + __be32 op_to_hdrlen; + __be32 hdrlen_to_pktlen; + __be32 r4[2]; +}; + +#define S_CPL_TX_QUIC_ENC_OPCODE 24 +#define M_CPL_TX_QUIC_ENC_OPCODE 0xff +#define V_CPL_TX_QUIC_ENC_OPCODE(x) ((x) << S_CPL_TX_QUIC_ENC_OPCODE) +#define G_CPL_TX_QUIC_ENC_OPCODE(x) \ + (((x) >> S_CPL_TX_QUIC_ENC_OPCODE) & M_CPL_TX_QUIC_ENC_OPCODE) + +#define S_CPL_TX_QUIC_ENC_KEYSIZE 22 +#define M_CPL_TX_QUIC_ENC_KEYSIZE 0x3 +#define V_CPL_TX_QUIC_ENC_KEYSIZE(x) ((x) << S_CPL_TX_QUIC_ENC_KEYSIZE) +#define G_CPL_TX_QUIC_ENC_KEYSIZE(x) \ + (((x) >> S_CPL_TX_QUIC_ENC_KEYSIZE) & M_CPL_TX_QUIC_ENC_KEYSIZE) + +#define S_CPL_TX_QUIC_ENC_PKTNUMSIZE 20 +#define M_CPL_TX_QUIC_ENC_PKTNUMSIZE 0x3 +#define V_CPL_TX_QUIC_ENC_PKTNUMSIZE(x) ((x) << S_CPL_TX_QUIC_ENC_PKTNUMSIZE) +#define G_CPL_TX_QUIC_ENC_PKTNUMSIZE(x) \ + (((x) >> S_CPL_TX_QUIC_ENC_PKTNUMSIZE) & M_CPL_TX_QUIC_ENC_PKTNUMSIZE) + +#define S_CPL_TX_QUIC_ENC_HDRTYPE 19 +#define M_CPL_TX_QUIC_ENC_HDRTYPE 0x1 +#define V_CPL_TX_QUIC_ENC_HDRTYPE(x) ((x) << S_CPL_TX_QUIC_ENC_HDRTYPE) +#define G_CPL_TX_QUIC_ENC_HDRTYPE(x) \ + (((x) >> S_CPL_TX_QUIC_ENC_HDRTYPE) & M_CPL_TX_QUIC_ENC_HDRTYPE) +#define F_CPL_TX_QUIC_ENC_HDRTYPE V_CPL_TX_QUIC_ENC_HDRTYPE(1U) + +#define S_CPL_TX_QUIC_ENC_HDRSTARTOFFSET 4 +#define M_CPL_TX_QUIC_ENC_HDRSTARTOFFSET 0xfff +#define V_CPL_TX_QUIC_ENC_HDRSTARTOFFSET(x) \ + ((x) << S_CPL_TX_QUIC_ENC_HDRSTARTOFFSET) +#define G_CPL_TX_QUIC_ENC_HDRSTARTOFFSET(x) \ + (((x) >> S_CPL_TX_QUIC_ENC_HDRSTARTOFFSET) & \ + M_CPL_TX_QUIC_ENC_HDRSTARTOFFSET) + +#define S_CPL_TX_QUIC_ENC_HDRLENGTH_HI 0 +#define M_CPL_TX_QUIC_ENC_HDRLENGTH_HI 0x3 +#define V_CPL_TX_QUIC_ENC_HDRLENGTH_HI(x) \ + ((x) << S_CPL_TX_QUIC_ENC_HDRLENGTH_HI) +#define G_CPL_TX_QUIC_ENC_HDRLENGTH_HI(x) \ + (((x) >> S_CPL_TX_QUIC_ENC_HDRLENGTH_HI) & M_CPL_TX_QUIC_ENC_HDRLENGTH_HI) + +#define S_CPL_TX_QUIC_ENC_HDRLENGTH_LO 24 +#define M_CPL_TX_QUIC_ENC_HDRLENGTH_LO 0xff +#define V_CPL_TX_QUIC_ENC_HDRLENGTH_LO(x) \ + ((x) << S_CPL_TX_QUIC_ENC_HDRLENGTH_LO) +#define G_CPL_TX_QUIC_ENC_HDRLENGTH_LO(x) \ + (((x) >> S_CPL_TX_QUIC_ENC_HDRLENGTH_LO) & M_CPL_TX_QUIC_ENC_HDRLENGTH_LO) + +#define S_CPL_TX_QUIC_ENC_NUMPKT 16 +#define M_CPL_TX_QUIC_ENC_NUMPKT 0xff +#define V_CPL_TX_QUIC_ENC_NUMPKT(x) ((x) << S_CPL_TX_QUIC_ENC_NUMPKT) +#define G_CPL_TX_QUIC_ENC_NUMPKT(x) \ + (((x) >> S_CPL_TX_QUIC_ENC_NUMPKT) & M_CPL_TX_QUIC_ENC_NUMPKT) + +#define S_CPL_TX_QUIC_ENC_PKTLEN 0 +#define M_CPL_TX_QUIC_ENC_PKTLEN 0xffff +#define V_CPL_TX_QUIC_ENC_PKTLEN(x) ((x) << S_CPL_TX_QUIC_ENC_PKTLEN) +#define G_CPL_TX_QUIC_ENC_PKTLEN(x) \ + (((x) >> S_CPL_TX_QUIC_ENC_PKTLEN) & M_CPL_TX_QUIC_ENC_PKTLEN) + +struct cpl_tls_tx_scmd_fmt { + __be32 op_to_num_ivs; + __be32 enb_dbgId_to_hdrlen; + __be32 seq_num[2]; +}; + +#define S_CPL_TLS_TX_SCMD_FMT_OPCODE 31 +#define M_CPL_TLS_TX_SCMD_FMT_OPCODE 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_OPCODE(x) ((x) << S_CPL_TLS_TX_SCMD_FMT_OPCODE) +#define G_CPL_TLS_TX_SCMD_FMT_OPCODE(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_OPCODE) & M_CPL_TLS_TX_SCMD_FMT_OPCODE) +#define F_CPL_TLS_TX_SCMD_FMT_OPCODE V_CPL_TLS_TX_SCMD_FMT_OPCODE(1U) + +#define S_CPL_TLS_TX_SCMD_FMT_SEQNUMBERCTRL 29 +#define M_CPL_TLS_TX_SCMD_FMT_SEQNUMBERCTRL 0x3 +#define V_CPL_TLS_TX_SCMD_FMT_SEQNUMBERCTRL(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_SEQNUMBERCTRL) +#define G_CPL_TLS_TX_SCMD_FMT_SEQNUMBERCTRL(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_SEQNUMBERCTRL) & \ + M_CPL_TLS_TX_SCMD_FMT_SEQNUMBERCTRL) + +#define S_CPL_TLS_TX_SCMD_FMT_PROTOVERSION 24 +#define M_CPL_TLS_TX_SCMD_FMT_PROTOVERSION 0xf +#define V_CPL_TLS_TX_SCMD_FMT_PROTOVERSION(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_PROTOVERSION) +#define G_CPL_TLS_TX_SCMD_FMT_PROTOVERSION(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_PROTOVERSION) & \ + M_CPL_TLS_TX_SCMD_FMT_PROTOVERSION) + +#define S_CPL_TLS_TX_SCMD_FMT_ENCDECCTRL 23 +#define M_CPL_TLS_TX_SCMD_FMT_ENCDECCTRL 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_ENCDECCTRL(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_ENCDECCTRL) +#define G_CPL_TLS_TX_SCMD_FMT_ENCDECCTRL(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_ENCDECCTRL) & \ + M_CPL_TLS_TX_SCMD_FMT_ENCDECCTRL) +#define F_CPL_TLS_TX_SCMD_FMT_ENCDECCTRL V_CPL_TLS_TX_SCMD_FMT_ENCDECCTRL(1U) + +#define S_CPL_TLS_TX_SCMD_FMT_CIPHAUTHSEQCTRL 22 +#define M_CPL_TLS_TX_SCMD_FMT_CIPHAUTHSEQCTRL 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_CIPHAUTHSEQCTRL(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_CIPHAUTHSEQCTRL) +#define G_CPL_TLS_TX_SCMD_FMT_CIPHAUTHSEQCTRL(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_CIPHAUTHSEQCTRL) & \ + M_CPL_TLS_TX_SCMD_FMT_CIPHAUTHSEQCTRL) +#define F_CPL_TLS_TX_SCMD_FMT_CIPHAUTHSEQCTRL \ + V_CPL_TLS_TX_SCMD_FMT_CIPHAUTHSEQCTRL(1U) + +#define S_CPL_TLS_TX_SCMD_FMT_CIPHMODE 18 +#define M_CPL_TLS_TX_SCMD_FMT_CIPHMODE 0xf +#define V_CPL_TLS_TX_SCMD_FMT_CIPHMODE(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_CIPHMODE) +#define G_CPL_TLS_TX_SCMD_FMT_CIPHMODE(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_CIPHMODE) & M_CPL_TLS_TX_SCMD_FMT_CIPHMODE) + +#define S_CPL_TLS_TX_SCMD_FMT_AUTHMODE 14 +#define M_CPL_TLS_TX_SCMD_FMT_AUTHMODE 0xf +#define V_CPL_TLS_TX_SCMD_FMT_AUTHMODE(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_AUTHMODE) +#define G_CPL_TLS_TX_SCMD_FMT_AUTHMODE(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_AUTHMODE) & M_CPL_TLS_TX_SCMD_FMT_AUTHMODE) + +#define S_CPL_TLS_TX_SCMD_FMT_HMACCTRL 11 +#define M_CPL_TLS_TX_SCMD_FMT_HMACCTRL 0x7 +#define V_CPL_TLS_TX_SCMD_FMT_HMACCTRL(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_HMACCTRL) +#define G_CPL_TLS_TX_SCMD_FMT_HMACCTRL(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_HMACCTRL) & M_CPL_TLS_TX_SCMD_FMT_HMACCTRL) + +#define S_CPL_TLS_TX_SCMD_FMT_IVSIZE 7 +#define M_CPL_TLS_TX_SCMD_FMT_IVSIZE 0xf +#define V_CPL_TLS_TX_SCMD_FMT_IVSIZE(x) ((x) << S_CPL_TLS_TX_SCMD_FMT_IVSIZE) +#define G_CPL_TLS_TX_SCMD_FMT_IVSIZE(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_IVSIZE) & M_CPL_TLS_TX_SCMD_FMT_IVSIZE) + +#define S_CPL_TLS_TX_SCMD_FMT_NUMIVS 0 +#define M_CPL_TLS_TX_SCMD_FMT_NUMIVS 0x7f +#define V_CPL_TLS_TX_SCMD_FMT_NUMIVS(x) ((x) << S_CPL_TLS_TX_SCMD_FMT_NUMIVS) +#define G_CPL_TLS_TX_SCMD_FMT_NUMIVS(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_NUMIVS) & M_CPL_TLS_TX_SCMD_FMT_NUMIVS) + +#define S_CPL_TLS_TX_SCMD_FMT_ENBDBGID 31 +#define M_CPL_TLS_TX_SCMD_FMT_ENBDBGID 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_ENBDBGID(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_ENBDBGID) +#define G_CPL_TLS_TX_SCMD_FMT_ENBDBGID(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_ENBDBGID) & M_CPL_TLS_TX_SCMD_FMT_ENBDBGID) +#define F_CPL_TLS_TX_SCMD_FMT_ENBDBGID V_CPL_TLS_TX_SCMD_FMT_ENBDBGID(1U) + +#define S_CPL_TLS_TX_SCMD_FMT_IVGENCTRL 30 +#define M_CPL_TLS_TX_SCMD_FMT_IVGENCTRL 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_IVGENCTRL(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_IVGENCTRL) +#define G_CPL_TLS_TX_SCMD_FMT_IVGENCTRL(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_IVGENCTRL) & \ + M_CPL_TLS_TX_SCMD_FMT_IVGENCTRL) + +#define S_CPL_TLS_TX_SCMD_FMT_MOREFRAGS 20 +#define M_CPL_TLS_TX_SCMD_FMT_MOREFRAGS 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_MOREFRAGS(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_MOREFRAGS) +#define G_CPL_TLS_TX_SCMD_FMT_MOREFRAGS(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_MOREFRAGS) & \ + M_CPL_TLS_TX_SCMD_FMT_MOREFRAGS) +#define F_CPL_TLS_TX_SCMD_FMT_MOREFRAGS V_CPL_TLS_TX_SCMD_FMT_MOREFRAGS(1U) + +#define S_CPL_TLS_TX_SCMD_FMT_LASTFRAGS 19 +#define M_CPL_TLS_TX_SCMD_FMT_LASTFRAGS 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_LASTFRAGS(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_LASTFRAGS) +#define G_CPL_TLS_TX_SCMD_FMT_LASTFRAGS(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_LASTFRAGS) & \ + M_CPL_TLS_TX_SCMD_FMT_LASTFRAGS) +#define F_CPL_TLS_TX_SCMD_FMT_LASTFRAGS V_CPL_TLS_TX_SCMD_FMT_LASTFRAGS(1U) + +#define S_CPL_TLS_TX_SCMD_FMT_TLSCOMPPDU 18 +#define M_CPL_TLS_TX_SCMD_FMT_TLSCOMPPDU 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_TLSCOMPPDU(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_TLSCOMPPDU) +#define G_CPL_TLS_TX_SCMD_FMT_TLSCOMPPDU(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_TLSCOMPPDU) & \ + M_CPL_TLS_TX_SCMD_FMT_TLSCOMPPDU) +#define F_CPL_TLS_TX_SCMD_FMT_TLSCOMPPDU V_CPL_TLS_TX_SCMD_FMT_TLSCOMPPDU(1U) + +#define S_CPL_TLS_TX_SCMD_FMT_PAYLOADONLY 17 +#define M_CPL_TLS_TX_SCMD_FMT_PAYLOADONLY 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_PAYLOADONLY(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_PAYLOADONLY) +#define G_CPL_TLS_TX_SCMD_FMT_PAYLOADONLY(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_PAYLOADONLY) & \ + M_CPL_TLS_TX_SCMD_FMT_PAYLOADONLY) +#define F_CPL_TLS_TX_SCMD_FMT_PAYLOADONLY \ + V_CPL_TLS_TX_SCMD_FMT_PAYLOADONLY(1U) + +#define S_CPL_TLS_TX_SCMD_FMT_TLSFRAGENABLE 16 +#define M_CPL_TLS_TX_SCMD_FMT_TLSFRAGENABLE 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_TLSFRAGENABLE(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_TLSFRAGENABLE) +#define G_CPL_TLS_TX_SCMD_FMT_TLSFRAGENABLE(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_TLSFRAGENABLE) & \ + M_CPL_TLS_TX_SCMD_FMT_TLSFRAGENABLE) +#define F_CPL_TLS_TX_SCMD_FMT_TLSFRAGENABLE \ + V_CPL_TLS_TX_SCMD_FMT_TLSFRAGENABLE(1U) + +#define S_CPL_TLS_TX_SCMD_FMT_MACONLY 15 +#define M_CPL_TLS_TX_SCMD_FMT_MACONLY 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_MACONLY(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_MACONLY) +#define G_CPL_TLS_TX_SCMD_FMT_MACONLY(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_MACONLY) & M_CPL_TLS_TX_SCMD_FMT_MACONLY) +#define F_CPL_TLS_TX_SCMD_FMT_MACONLY V_CPL_TLS_TX_SCMD_FMT_MACONLY(1U) + +#define S_CPL_TLS_TX_SCMD_FMT_AADIVDROP 14 +#define M_CPL_TLS_TX_SCMD_FMT_AADIVDROP 0x1 +#define V_CPL_TLS_TX_SCMD_FMT_AADIVDROP(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_AADIVDROP) +#define G_CPL_TLS_TX_SCMD_FMT_AADIVDROP(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_AADIVDROP) & \ + M_CPL_TLS_TX_SCMD_FMT_AADIVDROP) +#define F_CPL_TLS_TX_SCMD_FMT_AADIVDROP V_CPL_TLS_TX_SCMD_FMT_AADIVDROP(1U) + +#define S_CPL_TLS_TX_SCMD_FMT_HDRLENGTH 0 +#define M_CPL_TLS_TX_SCMD_FMT_HDRLENGTH 0x3fff +#define V_CPL_TLS_TX_SCMD_FMT_HDRLENGTH(x) \ + ((x) << S_CPL_TLS_TX_SCMD_FMT_HDRLENGTH) +#define G_CPL_TLS_TX_SCMD_FMT_HDRLENGTH(x) \ + (((x) >> S_CPL_TLS_TX_SCMD_FMT_HDRLENGTH) & \ + M_CPL_TLS_TX_SCMD_FMT_HDRLENGTH) + struct cpl_rcb_upd { __be32 op_to_tid; __be32 opcode_psn; __u8 nodata_to_cnprepclr; - __u8 r0; + __u8 rsp_nak_seqclr_pkd; __be16 wrptr; __be32 length; }; @@ -6202,13 +6614,6 @@ struct cpl_roce_cqe { #define G_CPL_ROCE_CQE_QPID(x) \ (((x) >> S_CPL_ROCE_CQE_QPID) & M_CPL_ROCE_CQE_QPID) -#define S_CPL_ROCE_CQE_EXTMODE 11 -#define M_CPL_ROCE_CQE_EXTMODE 0x1 -#define V_CPL_ROCE_CQE_EXTMODE(x) ((x) << S_CPL_ROCE_CQE_EXTMODE) -#define G_CPL_ROCE_CQE_EXTMODE(x) \ - (((x) >> S_CPL_ROCE_CQE_EXTMODE) & M_CPL_ROCE_CQE_EXTMODE) -#define F_CPL_ROCE_CQE_EXTMODE V_CPL_ROCE_CQE_EXTMODE(1U) - #define S_CPL_ROCE_CQE_GENERATION_BIT 10 #define M_CPL_ROCE_CQE_GENERATION_BIT 0x1 #define V_CPL_ROCE_CQE_GENERATION_BIT(x) \ @@ -6249,6 +6654,13 @@ struct cpl_roce_cqe { #define G_CPL_ROCE_CQE_WR_TYPE_EXT(x) \ (((x) >> S_CPL_ROCE_CQE_WR_TYPE_EXT) & M_CPL_ROCE_CQE_WR_TYPE_EXT) +#define S_CPL_ROCE_CQE_EXTMODE 23 +#define M_CPL_ROCE_CQE_EXTMODE 0x1 +#define V_CPL_ROCE_CQE_EXTMODE(x) ((x) << S_CPL_ROCE_CQE_EXTMODE) +#define G_CPL_ROCE_CQE_EXTMODE(x) \ + (((x) >> S_CPL_ROCE_CQE_EXTMODE) & M_CPL_ROCE_CQE_EXTMODE) +#define F_CPL_ROCE_CQE_EXTMODE V_CPL_ROCE_CQE_EXTMODE(1U) + #define S_CPL_ROCE_CQE_SRQ 0 #define M_CPL_ROCE_CQE_SRQ 0xfff #define V_CPL_ROCE_CQE_SRQ(x) ((x) << S_CPL_ROCE_CQE_SRQ) @@ -6304,13 +6716,6 @@ struct cpl_roce_cqe_fw { #define G_CPL_ROCE_CQE_FW_QPID(x) \ (((x) >> S_CPL_ROCE_CQE_FW_QPID) & M_CPL_ROCE_CQE_FW_QPID) -#define S_CPL_ROCE_CQE_FW_EXTMODE 11 -#define M_CPL_ROCE_CQE_FW_EXTMODE 0x1 -#define V_CPL_ROCE_CQE_FW_EXTMODE(x) ((x) << S_CPL_ROCE_CQE_FW_EXTMODE) -#define G_CPL_ROCE_CQE_FW_EXTMODE(x) \ - (((x) >> S_CPL_ROCE_CQE_FW_EXTMODE) & M_CPL_ROCE_CQE_FW_EXTMODE) -#define F_CPL_ROCE_CQE_FW_EXTMODE V_CPL_ROCE_CQE_FW_EXTMODE(1U) - #define S_CPL_ROCE_CQE_FW_GENERATION_BIT 10 #define M_CPL_ROCE_CQE_FW_GENERATION_BIT 0x1 #define V_CPL_ROCE_CQE_FW_GENERATION_BIT(x) \ @@ -6353,6 +6758,14 @@ struct cpl_roce_cqe_fw { #define G_CPL_ROCE_CQE_FW_WR_TYPE_EXT(x) \ (((x) >> S_CPL_ROCE_CQE_FW_WR_TYPE_EXT) & M_CPL_ROCE_CQE_FW_WR_TYPE_EXT) +#define S_CPL_ROCE_CQE_FW_EXTMODE 23 +#define M_CPL_ROCE_CQE_FW_EXTMODE 0x1 +#define V_CPL_ROCE_CQE_FW_EXTMODE(x) ((x) << S_CPL_ROCE_CQE_FW_EXTMODE) +#define G_CPL_ROCE_CQE_FW_EXTMODE(x) \ + (((x) >> S_CPL_ROCE_CQE_FW_EXTMODE) & M_CPL_ROCE_CQE_FW_EXTMODE) +#define F_CPL_ROCE_CQE_FW_EXTMODE V_CPL_ROCE_CQE_FW_EXTMODE(1U) + + #define S_CPL_ROCE_CQE_FW_SRQ 0 #define M_CPL_ROCE_CQE_FW_SRQ 0xfff #define V_CPL_ROCE_CQE_FW_SRQ(x) ((x) << S_CPL_ROCE_CQE_FW_SRQ) @@ -6360,16 +6773,16 @@ struct cpl_roce_cqe_fw { (((x) >> S_CPL_ROCE_CQE_FW_SRQ) & M_CPL_ROCE_CQE_FW_SRQ) struct cpl_roce_cqe_err { - __be32 op_to_CQID; - __be32 Tid_FlitCnt; - __be32 QPID_to_WR_type; - __be32 Length; - __be32 TAG; - __be32 MSN; - __be32 SE_to_SRQ; - __be32 RQE; - __be32 ExtInfoMS[2]; - __be32 ExtInfoLS[2]; + __be32 op_to_cqid; + __be32 tid_flitcnt; + __be32 qpid_to_wr_type; + __be32 length; + __be32 tag; + __be32 msn; + __be32 se_to_srq; + __be32 rqe; + __be32 extinfoms[2]; + __be32 extinfols[2]; }; #define S_CPL_ROCE_CQE_ERR_OPCODE 24 @@ -6408,13 +6821,6 @@ struct cpl_roce_cqe_err { #define G_CPL_ROCE_CQE_ERR_QPID(x) \ (((x) >> S_CPL_ROCE_CQE_ERR_QPID) & M_CPL_ROCE_CQE_ERR_QPID) -#define S_CPL_ROCE_CQE_ERR_EXTMODE 11 -#define M_CPL_ROCE_CQE_ERR_EXTMODE 0x1 -#define V_CPL_ROCE_CQE_ERR_EXTMODE(x) ((x) << S_CPL_ROCE_CQE_ERR_EXTMODE) -#define G_CPL_ROCE_CQE_ERR_EXTMODE(x) \ - (((x) >> S_CPL_ROCE_CQE_ERR_EXTMODE) & M_CPL_ROCE_CQE_ERR_EXTMODE) -#define F_CPL_ROCE_CQE_ERR_EXTMODE V_CPL_ROCE_CQE_ERR_EXTMODE(1U) - #define S_CPL_ROCE_CQE_ERR_GENERATION_BIT 10 #define M_CPL_ROCE_CQE_ERR_GENERATION_BIT 0x1 #define V_CPL_ROCE_CQE_ERR_GENERATION_BIT(x) \ @@ -6458,6 +6864,14 @@ struct cpl_roce_cqe_err { #define G_CPL_ROCE_CQE_ERR_WR_TYPE_EXT(x) \ (((x) >> S_CPL_ROCE_CQE_ERR_WR_TYPE_EXT) & M_CPL_ROCE_CQE_ERR_WR_TYPE_EXT) +#define S_CPL_ROCE_CQE_ERR_EXTMODE 23 +#define M_CPL_ROCE_CQE_ERR_EXTMODE 0x1 +#define V_CPL_ROCE_CQE_ERR_EXTMODE(x) ((x) << S_CPL_ROCE_CQE_ERR_EXTMODE) +#define G_CPL_ROCE_CQE_ERR_EXTMODE(x) \ + (((x) >> S_CPL_ROCE_CQE_ERR_EXTMODE) & M_CPL_ROCE_CQE_ERR_EXTMODE) +#define F_CPL_ROCE_CQE_ERR_EXTMODE V_CPL_ROCE_CQE_ERR_EXTMODE(1U) + + #define S_CPL_ROCE_CQE_ERR_SRQ 0 #define M_CPL_ROCE_CQE_ERR_SRQ 0xfff #define V_CPL_ROCE_CQE_ERR_SRQ(x) ((x) << S_CPL_ROCE_CQE_ERR_SRQ) diff --git a/sys/dev/cxgbe/common/t4_regs.h b/sys/dev/cxgbe/common/t4_regs.h index 8f500ec0fbdd..51f150443261 100644 --- a/sys/dev/cxgbe/common/t4_regs.h +++ b/sys/dev/cxgbe/common/t4_regs.h @@ -27,11 +27,11 @@ */ /* This file is automatically generated --- changes will be lost */ -/* Generation Date : Thu Sep 11 05:25:56 PM IST 2025 */ +/* Generation Date : Tue Oct 28 05:23:45 PM IST 2025 */ /* Directory name: t4_reg.txt, Date: Not specified */ /* Directory name: t5_reg.txt, Changeset: 6945:54ba4ba7ee8b */ /* Directory name: t6_reg.txt, Changeset: 4277:9c165d0f4899 */ -/* Directory name: t7_reg.txt, Changeset: 5945:1487219ecb20 */ +/* Directory name: t7_sw_reg.txt, Changeset: 5946:0b60ff298e7d */ #define MYPF_BASE 0x1b000 #define MYPF_REG(reg_addr) (MYPF_BASE + (reg_addr)) @@ -44006,10 +44006,57 @@ #define V_MPS2CRYPTO_RX_INTF_FIFO(x) ((x) << S_MPS2CRYPTO_RX_INTF_FIFO) #define G_MPS2CRYPTO_RX_INTF_FIFO(x) (((x) >> S_MPS2CRYPTO_RX_INTF_FIFO) & M_MPS2CRYPTO_RX_INTF_FIFO) -#define S_RX_PRE_PROC_PERR 9 -#define M_RX_PRE_PROC_PERR 0x7ffU -#define V_RX_PRE_PROC_PERR(x) ((x) << S_RX_PRE_PROC_PERR) -#define G_RX_PRE_PROC_PERR(x) (((x) >> S_RX_PRE_PROC_PERR) & M_RX_PRE_PROC_PERR) +#define S_MAC_RX_PPROC_MPS2TP_TF 19 +#define V_MAC_RX_PPROC_MPS2TP_TF(x) ((x) << S_MAC_RX_PPROC_MPS2TP_TF) +#define F_MAC_RX_PPROC_MPS2TP_TF V_MAC_RX_PPROC_MPS2TP_TF(1U) + +#define S_MAC_RX_PPROC_LB_CH3 18 +#define V_MAC_RX_PPROC_LB_CH3(x) ((x) << S_MAC_RX_PPROC_LB_CH3) +#define F_MAC_RX_PPROC_LB_CH3 V_MAC_RX_PPROC_LB_CH3(1U) + +#define S_MAC_RX_PPROC_LB_CH2 17 +#define V_MAC_RX_PPROC_LB_CH2(x) ((x) << S_MAC_RX_PPROC_LB_CH2) +#define F_MAC_RX_PPROC_LB_CH2 V_MAC_RX_PPROC_LB_CH2(1U) + +#define S_MAC_RX_PPROC_LB_CH1 16 +#define V_MAC_RX_PPROC_LB_CH1(x) ((x) << S_MAC_RX_PPROC_LB_CH1) +#define F_MAC_RX_PPROC_LB_CH1 V_MAC_RX_PPROC_LB_CH1(1U) + +#define S_MAC_RX_PPROC_LB_CH0 15 +#define V_MAC_RX_PPROC_LB_CH0(x) ((x) << S_MAC_RX_PPROC_LB_CH0) +#define F_MAC_RX_PPROC_LB_CH0 V_MAC_RX_PPROC_LB_CH0(1U) + +#define S_MAC_RX_PPROC_DWRR_CH0_3 14 +#define V_MAC_RX_PPROC_DWRR_CH0_3(x) ((x) << S_MAC_RX_PPROC_DWRR_CH0_3) +#define F_MAC_RX_PPROC_DWRR_CH0_3 V_MAC_RX_PPROC_DWRR_CH0_3(1U) + +#define S_MAC_RX_FIFO_PERR 13 +#define V_MAC_RX_FIFO_PERR(x) ((x) << S_MAC_RX_FIFO_PERR) +#define F_MAC_RX_FIFO_PERR V_MAC_RX_FIFO_PERR(1U) + +#define S_MAC2MPS_PT3_PERR 12 +#define V_MAC2MPS_PT3_PERR(x) ((x) << S_MAC2MPS_PT3_PERR) +#define F_MAC2MPS_PT3_PERR V_MAC2MPS_PT3_PERR(1U) + +#define S_MAC2MPS_PT2_PERR 11 +#define V_MAC2MPS_PT2_PERR(x) ((x) << S_MAC2MPS_PT2_PERR) +#define F_MAC2MPS_PT2_PERR V_MAC2MPS_PT2_PERR(1U) + +#define S_MAC2MPS_PT1_PERR 10 +#define V_MAC2MPS_PT1_PERR(x) ((x) << S_MAC2MPS_PT1_PERR) +#define F_MAC2MPS_PT1_PERR V_MAC2MPS_PT1_PERR(1U) + +#define S_MAC2MPS_PT0_PERR 9 +#define V_MAC2MPS_PT0_PERR(x) ((x) << S_MAC2MPS_PT0_PERR) +#define F_MAC2MPS_PT0_PERR V_MAC2MPS_PT0_PERR(1U) + +#define S_LPBK_FIFO_PERR 8 +#define V_LPBK_FIFO_PERR(x) ((x) << S_LPBK_FIFO_PERR) +#define F_LPBK_FIFO_PERR V_LPBK_FIFO_PERR(1U) + +#define S_TP2MPS_TF_FIFO_PERR 7 +#define V_TP2MPS_TF_FIFO_PERR(x) ((x) << S_TP2MPS_TF_FIFO_PERR) +#define F_TP2MPS_TF_FIFO_PERR V_TP2MPS_TF_FIFO_PERR(1U) #define A_MPS_RX_PAUSE_GEN_TH_1 0x11090 #define A_MPS_RX_PERR_INT_ENABLE2 0x11090 @@ -78258,6 +78305,26 @@ #define G_RX_CDR_LANE_SEL(x) (((x) >> S_RX_CDR_LANE_SEL) & M_RX_CDR_LANE_SEL) #define A_MAC_DEBUG_PL_IF_1 0x381c4 +#define A_MAC_HSS0_ANALOG_TEST_CTRL 0x381d0 + +#define S_WP_PMT_IN_I 0 +#define M_WP_PMT_IN_I 0xfU +#define V_WP_PMT_IN_I(x) ((x) << S_WP_PMT_IN_I) +#define G_WP_PMT_IN_I(x) (((x) >> S_WP_PMT_IN_I) & M_WP_PMT_IN_I) + +#define A_MAC_HSS1_ANALOG_TEST_CTRL 0x381d4 +#define A_MAC_HSS2_ANALOG_TEST_CTRL 0x381d8 +#define A_MAC_HSS3_ANALOG_TEST_CTRL 0x381dc +#define A_MAC_HSS0_ANALOG_TEST_STATUS 0x381e0 + +#define S_WP_PMT_OUT_O 0 +#define M_WP_PMT_OUT_O 0xfU +#define V_WP_PMT_OUT_O(x) ((x) << S_WP_PMT_OUT_O) +#define G_WP_PMT_OUT_O(x) (((x) >> S_WP_PMT_OUT_O) & M_WP_PMT_OUT_O) + +#define A_MAC_HSS1_ANALOG_TEST_STATUS 0x381e4 +#define A_MAC_HSS2_ANALOG_TEST_STATUS 0x381e8 +#define A_MAC_HSS3_ANALOG_TEST_STATUS 0x381ec #define A_MAC_SIGNAL_DETECT_CTRL 0x381f0 #define S_SIGNAL_DET_LN7 15 @@ -80933,6 +81000,27 @@ #define F_Q1_LOS_0_ASSERT V_Q1_LOS_0_ASSERT(1U) #define A_MAC_IOS_INTR_CAUSE_QUAD1 0x3a09c +#define A_MAC_HSS0_PMD_RECEIVE_SIGNAL_DETECT 0x3a93c + +#define S_PMD_RECEIVE_SIGNAL_DETECT_1N3 4 +#define V_PMD_RECEIVE_SIGNAL_DETECT_1N3(x) ((x) << S_PMD_RECEIVE_SIGNAL_DETECT_1N3) +#define F_PMD_RECEIVE_SIGNAL_DETECT_1N3 V_PMD_RECEIVE_SIGNAL_DETECT_1N3(1U) + +#define S_PMD_RECEIVE_SIGNAL_DETECT_1N2 3 +#define V_PMD_RECEIVE_SIGNAL_DETECT_1N2(x) ((x) << S_PMD_RECEIVE_SIGNAL_DETECT_1N2) +#define F_PMD_RECEIVE_SIGNAL_DETECT_1N2 V_PMD_RECEIVE_SIGNAL_DETECT_1N2(1U) + +#define S_PMD_RECEIVE_SIGNAL_DETECT_LN1 2 +#define V_PMD_RECEIVE_SIGNAL_DETECT_LN1(x) ((x) << S_PMD_RECEIVE_SIGNAL_DETECT_LN1) +#define F_PMD_RECEIVE_SIGNAL_DETECT_LN1 V_PMD_RECEIVE_SIGNAL_DETECT_LN1(1U) + +#define S_PMD_RECEIVE_SIGNAL_DETECT_1N0 1 +#define V_PMD_RECEIVE_SIGNAL_DETECT_1N0(x) ((x) << S_PMD_RECEIVE_SIGNAL_DETECT_1N0) +#define F_PMD_RECEIVE_SIGNAL_DETECT_1N0 V_PMD_RECEIVE_SIGNAL_DETECT_1N0(1U) + +#define A_MAC_HSS1_PMD_RECEIVE_SIGNAL_DETECT 0x3b93c +#define A_MAC_HSS2_PMD_RECEIVE_SIGNAL_DETECT 0x3c93c +#define A_MAC_HSS3_PMD_RECEIVE_SIGNAL_DETECT 0x3d93c #define A_MAC_MTIP_PCS_1G_0_CONTROL 0x3e000 #define S_SPEED_SEL_1 13 diff --git a/sys/dev/cxgbe/crypto/t7_kern_tls.c b/sys/dev/cxgbe/crypto/t7_kern_tls.c index 217459126361..d9710b5bd13f 100644 --- a/sys/dev/cxgbe/crypto/t7_kern_tls.c +++ b/sys/dev/cxgbe/crypto/t7_kern_tls.c @@ -141,7 +141,8 @@ alloc_tlspcb(struct ifnet *ifp, struct vi_info *vi, int flags) tlsp->tx_key_addr = -1; tlsp->ghash_offset = -1; tlsp->rx_chid = pi->rx_chan; - tlsp->rx_qid = sc->sge.rxq[pi->vi->first_rxq].iq.abs_id; + tlsp->rx_qid = -1; + tlsp->txq = NULL; mbufq_init(&tlsp->pending_mbufs, INT_MAX); return (tlsp); @@ -157,7 +158,8 @@ t7_tls_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params, struct vi_info *vi; struct inpcb *inp; struct sge_txq *txq; - int error, iv_size, keyid, mac_first; + int error, iv_size, keyid, mac_first, qidx; + uint32_t flowid; tls = params->tls.tls; @@ -250,11 +252,15 @@ t7_tls_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params, goto failed; } - txq = &sc->sge.txq[vi->first_txq]; if (inp->inp_flowtype != M_HASHTYPE_NONE) - txq += ((inp->inp_flowid % (vi->ntxq - vi->rsrv_noflowq)) + - vi->rsrv_noflowq); - tlsp->txq = txq; + flowid = inp->inp_flowid; + else + flowid = arc4random(); + qidx = flowid % vi->nrxq + vi->first_rxq; + tlsp->rx_qid = sc->sge.rxq[qidx].iq.abs_id; + qidx = (flowid % (vi->ntxq - vi->rsrv_noflowq)) + vi->rsrv_noflowq + + vi->first_txq; + tlsp->txq = txq = &sc->sge.txq[qidx]; INP_RUNLOCK(inp); error = ktls_setup_keys(tlsp, tls, txq); diff --git a/sys/dev/cxgbe/firmware/t4fw_interface.h b/sys/dev/cxgbe/firmware/t4fw_interface.h index 5874f0343b03..b11552dce021 100644 --- a/sys/dev/cxgbe/firmware/t4fw_interface.h +++ b/sys/dev/cxgbe/firmware/t4fw_interface.h @@ -8967,9 +8967,10 @@ enum fw_port_type { FW_PORT_TYPE_SFP28 = 20, /* No, 1, 25G/10G/1G */ FW_PORT_TYPE_KR_SFP28 = 21, /* No, 1, 25G/10G/1G using Backplane */ FW_PORT_TYPE_KR_XLAUI = 22, /* No, 4, 40G/10G/1G, No AN*/ - FW_PORT_TYPE_SFP56 = 26, - FW_PORT_TYPE_QSFP56 = 27, - FW_PORT_TYPE_NONE = M_FW_PORT_CMD_PTYPE + FW_PORT_TYPE_SFP56 = 26, /* No, 1, 50G/25G */ + FW_PORT_TYPE_QSFP56 = 27, /* No, 4, 200G/100G/50G/25G */ + FW_PORT_TYPE_QSFPDD = 34, /* No, 8, 400G/200G/100G/50G */ + FW_PORT_TYPE_NONE = M_FW_PORT_CMD_PORTTYPE32 }; static inline bool diff --git a/sys/dev/cxgbe/nvmf/nvmf_che.c b/sys/dev/cxgbe/nvmf/nvmf_che.c new file mode 100644 index 000000000000..5c2174b8a40b --- /dev/null +++ b/sys/dev/cxgbe/nvmf/nvmf_che.c @@ -0,0 +1,3331 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Chelsio Communications, Inc. + * Written by: John Baldwin <jhb@FreeBSD.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "opt_inet.h" + +#include <sys/param.h> +#include <sys/libkern.h> +#include <sys/kernel.h> +#include <sys/module.h> + +#ifdef TCP_OFFLOAD +#include <sys/bitset.h> +#include <sys/capsicum.h> +#include <sys/file.h> +#include <sys/kthread.h> +#include <sys/ktr.h> +#include <sys/malloc.h> +#include <sys/mbuf.h> +#include <sys/nv.h> +#include <sys/protosw.h> +#include <sys/socket.h> +#include <sys/socketvar.h> +#include <netinet/in.h> +#include <netinet/in_pcb.h> +#include <netinet/tcp_var.h> +#include <netinet/toecore.h> + +#include <dev/nvmf/nvmf.h> +#include <dev/nvmf/nvmf_proto.h> +#include <dev/nvmf/nvmf_tcp.h> +#include <dev/nvmf/nvmf_transport.h> +#include <dev/nvmf/nvmf_transport_internal.h> + +#include <vm/pmap.h> +#include <vm/vm_page.h> + +#include "common/common.h" +#include "common/t4_regs.h" +#include "common/t4_tcb.h" +#include "tom/t4_tom.h" + +/* Status code values in CPL_NVMT_CMP. */ +#define CMP_STATUS_ERROR_MASK 0x7f +#define CMP_STATUS_NO_ERROR 0 +#define CMP_STATUS_HEADER_DIGEST 1 +#define CMP_STATUS_DIRECTION_MISMATCH 2 +#define CMP_STATUS_DIGEST_FLAG_MISMATCH 3 +#define CMP_STATUS_SUCCESS_NOT_LAST 4 +#define CMP_STATUS_BAD_DATA_LENGTH 5 +#define CMP_STATUS_USER_MODE_UNALLOCATED 6 +#define CMP_STATUS_RQT_LIMIT 7 +#define CMP_STATUS_RQT_WRAP 8 +#define CMP_STATUS_RQT_BOUND 9 +#define CMP_STATUS_TPT_LIMIT 16 +#define CMP_STATUS_TPT_INVALID 17 +#define CMP_STATUS_TPT_COLOUR_MISMATCH 18 +#define CMP_STATUS_TPT_MISC 19 +#define CMP_STATUS_TPT_WRAP 20 +#define CMP_STATUS_TPT_BOUND 21 +#define CMP_STATUS_TPT_LAST_PDU_UNALIGNED 22 +#define CMP_STATUS_PBL_LIMIT 24 +#define CMP_STATUS_DATA_DIGEST 25 +#define CMP_STATUS_DDP 0x80 + +/* + * Transfer tags and CIDs with the MSB set are "unallocated" tags that + * pass data through to the freelist without using DDP. + */ +#define CHE_FL_TAG_MASK 0x8000 +#define CHE_MAX_FL_TAG 0x7fff +#define CHE_NUM_FL_TAGS (CHE_MAX_FL_TAG + 1) + +#define CHE_TAG_IS_FL(ttag) (((ttag) & CHE_FL_TAG_MASK) == CHE_FL_TAG_MASK) +#define CHE_RAW_FL_TAG(ttag) ((ttag) & ~CHE_FL_TAG_MASK) +#define CHE_DDP_TAG(stag_idx, color) ((stag_idx) << 4 | (color)) +#define CHE_STAG_COLOR(stag) ((stag) & 0xf) +#define CHE_STAG_IDX(stag) ((stag) >> 4) +#define CHE_DDP_MAX_COLOR 0xf + +#define CHE_DDP_NO_TAG 0xffff + +/* + * A bitmap of non-DDP CIDs in use on the host. Since there is no + * _BIT_FFC (find first clear), the bitset is inverted so that a clear + * bit indicates an in-use CID. + */ +BITSET_DEFINE(fl_cid_set, CHE_NUM_FL_TAGS); +#define FL_CID_INIT(p) __BIT_FILL(CHE_NUM_FL_TAGS, p) +#define FL_CID_BUSY(n, p) __BIT_CLR(CHE_NUM_FL_TAGS, n, p) +#define FL_CID_ISACTIVE(n, p) !__BIT_ISSET(CHE_NUM_FL_TAGS, n, p) +#define FL_CID_FREE(n, p) __BIT_SET(CHE_NUM_FL_TAGS, n, p) +#define FL_CID_FINDFREE_AT(p, start) __BIT_FFS_AT(CHE_NUM_FL_TAGS, p, start) + +/* + * The TCP sequence number of both CPL_NVMT_DATA and CPL_NVMT_CMP + * mbufs are saved here while the mbuf is in qp->rx_data and qp->rx_pdus. + */ +#define nvmf_tcp_seq PH_loc.thirtytwo[0] + +/* + * The CPL status of CPL_NVMT_CMP mbufs are saved here while the mbuf + * is in qp->rx_pdus. + */ +#define nvmf_cpl_status PH_loc.eight[4] + +struct nvmf_che_capsule; +struct nvmf_che_qpair; + +struct nvmf_che_adapter { + struct adapter *sc; + + u_int ddp_threshold; + u_int max_transmit_pdu; + u_int max_receive_pdu; + bool nvmt_data_iqe; + + struct sysctl_ctx_list ctx; /* from uld_activate to deactivate */ +}; + +struct nvmf_che_command_buffer { + struct nvmf_che_qpair *qp; + + struct nvmf_io_request io; + size_t data_len; + size_t data_xfered; + uint32_t data_offset; + + u_int refs; + int error; + + bool ddp_ok; + uint16_t cid; + uint16_t ttag; + uint16_t original_cid; /* Host only */ + + TAILQ_ENTRY(nvmf_che_command_buffer) link; + + /* Fields used for DDP. */ + struct fw_ri_tpte tpte; + uint64_t *pbl; + uint32_t pbl_addr; + uint32_t pbl_len; + + /* Controller only */ + struct nvmf_che_capsule *cc; +}; + +struct nvmf_che_command_buffer_list { + TAILQ_HEAD(, nvmf_che_command_buffer) head; + struct mtx lock; +}; + +struct nvmf_che_qpair { + struct nvmf_qpair qp; + + struct socket *so; + struct toepcb *toep; + struct nvmf_che_adapter *nca; + + volatile u_int refs; /* Every allocated capsule holds a reference */ + uint8_t txpda; + uint8_t rxpda; + bool header_digests; + bool data_digests; + uint32_t maxr2t; + uint32_t maxh2cdata; /* Controller only */ + uint32_t max_rx_data; + uint32_t max_tx_data; + uint32_t max_icd; /* Host only */ + uint32_t max_ioccsz; /* Controller only */ + union { + uint16_t next_fl_ttag; /* Controller only */ + uint16_t next_cid; /* Host only */ + }; + uint16_t next_ddp_tag; + u_int num_fl_ttags; /* Controller only */ + u_int active_fl_ttags; /* Controller only */ + u_int num_ddp_tags; + u_int active_ddp_tags; + bool send_success; /* Controller only */ + uint8_t ddp_color; + uint32_t tpt_offset; + + /* Receive state. */ + struct thread *rx_thread; + struct cv rx_cv; + bool rx_shutdown; + int rx_error; + struct mbufq rx_data; /* Data received via CPL_NVMT_DATA. */ + struct mbufq rx_pdus; /* PDU headers received via CPL_NVMT_CMP. */ + + /* Transmit state. */ + struct thread *tx_thread; + struct cv tx_cv; + bool tx_shutdown; + STAILQ_HEAD(, nvmf_che_capsule) tx_capsules; + + struct nvmf_che_command_buffer_list tx_buffers; + struct nvmf_che_command_buffer_list rx_buffers; + + /* + * For the controller, an RX command buffer can be in one of + * three locations, all protected by the rx_buffers.lock. If + * a receive request is waiting for either an R2T slot for its + * command (due to exceeding MAXR2T), or a transfer tag it is + * placed on the rx_buffers list. When a request is allocated + * an active transfer tag, it moves to either the + * open_ddp_tags[] or open_fl_ttags[] array (indexed by the + * tag) until it completes. + * + * For the host, an RX command buffer using DDP is in + * open_ddp_tags[], otherwise it is in rx_buffers. + */ + struct nvmf_che_command_buffer **open_ddp_tags; + struct nvmf_che_command_buffer **open_fl_ttags; /* Controller only */ + + /* + * For the host, CIDs submitted by nvmf(4) must be rewritten + * to either use DDP or not use DDP. The CID in response + * capsules must be restored to their original value. For + * DDP, the original CID is stored in the command buffer. + * These variables manage non-DDP CIDs. + */ + uint16_t *fl_cids; /* Host only */ + struct fl_cid_set *fl_cid_set; /* Host only */ + struct mtx fl_cid_lock; /* Host only */ +}; + +struct nvmf_che_rxpdu { + struct mbuf *m; + const struct nvme_tcp_common_pdu_hdr *hdr; + uint32_t data_len; + bool data_digest_mismatch; + bool ddp; +}; + +struct nvmf_che_capsule { + struct nvmf_capsule nc; + + volatile u_int refs; + + struct nvmf_che_rxpdu rx_pdu; + + uint32_t active_r2ts; /* Controller only */ +#ifdef INVARIANTS + uint32_t tx_data_offset; /* Controller only */ + u_int pending_r2ts; /* Controller only */ +#endif + + STAILQ_ENTRY(nvmf_che_capsule) link; +}; + +#define CCAP(nc) ((struct nvmf_che_capsule *)(nc)) +#define CQP(qp) ((struct nvmf_che_qpair *)(qp)) + +static void che_release_capsule(struct nvmf_che_capsule *cc); +static void che_free_qpair(struct nvmf_qpair *nq); + +SYSCTL_NODE(_kern_nvmf, OID_AUTO, che, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, + "Chelsio TCP offload transport"); + +static u_int che_max_transmit_pdu = 32 * 1024; +SYSCTL_UINT(_kern_nvmf_che, OID_AUTO, max_transmit_pdu, CTLFLAG_RWTUN, + &che_max_transmit_pdu, 0, + "Maximum size of a transmitted PDU"); + +static u_int che_max_receive_pdu = 32 * 1024; +SYSCTL_UINT(_kern_nvmf_che, OID_AUTO, max_receive_pdu, CTLFLAG_RWTUN, + &che_max_receive_pdu, 0, + "Maximum size of a received PDU"); + +static int use_dsgl = 1; +SYSCTL_INT(_kern_nvmf_che, OID_AUTO, use_dsgl, CTLFLAG_RWTUN, &use_dsgl, 0, + "Use DSGL for PBL/FastReg (default=1)"); + +static int inline_threshold = 256; +SYSCTL_INT(_kern_nvmf_che, OID_AUTO, inline_threshold, CTLFLAG_RWTUN, + &inline_threshold, 0, + "inline vs dsgl threshold (default=256)"); + +static int ddp_tags_per_qp = 128; +SYSCTL_INT(_kern_nvmf_che, OID_AUTO, ddp_tags_per_qp, CTLFLAG_RWTUN, + &ddp_tags_per_qp, 0, + "Number of DDP tags to reserve for each queue pair"); + +static MALLOC_DEFINE(M_NVMF_CHE, "nvmf_che", "Chelsio NVMe-TCP offload"); + +/* + * PBL regions consist of N full-sized pages. TPT entries support an + * initial offset into the first page (FBO) and can handle a partial + * length on the last page. + */ +static bool +che_ddp_io_check(struct nvmf_che_qpair *qp, const struct nvmf_io_request *io) +{ + const struct memdesc *mem = &io->io_mem; + struct bus_dma_segment *ds; + int i; + + if (io->io_len < qp->nca->ddp_threshold) { + return (false); + } + + switch (mem->md_type) { + case MEMDESC_VADDR: + case MEMDESC_PADDR: + case MEMDESC_VMPAGES: + return (true); + case MEMDESC_VLIST: + case MEMDESC_PLIST: + /* + * Require all but the first segment to start on a + * page boundary. Require all but the last segment to + * end on a page boundary. + */ + ds = mem->u.md_list; + for (i = 0; i < mem->md_nseg; i++, ds++) { + if (i != 0 && ds->ds_addr % PAGE_SIZE != 0) + return (false); + if (i != mem->md_nseg - 1 && + (ds->ds_addr + ds->ds_len) % PAGE_SIZE != 0) + return (false); + } + return (true); + default: + /* + * Other types could be validated with more work, but + * they aren't used currently by nvmf(4) or nvmft(4). + */ + return (false); + } +} + +static u_int +che_fbo(struct nvmf_che_command_buffer *cb) +{ + struct memdesc *mem = &cb->io.io_mem; + + switch (mem->md_type) { + case MEMDESC_VADDR: + return ((uintptr_t)mem->u.md_vaddr & PAGE_MASK); + case MEMDESC_PADDR: + return (mem->u.md_paddr & PAGE_MASK); + case MEMDESC_VMPAGES: + return (mem->md_offset); + case MEMDESC_VLIST: + case MEMDESC_PLIST: + return (mem->u.md_list[0].ds_addr & PAGE_MASK); + default: + __assert_unreachable(); + } +} + +static u_int +che_npages(struct nvmf_che_command_buffer *cb) +{ + return (howmany(che_fbo(cb) + cb->io.io_len, PAGE_SIZE)); +} + +static struct nvmf_che_command_buffer * +che_alloc_command_buffer(struct nvmf_che_qpair *qp, + const struct nvmf_io_request *io, uint32_t data_offset, size_t data_len, + uint16_t cid) +{ + struct nvmf_che_command_buffer *cb; + + cb = malloc(sizeof(*cb), M_NVMF_CHE, M_WAITOK); + cb->qp = qp; + cb->io = *io; + cb->data_offset = data_offset; + cb->data_len = data_len; + cb->data_xfered = 0; + refcount_init(&cb->refs, 1); + cb->error = 0; + cb->ddp_ok = che_ddp_io_check(qp, io); + cb->cid = cid; + cb->ttag = 0; + cb->original_cid = 0; + cb->cc = NULL; + cb->pbl = NULL; + + return (cb); +} + +static void +che_hold_command_buffer(struct nvmf_che_command_buffer *cb) +{ + refcount_acquire(&cb->refs); +} + +static void +che_free_command_buffer(struct nvmf_che_command_buffer *cb) +{ + nvmf_complete_io_request(&cb->io, cb->data_xfered, cb->error); + if (cb->cc != NULL) + che_release_capsule(cb->cc); + MPASS(cb->pbl == NULL); + free(cb, M_NVMF_CHE); +} + +static void +che_release_command_buffer(struct nvmf_che_command_buffer *cb) +{ + if (refcount_release(&cb->refs)) + che_free_command_buffer(cb); +} + +static void +che_add_command_buffer(struct nvmf_che_command_buffer_list *list, + struct nvmf_che_command_buffer *cb) +{ + mtx_assert(&list->lock, MA_OWNED); + TAILQ_INSERT_HEAD(&list->head, cb, link); +} + +static struct nvmf_che_command_buffer * +che_find_command_buffer(struct nvmf_che_command_buffer_list *list, + uint16_t cid) +{ + struct nvmf_che_command_buffer *cb; + + mtx_assert(&list->lock, MA_OWNED); + TAILQ_FOREACH(cb, &list->head, link) { + if (cb->cid == cid) + return (cb); + } + return (NULL); +} + +static void +che_remove_command_buffer(struct nvmf_che_command_buffer_list *list, + struct nvmf_che_command_buffer *cb) +{ + mtx_assert(&list->lock, MA_OWNED); + TAILQ_REMOVE(&list->head, cb, link); +} + +static void +che_purge_command_buffer(struct nvmf_che_command_buffer_list *list, + uint16_t cid) +{ + struct nvmf_che_command_buffer *cb; + + mtx_lock(&list->lock); + cb = che_find_command_buffer(list, cid); + if (cb != NULL) { + che_remove_command_buffer(list, cb); + mtx_unlock(&list->lock); + che_release_command_buffer(cb); + } else + mtx_unlock(&list->lock); +} + +static int +che_write_mem_inline(struct adapter *sc, struct toepcb *toep, uint32_t addr, + uint32_t len, void *data, struct mbufq *wrq) +{ + struct mbuf *m; + char *cp; + int copy_len, i, num_wqe, wr_len; + +#ifdef VERBOSE_TRACES + CTR(KTR_CXGBE, "%s: addr 0x%x len %u", __func__, addr << 5, len); +#endif + num_wqe = DIV_ROUND_UP(len, T4_MAX_INLINE_SIZE); + cp = data; + for (i = 0; i < num_wqe; i++) { + copy_len = min(len, T4_MAX_INLINE_SIZE); + wr_len = T4_WRITE_MEM_INLINE_LEN(copy_len); + + m = alloc_raw_wr_mbuf(wr_len); + if (m == NULL) + return (ENOMEM); + t4_write_mem_inline_wr(sc, mtod(m, void *), wr_len, toep->tid, + addr, copy_len, cp, 0); + if (cp != NULL) + cp += T4_MAX_INLINE_SIZE; + addr += T4_MAX_INLINE_SIZE >> 5; + len -= T4_MAX_INLINE_SIZE; + + mbufq_enqueue(wrq, m); + } + return (0); +} + +static int +che_write_mem_dma_aligned(struct adapter *sc, struct toepcb *toep, + uint32_t addr, uint32_t len, void *data, struct mbufq *wrq) +{ + struct mbuf *m; + vm_offset_t va; + u_int todo; + int wr_len; + + /* First page. */ + va = (vm_offset_t)data; + todo = min(PAGE_SIZE - (va % PAGE_SIZE), len); + wr_len = T4_WRITE_MEM_DMA_LEN; + m = alloc_raw_wr_mbuf(wr_len); + if (m == NULL) + return (ENOMEM); + t4_write_mem_dma_wr(sc, mtod(m, void *), wr_len, toep->tid, addr, + todo, pmap_kextract(va), 0); + mbufq_enqueue(wrq, m); + len -= todo; + addr += todo >> 5; + va += todo; + + while (len > 0) { + MPASS(va == trunc_page(va)); + todo = min(PAGE_SIZE, len); + m = alloc_raw_wr_mbuf(wr_len); + if (m == NULL) + return (ENOMEM); + t4_write_mem_dma_wr(sc, mtod(m, void *), wr_len, toep->tid, + addr, todo, pmap_kextract(va), 0); + mbufq_enqueue(wrq, m); + len -= todo; + addr += todo >> 5; + va += todo; + } + return (0); +} + +static int +che_write_adapter_mem(struct nvmf_che_qpair *qp, uint32_t addr, uint32_t len, + void *data) +{ + struct adapter *sc = qp->nca->sc; + struct toepcb *toep = qp->toep; + struct socket *so = qp->so; + struct inpcb *inp = sotoinpcb(so); + struct mbufq mq; + int error; + + mbufq_init(&mq, INT_MAX); + if (!use_dsgl || len < inline_threshold || data == NULL) + error = che_write_mem_inline(sc, toep, addr, len, data, &mq); + else + error = che_write_mem_dma_aligned(sc, toep, addr, len, data, + &mq); + if (__predict_false(error != 0)) + goto error; + + INP_WLOCK(inp); + if ((inp->inp_flags & INP_DROPPED) != 0) { + INP_WUNLOCK(inp); + error = ECONNRESET; + goto error; + } + mbufq_concat(&toep->ulp_pduq, &mq); + INP_WUNLOCK(inp); + return (0); + +error: + mbufq_drain(&mq); + return (error); +} + +static bool +che_alloc_pbl(struct nvmf_che_qpair *qp, struct nvmf_che_command_buffer *cb) +{ + struct adapter *sc = qp->nca->sc; + struct memdesc *mem = &cb->io.io_mem; + uint64_t *pbl; + uint32_t addr, len; + u_int i, npages; + int error; + + MPASS(cb->pbl == NULL); + MPASS(cb->ddp_ok); + + /* Hardware limit? iWARP only enforces this for T5. */ + if (cb->io.io_len >= (8 * 1024 * 1024 * 1024ULL)) + return (false); + + npages = che_npages(cb); + len = roundup2(npages, 4) * sizeof(*cb->pbl); + addr = t4_pblpool_alloc(sc, len); + if (addr == 0) + return (false); + + pbl = malloc(len, M_NVMF_CHE, M_NOWAIT | M_ZERO); + if (pbl == NULL) { + t4_pblpool_free(sc, addr, len); + return (false); + } + + switch (mem->md_type) { + case MEMDESC_VADDR: + { + vm_offset_t va; + + va = trunc_page((uintptr_t)mem->u.md_vaddr); + for (i = 0; i < npages; i++) + pbl[i] = htobe64(pmap_kextract(va + i * PAGE_SIZE)); + break; + } + case MEMDESC_PADDR: + { + vm_paddr_t pa; + + pa = trunc_page(mem->u.md_paddr); + for (i = 0; i < npages; i++) + pbl[i] = htobe64(pa + i * PAGE_SIZE); + break; + } + case MEMDESC_VMPAGES: + for (i = 0; i < npages; i++) + pbl[i] = htobe64(VM_PAGE_TO_PHYS(mem->u.md_ma[i])); + break; + case MEMDESC_VLIST: + { + struct bus_dma_segment *ds; + vm_offset_t va; + vm_size_t len; + u_int j, k; + + i = 0; + ds = mem->u.md_list; + for (j = 0; j < mem->md_nseg; j++, ds++) { + va = trunc_page((uintptr_t)ds->ds_addr); + len = ds->ds_len; + if (ds->ds_addr % PAGE_SIZE != 0) + len += ds->ds_addr % PAGE_SIZE; + for (k = 0; k < howmany(len, PAGE_SIZE); k++) { + pbl[i] = htobe64(pmap_kextract(va + + k * PAGE_SIZE)); + i++; + } + } + MPASS(i == npages); + break; + } + case MEMDESC_PLIST: + { + struct bus_dma_segment *ds; + vm_paddr_t pa; + vm_size_t len; + u_int j, k; + + i = 0; + ds = mem->u.md_list; + for (j = 0; j < mem->md_nseg; j++, ds++) { + pa = trunc_page((vm_paddr_t)ds->ds_addr); + len = ds->ds_len; + if (ds->ds_addr % PAGE_SIZE != 0) + len += ds->ds_addr % PAGE_SIZE; + for (k = 0; k < howmany(len, PAGE_SIZE); k++) { + pbl[i] = htobe64(pa + k * PAGE_SIZE); + i++; + } + } + MPASS(i == npages); + break; + } + default: + __assert_unreachable(); + } + + error = che_write_adapter_mem(qp, addr >> 5, len, pbl); + if (error != 0) { + t4_pblpool_free(sc, addr, len); + free(pbl, M_NVMF_CHE); + return (false); + } + + cb->pbl = pbl; + cb->pbl_addr = addr; + cb->pbl_len = len; + + return (true); +} + +static void +che_free_pbl(struct nvmf_che_command_buffer *cb) +{ + free(cb->pbl, M_NVMF_CHE); + t4_pblpool_free(cb->qp->nca->sc, cb->pbl_addr, cb->pbl_len); + cb->pbl = NULL; + cb->pbl_addr = 0; + cb->pbl_len = 0; +} + +static bool +che_write_tpt_entry(struct nvmf_che_qpair *qp, + struct nvmf_che_command_buffer *cb, uint16_t stag) +{ + uint32_t tpt_addr; + int error; + + cb->tpte.valid_to_pdid = htobe32(F_FW_RI_TPTE_VALID | + V_FW_RI_TPTE_STAGKEY(CHE_STAG_COLOR(stag)) | + F_FW_RI_TPTE_STAGSTATE | + V_FW_RI_TPTE_STAGTYPE(FW_RI_STAG_NSMR) | + V_FW_RI_TPTE_PDID(0)); + cb->tpte.locread_to_qpid = htobe32( + V_FW_RI_TPTE_PERM(FW_RI_MEM_ACCESS_REM_WRITE) | + V_FW_RI_TPTE_ADDRTYPE(FW_RI_ZERO_BASED_TO) | + V_FW_RI_TPTE_PS(PAGE_SIZE) | + V_FW_RI_TPTE_QPID(qp->toep->tid)); +#define PBL_OFF(qp, a) ((a) - (qp)->nca->sc->vres.pbl.start) + cb->tpte.nosnoop_pbladdr = + htobe32(V_FW_RI_TPTE_PBLADDR(PBL_OFF(qp, cb->pbl_addr) >> 3)); + cb->tpte.len_lo = htobe32(cb->data_len); + cb->tpte.va_hi = 0; + cb->tpte.va_lo_fbo = htobe32(che_fbo(cb)); + cb->tpte.dca_mwbcnt_pstag = 0; + cb->tpte.len_hi = htobe32(cb->data_offset); + + tpt_addr = qp->tpt_offset + CHE_STAG_IDX(stag) + + (qp->nca->sc->vres.stag.start >> 5); + + error = che_write_adapter_mem(qp, tpt_addr, sizeof(cb->tpte), + &cb->tpte); + return (error == 0); +} + +static void +che_clear_tpt_entry(struct nvmf_che_qpair *qp, uint16_t stag) +{ + uint32_t tpt_addr; + + tpt_addr = qp->tpt_offset + CHE_STAG_IDX(stag) + + (qp->nca->sc->vres.stag.start >> 5); + + (void)che_write_adapter_mem(qp, tpt_addr, sizeof(struct fw_ri_tpte), + NULL); +} + +static uint16_t +che_alloc_ddp_stag(struct nvmf_che_qpair *qp, + struct nvmf_che_command_buffer *cb) +{ + uint16_t stag_idx; + + mtx_assert(&qp->rx_buffers.lock, MA_OWNED); + MPASS(cb->ddp_ok); + + if (qp->active_ddp_tags == qp->num_ddp_tags) + return (CHE_DDP_NO_TAG); + + MPASS(qp->num_ddp_tags != 0); + + stag_idx = qp->next_ddp_tag; + for (;;) { + if (qp->open_ddp_tags[stag_idx] == NULL) + break; + if (stag_idx == qp->num_ddp_tags - 1) { + stag_idx = 0; + if (qp->ddp_color == CHE_DDP_MAX_COLOR) + qp->ddp_color = 0; + else + qp->ddp_color++; + } else + stag_idx++; + MPASS(stag_idx != qp->next_ddp_tag); + } + if (stag_idx == qp->num_ddp_tags - 1) + qp->next_ddp_tag = 0; + else + qp->next_ddp_tag = stag_idx + 1; + + qp->active_ddp_tags++; + qp->open_ddp_tags[stag_idx] = cb; + + return (CHE_DDP_TAG(stag_idx, qp->ddp_color)); +} + +static void +che_free_ddp_stag(struct nvmf_che_qpair *qp, struct nvmf_che_command_buffer *cb, + uint16_t stag) +{ + MPASS(!CHE_TAG_IS_FL(stag)); + + mtx_assert(&qp->rx_buffers.lock, MA_OWNED); + + MPASS(qp->open_ddp_tags[CHE_STAG_IDX(stag)] == cb); + + qp->open_ddp_tags[CHE_STAG_IDX(stag)] = NULL; + qp->active_ddp_tags--; +} + +static uint16_t +che_alloc_ddp_tag(struct nvmf_che_qpair *qp, + struct nvmf_che_command_buffer *cb) +{ + uint16_t stag; + + mtx_assert(&qp->rx_buffers.lock, MA_OWNED); + + if (!cb->ddp_ok) + return (CHE_DDP_NO_TAG); + + stag = che_alloc_ddp_stag(qp, cb); + if (stag == CHE_DDP_NO_TAG) { + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_ddp_setup_no_stag, + 1); + return (CHE_DDP_NO_TAG); + } + + if (!che_alloc_pbl(qp, cb)) { + che_free_ddp_stag(qp, cb, stag); + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_ddp_setup_error, 1); + return (CHE_DDP_NO_TAG); + } + + if (!che_write_tpt_entry(qp, cb, stag)) { + che_free_pbl(cb); + che_free_ddp_stag(qp, cb, stag); + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_ddp_setup_error, 1); + return (CHE_DDP_NO_TAG); + } + + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_ddp_setup_ok, 1); + return (stag); +} + +static void +che_free_ddp_tag(struct nvmf_che_qpair *qp, struct nvmf_che_command_buffer *cb, + uint16_t stag) +{ + MPASS(!CHE_TAG_IS_FL(stag)); + + mtx_assert(&qp->rx_buffers.lock, MA_OWNED); + + MPASS(qp->open_ddp_tags[CHE_STAG_IDX(stag)] == cb); + + che_clear_tpt_entry(qp, stag); + che_free_pbl(cb); + che_free_ddp_stag(qp, cb, stag); +} + +static void +nvmf_che_write_pdu(struct nvmf_che_qpair *qp, struct mbuf *m) +{ + struct epoch_tracker et; + struct socket *so = qp->so; + struct inpcb *inp = sotoinpcb(so); + struct toepcb *toep = qp->toep; + + CURVNET_SET(so->so_vnet); + NET_EPOCH_ENTER(et); + INP_WLOCK(inp); + if (__predict_false(inp->inp_flags & INP_DROPPED) || + __predict_false((toep->flags & TPF_ATTACHED) == 0)) { + m_freem(m); + } else { + mbufq_enqueue(&toep->ulp_pduq, m); + t4_push_pdus(toep->vi->adapter, toep, 0); + } + INP_WUNLOCK(inp); + NET_EPOCH_EXIT(et); + CURVNET_RESTORE(); +} + +static void +nvmf_che_report_error(struct nvmf_che_qpair *qp, uint16_t fes, uint32_t fei, + struct mbuf *rx_pdu, u_int hlen) +{ + struct nvme_tcp_term_req_hdr *hdr; + struct mbuf *m; + + if (hlen != 0) { + hlen = min(hlen, NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE); + hlen = min(hlen, m_length(rx_pdu, NULL)); + } + + m = m_get2(sizeof(*hdr) + hlen, M_WAITOK, MT_DATA, M_PKTHDR); + m->m_len = sizeof(*hdr) + hlen; + m->m_pkthdr.len = m->m_len; + hdr = mtod(m, void *); + memset(hdr, 0, sizeof(*hdr)); + hdr->common.pdu_type = qp->qp.nq_controller ? + NVME_TCP_PDU_TYPE_C2H_TERM_REQ : NVME_TCP_PDU_TYPE_H2C_TERM_REQ; + hdr->common.hlen = sizeof(*hdr); + hdr->common.plen = sizeof(*hdr) + hlen; + hdr->fes = htole16(fes); + le32enc(hdr->fei, fei); + if (hlen != 0) + m_copydata(rx_pdu, 0, hlen, (caddr_t)(hdr + 1)); + + nvmf_che_write_pdu(qp, m); +} + +static int +nvmf_che_validate_pdu(struct nvmf_che_qpair *qp, struct nvmf_che_rxpdu *pdu) +{ + const struct nvme_tcp_common_pdu_hdr *ch; + struct mbuf *m = pdu->m; + uint32_t data_len, fei, plen, rx_digest; + u_int hlen, cpl_error; + int error; + uint16_t fes; + + /* Determine how large of a PDU header to return for errors. */ + ch = pdu->hdr; + hlen = ch->hlen; + plen = le32toh(ch->plen); + if (hlen < sizeof(*ch) || hlen > plen) + hlen = sizeof(*ch); + + cpl_error = m->m_pkthdr.nvmf_cpl_status & CMP_STATUS_ERROR_MASK; + switch (cpl_error) { + case CMP_STATUS_NO_ERROR: + break; + case CMP_STATUS_HEADER_DIGEST: + counter_u64_add( + qp->toep->ofld_rxq->rx_nvme_header_digest_errors, 1); + printf("NVMe/TCP: Header digest mismatch\n"); + rx_digest = le32dec(mtodo(m, ch->hlen)); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_HDGST_ERROR, rx_digest, m, + hlen); + return (EBADMSG); + case CMP_STATUS_DIRECTION_MISMATCH: + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_invalid_headers, 1); + printf("NVMe/TCP: Invalid PDU type %u\n", ch->pdu_type); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_common_pdu_hdr, pdu_type), m, + hlen); + return (EBADMSG); + case CMP_STATUS_SUCCESS_NOT_LAST: + case CMP_STATUS_DIGEST_FLAG_MISMATCH: + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_invalid_headers, 1); + printf("NVMe/TCP: Invalid PDU header flags %#x\n", ch->flags); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_common_pdu_hdr, flags), m, hlen); + return (EBADMSG); + case CMP_STATUS_BAD_DATA_LENGTH: + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_invalid_headers, 1); + printf("NVMe/TCP: Invalid PDU length %u\n", plen); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_common_pdu_hdr, plen), m, hlen); + return (EBADMSG); + case CMP_STATUS_USER_MODE_UNALLOCATED: + case CMP_STATUS_RQT_LIMIT: + case CMP_STATUS_RQT_WRAP: + case CMP_STATUS_RQT_BOUND: + device_printf(qp->nca->sc->dev, + "received invalid NVMET error %u\n", + cpl_error); + return (ECONNRESET); + case CMP_STATUS_TPT_LIMIT: + case CMP_STATUS_TPT_INVALID: + case CMP_STATUS_TPT_COLOUR_MISMATCH: + case CMP_STATUS_TPT_MISC: + case CMP_STATUS_TPT_WRAP: + case CMP_STATUS_TPT_BOUND: + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_invalid_headers, 1); + switch (ch->pdu_type) { + case NVME_TCP_PDU_TYPE_H2C_DATA: + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_h2c_data_hdr, ttag), + pdu->m, pdu->hdr->hlen); + return (EBADMSG); + case NVME_TCP_PDU_TYPE_C2H_DATA: + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_c2h_data_hdr, cccid), m, + hlen); + return (EBADMSG); + default: + device_printf(qp->nca->sc->dev, + "received DDP NVMET error %u for PDU %u\n", + cpl_error, ch->pdu_type); + return (ECONNRESET); + } + case CMP_STATUS_TPT_LAST_PDU_UNALIGNED: + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_invalid_headers, 1); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_PDU_SEQUENCE_ERROR, 0, m, hlen); + return (EBADMSG); + case CMP_STATUS_PBL_LIMIT: + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_invalid_headers, 1); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_OUT_OF_RANGE, 0, m, + hlen); + return (EBADMSG); + case CMP_STATUS_DATA_DIGEST: + /* Handled below. */ + break; + default: + device_printf(qp->nca->sc->dev, + "received unknown NVMET error %u\n", + cpl_error); + return (ECONNRESET); + } + + error = nvmf_tcp_validate_pdu_header(ch, qp->qp.nq_controller, + qp->header_digests, qp->data_digests, qp->rxpda, &data_len, &fes, + &fei); + if (error != 0) { + if (error != ECONNRESET) + nvmf_che_report_error(qp, fes, fei, m, hlen); + return (error); + } + + /* Check data digest if present. */ + pdu->data_digest_mismatch = false; + if ((ch->flags & NVME_TCP_CH_FLAGS_DDGSTF) != 0) { + if (cpl_error == CMP_STATUS_DATA_DIGEST) { + printf("NVMe/TCP: Data digest mismatch\n"); + pdu->data_digest_mismatch = true; + counter_u64_add( + qp->toep->ofld_rxq->rx_nvme_data_digest_errors, 1); + } + } + + pdu->data_len = data_len; + + return (0); +} + +static void +nvmf_che_free_pdu(struct nvmf_che_rxpdu *pdu) +{ + m_freem(pdu->m); + pdu->m = NULL; + pdu->hdr = NULL; +} + +static int +nvmf_che_handle_term_req(struct nvmf_che_rxpdu *pdu) +{ + const struct nvme_tcp_term_req_hdr *hdr; + + hdr = (const void *)pdu->hdr; + + printf("NVMe/TCP: Received termination request: fes %#x fei %#x\n", + le16toh(hdr->fes), le32dec(hdr->fei)); + nvmf_che_free_pdu(pdu); + return (ECONNRESET); +} + +static int +nvmf_che_save_command_capsule(struct nvmf_che_qpair *qp, + struct nvmf_che_rxpdu *pdu) +{ + const struct nvme_tcp_cmd *cmd; + struct nvmf_capsule *nc; + struct nvmf_che_capsule *cc; + + cmd = (const void *)pdu->hdr; + + nc = nvmf_allocate_command(&qp->qp, &cmd->ccsqe, M_WAITOK); + + cc = CCAP(nc); + cc->rx_pdu = *pdu; + + nvmf_capsule_received(&qp->qp, nc); + return (0); +} + +static int +nvmf_che_save_response_capsule(struct nvmf_che_qpair *qp, + struct nvmf_che_rxpdu *pdu) +{ + const struct nvme_tcp_rsp *rsp; + struct nvme_completion cpl; + struct nvmf_capsule *nc; + struct nvmf_che_capsule *cc; + uint16_t cid; + + rsp = (const void *)pdu->hdr; + + /* + * Restore the original CID and ensure any command buffers + * associated with this CID have been released. Once the CQE + * has been received, no further transfers to the command + * buffer for the associated CID can occur. + */ + cpl = rsp->rccqe; + cid = le16toh(cpl.cid); + if (CHE_TAG_IS_FL(cid)) { + cid = CHE_RAW_FL_TAG(cid); + mtx_lock(&qp->fl_cid_lock); + MPASS(FL_CID_ISACTIVE(cid, qp->fl_cid_set)); + cpl.cid = qp->fl_cids[cid]; + FL_CID_FREE(cid, qp->fl_cid_set); + mtx_unlock(&qp->fl_cid_lock); + + che_purge_command_buffer(&qp->rx_buffers, rsp->rccqe.cid); + che_purge_command_buffer(&qp->tx_buffers, rsp->rccqe.cid); + } else { + struct nvmf_che_command_buffer *cb; + + mtx_lock(&qp->rx_buffers.lock); + cb = qp->open_ddp_tags[CHE_STAG_IDX(cid)]; + MPASS(cb != NULL); + MPASS(cb->cid == rsp->rccqe.cid); + cpl.cid = cb->original_cid; + che_free_ddp_tag(qp, cb, cid); + mtx_unlock(&qp->rx_buffers.lock); + che_release_command_buffer(cb); + } +#ifdef VERBOSE_TRACES + CTR(KTR_CXGBE, "%s: tid %u freed cid 0x%04x for 0x%04x", __func__, + qp->toep->tid, le16toh(rsp->rccqe.cid), cpl.cid); +#endif + + nc = nvmf_allocate_response(&qp->qp, &cpl, M_WAITOK); + + nc->nc_sqhd_valid = true; + cc = CCAP(nc); + cc->rx_pdu = *pdu; + + nvmf_capsule_received(&qp->qp, nc); + return (0); +} + +/* + * Construct a PDU that contains an optional data payload. This + * includes dealing with the length fields in the common header. The + * adapter inserts digests and padding when the PDU is transmitted. + */ +static struct mbuf * +nvmf_che_construct_pdu(struct nvmf_che_qpair *qp, void *hdr, size_t hlen, + struct mbuf *data, uint32_t data_len) +{ + struct nvme_tcp_common_pdu_hdr *ch; + struct mbuf *top; + uint32_t pdo, plen; + uint8_t ulp_submode; + + plen = hlen; + if (qp->header_digests) + plen += sizeof(uint32_t); + if (data_len != 0) { + KASSERT(m_length(data, NULL) == data_len, ("length mismatch")); + pdo = roundup(plen, qp->txpda); + plen = pdo + data_len; + if (qp->data_digests) + plen += sizeof(uint32_t); + } else { + KASSERT(data == NULL, ("payload mbuf with zero length")); + pdo = 0; + } + + top = m_get2(hlen, M_WAITOK, MT_DATA, M_PKTHDR); + top->m_len = hlen; + top->m_pkthdr.len = hlen; + ch = mtod(top, void *); + memcpy(ch, hdr, hlen); + ch->hlen = hlen; + ulp_submode = 0; + if (qp->header_digests) { + ch->flags |= NVME_TCP_CH_FLAGS_HDGSTF; + ulp_submode |= ULP_CRC_HEADER; + } + if (qp->data_digests && data_len != 0) { + ch->flags |= NVME_TCP_CH_FLAGS_DDGSTF; + ulp_submode |= ULP_CRC_DATA; + } + ch->pdo = pdo; + ch->plen = htole32(plen); + set_mbuf_ulp_submode(top, ulp_submode); + + if (data_len != 0) { + top->m_pkthdr.len += data_len; + top->m_next = data; + } + + return (top); +} + +/* Allocate the next free freelist transfer tag. */ +static bool +nvmf_che_allocate_fl_ttag(struct nvmf_che_qpair *qp, + struct nvmf_che_command_buffer *cb) +{ + uint16_t ttag; + + mtx_assert(&qp->rx_buffers.lock, MA_OWNED); + + if (qp->active_fl_ttags == qp->num_fl_ttags) + return (false); + + ttag = qp->next_fl_ttag; + for (;;) { + if (qp->open_fl_ttags[ttag] == NULL) + break; + if (ttag == qp->num_fl_ttags - 1) + ttag = 0; + else + ttag++; + MPASS(ttag != qp->next_fl_ttag); + } + if (ttag == qp->num_fl_ttags - 1) + qp->next_fl_ttag = 0; + else + qp->next_fl_ttag = ttag + 1; + + qp->active_fl_ttags++; + qp->open_fl_ttags[ttag] = cb; + + cb->ttag = ttag | CHE_FL_TAG_MASK; + return (true); +} + +/* Attempt to allocate a free transfer tag and assign it to cb. */ +static bool +nvmf_che_allocate_ttag(struct nvmf_che_qpair *qp, + struct nvmf_che_command_buffer *cb) +{ + uint16_t stag; + + mtx_assert(&qp->rx_buffers.lock, MA_OWNED); + + stag = che_alloc_ddp_tag(qp, cb); + if (stag == CHE_DDP_NO_TAG) { + if (!nvmf_che_allocate_fl_ttag(qp, cb)) + return (false); + } else { + cb->ttag = stag; + } +#ifdef VERBOSE_TRACES + CTR(KTR_CXGBE, "%s: tid %u allocated ttag 0x%04x", __func__, + qp->toep->tid, cb->ttag); +#endif + cb->cc->active_r2ts++; + return (true); +} + +/* Find the next command buffer eligible to schedule for R2T. */ +static struct nvmf_che_command_buffer * +nvmf_che_next_r2t(struct nvmf_che_qpair *qp) +{ + struct nvmf_che_command_buffer *cb; + + mtx_assert(&qp->rx_buffers.lock, MA_OWNED); + + TAILQ_FOREACH(cb, &qp->rx_buffers.head, link) { + /* NB: maxr2t is 0's based. */ + if (cb->cc->active_r2ts > qp->maxr2t) + continue; + + if (!nvmf_che_allocate_ttag(qp, cb)) + return (NULL); +#ifdef INVARIANTS + cb->cc->pending_r2ts--; +#endif + TAILQ_REMOVE(&qp->rx_buffers.head, cb, link); + return (cb); + } + return (NULL); +} + +/* NB: cid and is little-endian already. */ +static void +che_send_r2t(struct nvmf_che_qpair *qp, uint16_t cid, uint16_t ttag, + uint32_t data_offset, uint32_t data_len) +{ + struct nvme_tcp_r2t_hdr r2t; + struct mbuf *m; + + memset(&r2t, 0, sizeof(r2t)); + r2t.common.pdu_type = NVME_TCP_PDU_TYPE_R2T; + r2t.cccid = cid; + r2t.ttag = htole16(ttag); + r2t.r2to = htole32(data_offset); + r2t.r2tl = htole32(data_len); + + m = nvmf_che_construct_pdu(qp, &r2t, sizeof(r2t), NULL, 0); + nvmf_che_write_pdu(qp, m); +} + +/* + * Release a transfer tag and schedule another R2T. + * + * NB: This drops the rx_buffers.lock mutex. + */ +static void +nvmf_che_send_next_r2t(struct nvmf_che_qpair *qp, + struct nvmf_che_command_buffer *cb) +{ + struct nvmf_che_command_buffer *ncb; + + mtx_assert(&qp->rx_buffers.lock, MA_OWNED); + +#ifdef VERBOSE_TRACES + CTR(KTR_CXGBE, "%s: tid %u freed ttag 0x%04x", __func__, qp->toep->tid, + cb->ttag); +#endif + if (CHE_TAG_IS_FL(cb->ttag)) { + uint16_t ttag; + + ttag = CHE_RAW_FL_TAG(cb->ttag); + MPASS(qp->open_fl_ttags[ttag] == cb); + + /* Release this transfer tag. */ + qp->open_fl_ttags[ttag] = NULL; + qp->active_fl_ttags--; + } else + che_free_ddp_tag(qp, cb, cb->ttag); + + cb->cc->active_r2ts--; + + /* Schedule another R2T. */ + ncb = nvmf_che_next_r2t(qp); + mtx_unlock(&qp->rx_buffers.lock); + if (ncb != NULL) + che_send_r2t(qp, ncb->cid, ncb->ttag, ncb->data_offset, + ncb->data_len); +} + +/* + * Copy len bytes starting at offset skip from an mbuf chain into an + * I/O buffer at destination offset io_offset. + */ +static void +mbuf_copyto_io(struct mbuf *m, u_int skip, u_int len, + struct nvmf_io_request *io, u_int io_offset) +{ + u_int todo; + + while (m->m_len <= skip) { + skip -= m->m_len; + m = m->m_next; + } + while (len != 0) { + MPASS((m->m_flags & M_EXTPG) == 0); + + todo = min(m->m_len - skip, len); + memdesc_copyback(&io->io_mem, io_offset, todo, mtodo(m, skip)); + skip = 0; + io_offset += todo; + len -= todo; + m = m->m_next; + } +} + +static int +nvmf_che_handle_h2c_data(struct nvmf_che_qpair *qp, struct nvmf_che_rxpdu *pdu) +{ + const struct nvme_tcp_h2c_data_hdr *h2c; + struct nvmf_che_command_buffer *cb; + uint32_t data_len, data_offset; + uint16_t ttag, fl_ttag; + + h2c = (const void *)pdu->hdr; + if (le32toh(h2c->datal) > qp->maxh2cdata) { + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_LIMIT_EXCEEDED, 0, + pdu->m, pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + ttag = le16toh(h2c->ttag); + if (CHE_TAG_IS_FL(ttag)) { + fl_ttag = CHE_RAW_FL_TAG(ttag); + if (fl_ttag >= qp->num_fl_ttags) { + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_h2c_data_hdr, ttag), + pdu->m, pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + mtx_lock(&qp->rx_buffers.lock); + cb = qp->open_fl_ttags[fl_ttag]; + } else { + if (CHE_STAG_IDX(ttag) >= qp->num_ddp_tags) { + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_h2c_data_hdr, ttag), + pdu->m, pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + mtx_lock(&qp->rx_buffers.lock); + cb = qp->open_ddp_tags[CHE_STAG_IDX(ttag)]; + } + + if (cb == NULL) { + mtx_unlock(&qp->rx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_h2c_data_hdr, ttag), pdu->m, + pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + MPASS(cb->ttag == ttag); + + /* For a data digest mismatch, fail the I/O request. */ + if (pdu->data_digest_mismatch) { + nvmf_che_send_next_r2t(qp, cb); + cb->error = EINTEGRITY; + che_release_command_buffer(cb); + nvmf_che_free_pdu(pdu); + return (0); + } + + data_len = le32toh(h2c->datal); + if (data_len != pdu->data_len) { + mtx_unlock(&qp->rx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_h2c_data_hdr, datal), pdu->m, + pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + data_offset = le32toh(h2c->datao); + if (data_offset < cb->data_offset || + data_offset + data_len > cb->data_offset + cb->data_len) { + mtx_unlock(&qp->rx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_OUT_OF_RANGE, 0, pdu->m, + pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + if (data_offset != cb->data_offset + cb->data_xfered) { + if (CHE_TAG_IS_FL(ttag)) { + mtx_unlock(&qp->rx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_PDU_SEQUENCE_ERROR, 0, pdu->m, + pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } else { + uint32_t ddp_bytes; + + /* Account for PDUs silently received via DDP. */ + ddp_bytes = data_offset - + (cb->data_offset + cb->data_xfered); + cb->data_xfered += ddp_bytes; +#ifdef VERBOSE_TRACES + CTR(KTR_CXGBE, "%s: tid %u previous ddp_bytes %u", + __func__, qp->toep->tid, ddp_bytes); +#endif + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_ddp_octets, + ddp_bytes); + } + } + + if ((cb->data_xfered + data_len == cb->data_len) != + ((pdu->hdr->flags & NVME_TCP_H2C_DATA_FLAGS_LAST_PDU) != 0)) { + mtx_unlock(&qp->rx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_PDU_SEQUENCE_ERROR, 0, pdu->m, + pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + cb->data_xfered += data_len; + data_offset -= cb->data_offset; + if (cb->data_xfered == cb->data_len) { + nvmf_che_send_next_r2t(qp, cb); + } else { + che_hold_command_buffer(cb); + mtx_unlock(&qp->rx_buffers.lock); + } + + if (CHE_TAG_IS_FL(ttag)) + mbuf_copyto_io(pdu->m->m_next, 0, data_len, &cb->io, + data_offset); + + che_release_command_buffer(cb); + nvmf_che_free_pdu(pdu); + return (0); +} + +static int +nvmf_che_handle_c2h_data(struct nvmf_che_qpair *qp, struct nvmf_che_rxpdu *pdu) +{ + const struct nvme_tcp_c2h_data_hdr *c2h; + struct nvmf_che_command_buffer *cb; + uint32_t data_len, data_offset; + uint16_t cid, original_cid; + + /* + * Unlike freelist command buffers, DDP command buffers are + * not released until the response capsule is received to keep + * the STAG allocated until the command has completed. + */ + c2h = (const void *)pdu->hdr; + + cid = le16toh(c2h->cccid); + if (CHE_TAG_IS_FL(cid)) { + mtx_lock(&qp->rx_buffers.lock); + cb = che_find_command_buffer(&qp->rx_buffers, c2h->cccid); + } else { + if (CHE_STAG_IDX(cid) >= qp->num_ddp_tags) { + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_c2h_data_hdr, cccid), + pdu->m, pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + mtx_lock(&qp->rx_buffers.lock); + cb = qp->open_ddp_tags[CHE_STAG_IDX(cid)]; + } + + if (cb == NULL) { + mtx_unlock(&qp->rx_buffers.lock); + /* + * XXX: Could be PDU sequence error if cccid is for a + * command that doesn't use a command buffer. + */ + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_c2h_data_hdr, cccid), pdu->m, + pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + /* For a data digest mismatch, fail the I/O request. */ + if (pdu->data_digest_mismatch) { + cb->error = EINTEGRITY; + if (CHE_TAG_IS_FL(cid)) { + che_remove_command_buffer(&qp->rx_buffers, cb); + mtx_unlock(&qp->rx_buffers.lock); + che_release_command_buffer(cb); + } else + mtx_unlock(&qp->rx_buffers.lock); + nvmf_che_free_pdu(pdu); + return (0); + } + + data_len = le32toh(c2h->datal); + if (data_len != pdu->data_len) { + mtx_unlock(&qp->rx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_c2h_data_hdr, datal), pdu->m, + pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + data_offset = le32toh(c2h->datao); + if (data_offset < cb->data_offset || + data_offset + data_len > cb->data_offset + cb->data_len) { + mtx_unlock(&qp->rx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_OUT_OF_RANGE, 0, + pdu->m, pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + if (data_offset != cb->data_offset + cb->data_xfered) { + if (CHE_TAG_IS_FL(cid)) { + mtx_unlock(&qp->rx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_PDU_SEQUENCE_ERROR, 0, pdu->m, + pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } else { + uint32_t ddp_bytes; + + /* Account for PDUs silently received via DDP. */ + ddp_bytes = data_offset - + (cb->data_offset + cb->data_xfered); + cb->data_xfered += ddp_bytes; +#ifdef VERBOSE_TRACES + CTR(KTR_CXGBE, "%s: tid %u previous ddp_bytes %u", + __func__, qp->toep->tid, ddp_bytes); +#endif + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_ddp_octets, + ddp_bytes); + } + } + + if ((cb->data_xfered + data_len == cb->data_len) != + ((pdu->hdr->flags & NVME_TCP_C2H_DATA_FLAGS_LAST_PDU) != 0)) { + mtx_unlock(&qp->rx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_PDU_SEQUENCE_ERROR, 0, pdu->m, + pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + cb->data_xfered += data_len; + original_cid = cb->original_cid; + + if (CHE_TAG_IS_FL(cid)) { + data_offset -= cb->data_offset; + if (cb->data_xfered == cb->data_len) + che_remove_command_buffer(&qp->rx_buffers, cb); + else + che_hold_command_buffer(cb); + mtx_unlock(&qp->rx_buffers.lock); + + if ((pdu->hdr->flags & NVME_TCP_C2H_DATA_FLAGS_SUCCESS) != 0) { + /* + * Free the CID as the command has now been + * completed. + */ + cid = CHE_RAW_FL_TAG(cid); + mtx_lock(&qp->fl_cid_lock); + MPASS(FL_CID_ISACTIVE(cid, qp->fl_cid_set)); + MPASS(original_cid == qp->fl_cids[cid]); + FL_CID_FREE(cid, qp->fl_cid_set); + mtx_unlock(&qp->fl_cid_lock); + } + + mbuf_copyto_io(pdu->m->m_next, 0, data_len, &cb->io, + data_offset); + + che_release_command_buffer(cb); + } else { + if ((pdu->hdr->flags & NVME_TCP_C2H_DATA_FLAGS_SUCCESS) != 0) { + /* + * Free the command buffer and STAG as the + * command has now been completed. + */ + che_free_ddp_tag(qp, cb, cid); + mtx_unlock(&qp->rx_buffers.lock); + che_release_command_buffer(cb); + } else + mtx_unlock(&qp->rx_buffers.lock); + } + + if ((pdu->hdr->flags & NVME_TCP_C2H_DATA_FLAGS_SUCCESS) != 0) { + struct nvme_completion cqe; + struct nvmf_capsule *nc; + + memset(&cqe, 0, sizeof(cqe)); + cqe.cid = original_cid; + + nc = nvmf_allocate_response(&qp->qp, &cqe, M_WAITOK); + nc->nc_sqhd_valid = false; + + nvmf_capsule_received(&qp->qp, nc); + } + + nvmf_che_free_pdu(pdu); + return (0); +} + +/* Called when m_free drops refcount to 0. */ +static void +nvmf_che_mbuf_done(struct mbuf *m) +{ + struct nvmf_che_command_buffer *cb = m->m_ext.ext_arg1; + + che_free_command_buffer(cb); +} + +static struct mbuf * +nvmf_che_mbuf(void *arg, int how, void *data, size_t len) +{ + struct nvmf_che_command_buffer *cb = arg; + struct mbuf *m; + + m = m_get(how, MT_DATA); + m->m_flags |= M_RDONLY; + m_extaddref(m, data, len, &cb->refs, nvmf_che_mbuf_done, cb, NULL); + m->m_len = len; + return (m); +} + +static void +nvmf_che_free_mext_pg(struct mbuf *m) +{ + struct nvmf_che_command_buffer *cb = m->m_ext.ext_arg1; + + M_ASSERTEXTPG(m); + che_release_command_buffer(cb); +} + +static struct mbuf * +nvmf_che_mext_pg(void *arg, int how) +{ + struct nvmf_che_command_buffer *cb = arg; + struct mbuf *m; + + m = mb_alloc_ext_pgs(how, nvmf_che_free_mext_pg, M_RDONLY); + m->m_ext.ext_arg1 = cb; + che_hold_command_buffer(cb); + return (m); +} + +/* + * Return an mbuf chain for a range of data belonging to a command + * buffer. + * + * The mbuf chain uses M_EXT mbufs which hold references on the + * command buffer so that it remains "alive" until the data has been + * fully transmitted. If truncate_ok is true, then the mbuf chain + * might return a short chain to avoid gratuitously splitting up a + * page. + */ +static struct mbuf * +nvmf_che_command_buffer_mbuf(struct nvmf_che_command_buffer *cb, + uint32_t data_offset, uint32_t data_len, uint32_t *actual_len, + bool can_truncate) +{ + struct mbuf *m; + size_t len; + + m = memdesc_alloc_ext_mbufs(&cb->io.io_mem, nvmf_che_mbuf, + nvmf_che_mext_pg, cb, M_WAITOK, data_offset, data_len, &len, + can_truncate); + if (actual_len != NULL) + *actual_len = len; + return (m); +} + +/* NB: cid and ttag and little-endian already. */ +static void +che_send_h2c_pdu(struct nvmf_che_qpair *qp, uint16_t cid, uint16_t ttag, + uint32_t data_offset, struct mbuf *m, size_t len, bool last_pdu) +{ + struct nvme_tcp_h2c_data_hdr h2c; + struct mbuf *top; + + memset(&h2c, 0, sizeof(h2c)); + h2c.common.pdu_type = NVME_TCP_PDU_TYPE_H2C_DATA; + if (last_pdu) + h2c.common.flags |= NVME_TCP_H2C_DATA_FLAGS_LAST_PDU; + h2c.cccid = cid; + h2c.ttag = ttag; + h2c.datao = htole32(data_offset); + h2c.datal = htole32(len); + + top = nvmf_che_construct_pdu(qp, &h2c, sizeof(h2c), m, len); + nvmf_che_write_pdu(qp, top); +} + +static int +nvmf_che_handle_r2t(struct nvmf_che_qpair *qp, struct nvmf_che_rxpdu *pdu) +{ + const struct nvme_tcp_r2t_hdr *r2t; + struct nvmf_che_command_buffer *cb; + uint32_t data_len, data_offset; + + r2t = (const void *)pdu->hdr; + + mtx_lock(&qp->tx_buffers.lock); + cb = che_find_command_buffer(&qp->tx_buffers, r2t->cccid); + if (cb == NULL) { + mtx_unlock(&qp->tx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD, + offsetof(struct nvme_tcp_r2t_hdr, cccid), pdu->m, + pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + data_offset = le32toh(r2t->r2to); + if (data_offset != cb->data_xfered) { + mtx_unlock(&qp->tx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_PDU_SEQUENCE_ERROR, 0, pdu->m, + pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + /* + * XXX: The spec does not specify how to handle R2T tranfers + * out of range of the original command. + */ + data_len = le32toh(r2t->r2tl); + if (data_offset + data_len > cb->data_len) { + mtx_unlock(&qp->tx_buffers.lock); + nvmf_che_report_error(qp, + NVME_TCP_TERM_REQ_FES_DATA_TRANSFER_OUT_OF_RANGE, 0, + pdu->m, pdu->hdr->hlen); + nvmf_che_free_pdu(pdu); + return (EBADMSG); + } + + cb->data_xfered += data_len; + if (cb->data_xfered == cb->data_len) + che_remove_command_buffer(&qp->tx_buffers, cb); + else + che_hold_command_buffer(cb); + mtx_unlock(&qp->tx_buffers.lock); + + /* + * Queue one or more H2C_DATA PDUs containing the requested + * data. + */ + while (data_len > 0) { + struct mbuf *m; + uint32_t sent, todo; + + todo = min(data_len, qp->max_tx_data); + m = nvmf_che_command_buffer_mbuf(cb, data_offset, todo, &sent, + todo < data_len); + che_send_h2c_pdu(qp, r2t->cccid, r2t->ttag, data_offset, m, + sent, sent == data_len); + + data_offset += sent; + data_len -= sent; + } + + che_release_command_buffer(cb); + nvmf_che_free_pdu(pdu); + return (0); +} + +static int +nvmf_che_dispatch_pdu(struct nvmf_che_qpair *qp, struct nvmf_che_rxpdu *pdu) +{ + /* + * The PDU header should always be contiguous in the mbuf from + * CPL_NVMT_CMP. + */ + pdu->hdr = mtod(pdu->m, void *); + KASSERT(pdu->m->m_len == pdu->hdr->hlen + + ((pdu->hdr->flags & NVME_TCP_CH_FLAGS_HDGSTF) != 0 ? + sizeof(uint32_t) : 0), + ("%s: mismatched PDU header mbuf length", __func__)); + + switch (pdu->hdr->pdu_type) { + default: + __assert_unreachable(); + break; + case NVME_TCP_PDU_TYPE_H2C_TERM_REQ: + case NVME_TCP_PDU_TYPE_C2H_TERM_REQ: + return (nvmf_che_handle_term_req(pdu)); + case NVME_TCP_PDU_TYPE_CAPSULE_CMD: + return (nvmf_che_save_command_capsule(qp, pdu)); + case NVME_TCP_PDU_TYPE_CAPSULE_RESP: + return (nvmf_che_save_response_capsule(qp, pdu)); + case NVME_TCP_PDU_TYPE_H2C_DATA: + return (nvmf_che_handle_h2c_data(qp, pdu)); + case NVME_TCP_PDU_TYPE_C2H_DATA: + return (nvmf_che_handle_c2h_data(qp, pdu)); + case NVME_TCP_PDU_TYPE_R2T: + return (nvmf_che_handle_r2t(qp, pdu)); + } +} + +static int +nvmf_che_attach_pdu_data(struct nvmf_che_qpair *qp, struct nvmf_che_rxpdu *pdu) +{ + struct socket *so = qp->so; + struct mbuf *m, *n; + uint32_t tcp_seq; + size_t len; + int error; + + /* Check for DDP data. */ + if (pdu->ddp) { + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_ddp_pdus, 1); + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_ddp_octets, + pdu->data_len); + return (0); + } + + error = 0; + len = pdu->data_len; + tcp_seq = pdu->m->m_pkthdr.nvmf_tcp_seq; + m = pdu->m; + SOCKBUF_LOCK(&so->so_rcv); + while (len > 0) { + n = mbufq_dequeue(&qp->rx_data); + KASSERT(n != NULL, ("%s: missing %zu data", __func__, len)); + if (n == NULL) { + error = ENOBUFS; + break; + } + + KASSERT(n->m_pkthdr.nvmf_tcp_seq == tcp_seq, + ("%s: TCP seq mismatch", __func__)); + KASSERT(n->m_pkthdr.len <= len, + ("%s: too much data", __func__)); + if (n->m_pkthdr.nvmf_tcp_seq != tcp_seq || + n->m_pkthdr.len > len) { + m_freem(n); + error = ENOBUFS; + break; + } + +#ifdef VERBOSE_TRACES + CTR(KTR_CXGBE, "%s: tid %u len %d seq %u", __func__, + qp->toep->tid, n->m_pkthdr.len, n->m_pkthdr.nvmf_tcp_seq); +#endif + pdu->m->m_pkthdr.len += n->m_pkthdr.len; + len -= n->m_pkthdr.len; + tcp_seq += n->m_pkthdr.len; + m_demote_pkthdr(n); + m->m_next = n; + m = m_last(n); + } + SOCKBUF_UNLOCK(&so->so_rcv); + + if (error == 0) { + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_fl_pdus, 1); + counter_u64_add(qp->toep->ofld_rxq->rx_nvme_fl_octets, + pdu->data_len); + } + return (error); +} + +static void +nvmf_che_receive(void *arg) +{ + struct nvmf_che_qpair *qp = arg; + struct socket *so = qp->so; + struct nvmf_che_rxpdu pdu; + struct mbuf *m; + int error, terror; + + SOCKBUF_LOCK(&so->so_rcv); + while (!qp->rx_shutdown) { + /* Wait for a PDU. */ + if (so->so_error != 0 || so->so_rerror != 0) { + if (so->so_error != 0) + error = so->so_error; + else + error = so->so_rerror; + SOCKBUF_UNLOCK(&so->so_rcv); + error: + nvmf_qpair_error(&qp->qp, error); + SOCKBUF_LOCK(&so->so_rcv); + while (!qp->rx_shutdown) + cv_wait(&qp->rx_cv, SOCKBUF_MTX(&so->so_rcv)); + break; + } + + m = mbufq_dequeue(&qp->rx_pdus); + if (m == NULL) { + if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) != 0) { + error = 0; + SOCKBUF_UNLOCK(&so->so_rcv); + goto error; + } + cv_wait(&qp->rx_cv, SOCKBUF_MTX(&so->so_rcv)); + continue; + } + SOCKBUF_UNLOCK(&so->so_rcv); + + pdu.m = m; + pdu.hdr = mtod(m, const void *); + pdu.ddp = (m->m_pkthdr.nvmf_cpl_status & CMP_STATUS_DDP) != 0; + + error = nvmf_che_validate_pdu(qp, &pdu); + if (error == 0 && pdu.data_len != 0) + error = nvmf_che_attach_pdu_data(qp, &pdu); + if (error != 0) + nvmf_che_free_pdu(&pdu); + else + error = nvmf_che_dispatch_pdu(qp, &pdu); + if (error != 0) { + /* + * If we received a termination request, close + * the connection immediately. + */ + if (error == ECONNRESET) + goto error; + + /* + * Wait for up to 30 seconds for the socket to + * be closed by the other end. + */ + SOCKBUF_LOCK(&so->so_rcv); + if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0) { + terror = cv_timedwait(&qp->rx_cv, + SOCKBUF_MTX(&so->so_rcv), 30 * hz); + if (terror == ETIMEDOUT) + printf("NVMe/TCP: Timed out after sending terminate request\n"); + } + SOCKBUF_UNLOCK(&so->so_rcv); + goto error; + } + + SOCKBUF_LOCK(&so->so_rcv); + } + SOCKBUF_UNLOCK(&so->so_rcv); + kthread_exit(); +} + +static int +nvmf_che_soupcall_receive(struct socket *so, void *arg, int waitflag) +{ + struct nvmf_che_qpair *qp = arg; + + cv_signal(&qp->rx_cv); + return (SU_OK); +} + +static int +do_nvmt_data(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) +{ + struct adapter *sc = iq->adapter; + struct nvmf_che_adapter *nca = sc->nvme_ulp_softc; + const struct cpl_nvmt_data *cpl; + u_int tid; + struct toepcb *toep; + struct nvmf_che_qpair *qp; + struct socket *so; + struct inpcb *inp; + struct tcpcb *tp; + int len __diagused; + + if (nca->nvmt_data_iqe) { + cpl = (const void *)(rss + 1); + } else { + cpl = mtod(m, const void *); + + /* strip off CPL header */ + m_adj(m, sizeof(*cpl)); + } + tid = GET_TID(cpl); + toep = lookup_tid(sc, tid); + + KASSERT(toep->tid == tid, ("%s: toep tid/atid mismatch", __func__)); + + len = m->m_pkthdr.len; + + KASSERT(len == be16toh(cpl->length), + ("%s: payload length mismatch", __func__)); + + inp = toep->inp; + INP_WLOCK(inp); + if (inp->inp_flags & INP_DROPPED) { + CTR(KTR_CXGBE, "%s: tid %u, rx (%d bytes), inp_flags 0x%x", + __func__, tid, len, inp->inp_flags); + INP_WUNLOCK(inp); + m_freem(m); + return (0); + } + + /* Save TCP sequence number. */ + m->m_pkthdr.nvmf_tcp_seq = be32toh(cpl->seq); + + qp = toep->ulpcb; + so = qp->so; + SOCKBUF_LOCK(&so->so_rcv); + mbufq_enqueue(&qp->rx_data, m); + SOCKBUF_UNLOCK(&so->so_rcv); + + tp = intotcpcb(inp); + tp->t_rcvtime = ticks; + +#ifdef VERBOSE_TRACES + CTR(KTR_CXGBE, "%s: tid %u len %d seq %u", __func__, tid, len, + be32toh(cpl->seq)); +#endif + + INP_WUNLOCK(inp); + return (0); +} + +static int +do_nvmt_cmp(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) +{ + struct adapter *sc = iq->adapter; + const struct cpl_nvmt_cmp *cpl = mtod(m, const void *); + u_int tid = GET_TID(cpl); + struct toepcb *toep = lookup_tid(sc, tid); + struct nvmf_che_qpair *qp = toep->ulpcb; + struct socket *so = qp->so; + struct inpcb *inp = toep->inp; + u_int hlen __diagused; + bool empty; + + KASSERT(toep->tid == tid, ("%s: toep tid/atid mismatch", __func__)); + KASSERT(!(toep->flags & TPF_SYNQE), + ("%s: toep %p claims to be a synq entry", __func__, toep)); + + /* strip off CPL header */ + m_adj(m, sizeof(*cpl)); + hlen = m->m_pkthdr.len; + + KASSERT(hlen == be16toh(cpl->length), + ("%s: payload length mismatch", __func__)); + + INP_WLOCK(inp); + if (inp->inp_flags & INP_DROPPED) { + CTR(KTR_CXGBE, "%s: tid %u, rx (hlen %u), inp_flags 0x%x", + __func__, tid, hlen, inp->inp_flags); + INP_WUNLOCK(inp); + m_freem(m); + return (0); + } + +#ifdef VERBOSE_TRACES + CTR(KTR_CXGBE, "%s: tid %u hlen %u seq %u status %u", __func__, tid, + hlen, be32toh(cpl->seq), cpl->status); +#endif + + /* Save TCP sequence number and CPL status. */ + m->m_pkthdr.nvmf_tcp_seq = be32toh(cpl->seq); + m->m_pkthdr.nvmf_cpl_status = cpl->status; + + SOCKBUF_LOCK(&so->so_rcv); + empty = mbufq_len(&qp->rx_pdus) == 0; + mbufq_enqueue(&qp->rx_pdus, m); + SOCKBUF_UNLOCK(&so->so_rcv); + INP_WUNLOCK(inp); + if (empty) + cv_signal(&qp->rx_cv); + return (0); +} + +static uint16_t +che_alloc_fl_cid(struct nvmf_che_qpair *qp, uint16_t original_cid) +{ + uint16_t new_cid; + + mtx_lock(&qp->fl_cid_lock); + new_cid = FL_CID_FINDFREE_AT(qp->fl_cid_set, qp->next_cid); + if (new_cid == 0) { + new_cid = FL_CID_FINDFREE_AT(qp->fl_cid_set, 0); + MPASS(new_cid != 0); + } + new_cid--; + FL_CID_BUSY(new_cid, qp->fl_cid_set); + if (new_cid == CHE_MAX_FL_TAG) + qp->next_cid = 0; + else + qp->next_cid = new_cid + 1; + qp->fl_cids[new_cid] = original_cid; + mtx_unlock(&qp->fl_cid_lock); + + return (new_cid | CHE_FL_TAG_MASK); +} + +static uint16_t +che_alloc_ddp_cid(struct nvmf_che_qpair *qp, struct nvmf_che_command_buffer *cb) +{ + mtx_assert(&qp->rx_buffers.lock, MA_OWNED); + + return (che_alloc_ddp_tag(qp, cb)); +} + +static struct mbuf * +che_command_pdu(struct nvmf_che_qpair *qp, struct nvmf_che_capsule *cc) +{ + struct nvmf_capsule *nc = &cc->nc; + struct nvmf_che_command_buffer *cb; + struct nvme_sgl_descriptor *sgl; + struct nvme_tcp_cmd cmd; + struct mbuf *top, *m; + uint16_t cid; + bool use_icd; + + use_icd = false; + cb = NULL; + m = NULL; + + if (nc->nc_data.io_len != 0) { + cb = che_alloc_command_buffer(qp, &nc->nc_data, 0, + nc->nc_data.io_len, nc->nc_sqe.cid); + cb->original_cid = nc->nc_sqe.cid; + + if (nc->nc_send_data && nc->nc_data.io_len <= qp->max_icd) { + cid = che_alloc_fl_cid(qp, nc->nc_sqe.cid); + use_icd = true; + m = nvmf_che_command_buffer_mbuf(cb, 0, + nc->nc_data.io_len, NULL, false); + cb->data_xfered = nc->nc_data.io_len; + che_release_command_buffer(cb); + } else if (nc->nc_send_data) { + cid = che_alloc_fl_cid(qp, nc->nc_sqe.cid); + cb->cid = htole16(cid); + mtx_lock(&qp->tx_buffers.lock); + che_add_command_buffer(&qp->tx_buffers, cb); + mtx_unlock(&qp->tx_buffers.lock); + } else { + mtx_lock(&qp->rx_buffers.lock); + cid = che_alloc_ddp_cid(qp, cb); + if (cid == CHE_DDP_NO_TAG) { + cid = che_alloc_fl_cid(qp, nc->nc_sqe.cid); + che_add_command_buffer(&qp->rx_buffers, cb); + } + cb->cid = htole16(cid); + mtx_unlock(&qp->rx_buffers.lock); + } + } else + cid = che_alloc_fl_cid(qp, nc->nc_sqe.cid); + +#ifdef VERBOSE_TRACES + CTR(KTR_CXGBE, "%s: tid %u allocated cid 0x%04x for 0x%04x", __func__, + qp->toep->tid, cid, nc->nc_sqe.cid); +#endif + memset(&cmd, 0, sizeof(cmd)); + cmd.common.pdu_type = NVME_TCP_PDU_TYPE_CAPSULE_CMD; + cmd.ccsqe = nc->nc_sqe; + cmd.ccsqe.cid = htole16(cid); + + /* Populate SGL in SQE. */ + sgl = &cmd.ccsqe.sgl; + memset(sgl, 0, sizeof(*sgl)); + sgl->address = 0; + sgl->length = htole32(nc->nc_data.io_len); + if (use_icd) { + /* Use in-capsule data. */ + sgl->type = NVME_SGL_TYPE_ICD; + } else { + /* Use a command buffer. */ + sgl->type = NVME_SGL_TYPE_COMMAND_BUFFER; + } + + top = nvmf_che_construct_pdu(qp, &cmd, sizeof(cmd), m, m != NULL ? + nc->nc_data.io_len : 0); + return (top); +} + +static struct mbuf * +che_response_pdu(struct nvmf_che_qpair *qp, struct nvmf_che_capsule *cc) +{ + struct nvmf_capsule *nc = &cc->nc; + struct nvme_tcp_rsp rsp; + + memset(&rsp, 0, sizeof(rsp)); + rsp.common.pdu_type = NVME_TCP_PDU_TYPE_CAPSULE_RESP; + rsp.rccqe = nc->nc_cqe; + + return (nvmf_che_construct_pdu(qp, &rsp, sizeof(rsp), NULL, 0)); +} + +static struct mbuf * +capsule_to_pdu(struct nvmf_che_qpair *qp, struct nvmf_che_capsule *cc) +{ + if (cc->nc.nc_qe_len == sizeof(struct nvme_command)) + return (che_command_pdu(qp, cc)); + else + return (che_response_pdu(qp, cc)); +} + +static void +nvmf_che_send(void *arg) +{ + struct nvmf_che_qpair *qp = arg; + struct nvmf_che_capsule *cc; + struct socket *so = qp->so; + struct mbuf *m; + int error; + + m = NULL; + SOCKBUF_LOCK(&so->so_snd); + while (!qp->tx_shutdown) { + if (so->so_error != 0) { + error = so->so_error; + SOCKBUF_UNLOCK(&so->so_snd); + m_freem(m); + nvmf_qpair_error(&qp->qp, error); + SOCKBUF_LOCK(&so->so_snd); + while (!qp->tx_shutdown) + cv_wait(&qp->tx_cv, SOCKBUF_MTX(&so->so_snd)); + break; + } + + if (STAILQ_EMPTY(&qp->tx_capsules)) { + cv_wait(&qp->tx_cv, SOCKBUF_MTX(&so->so_snd)); + continue; + } + + /* Convert a capsule into a PDU. */ + cc = STAILQ_FIRST(&qp->tx_capsules); + STAILQ_REMOVE_HEAD(&qp->tx_capsules, link); + SOCKBUF_UNLOCK(&so->so_snd); + + m = capsule_to_pdu(qp, cc); + che_release_capsule(cc); + + nvmf_che_write_pdu(qp, m); + + SOCKBUF_LOCK(&so->so_snd); + } + SOCKBUF_UNLOCK(&so->so_snd); + kthread_exit(); +} + +static int +nvmf_che_setsockopt(struct socket *so, u_int sspace, u_int rspace) +{ + struct sockopt opt; + int error, one = 1; + + /* Don't lower the buffer sizes, just enforce a minimum. */ + SOCKBUF_LOCK(&so->so_snd); + if (sspace < so->so_snd.sb_hiwat) + sspace = so->so_snd.sb_hiwat; + SOCKBUF_UNLOCK(&so->so_snd); + SOCKBUF_LOCK(&so->so_rcv); + if (rspace < so->so_rcv.sb_hiwat) + rspace = so->so_rcv.sb_hiwat; + SOCKBUF_UNLOCK(&so->so_rcv); + + error = soreserve(so, sspace, rspace); + if (error != 0) + return (error); + SOCKBUF_LOCK(&so->so_snd); + so->so_snd.sb_flags |= SB_AUTOSIZE; + SOCKBUF_UNLOCK(&so->so_snd); + SOCKBUF_LOCK(&so->so_rcv); + so->so_rcv.sb_flags |= SB_AUTOSIZE; + SOCKBUF_UNLOCK(&so->so_rcv); + + /* + * Disable Nagle. + */ + bzero(&opt, sizeof(opt)); + opt.sopt_dir = SOPT_SET; + opt.sopt_level = IPPROTO_TCP; + opt.sopt_name = TCP_NODELAY; + opt.sopt_val = &one; + opt.sopt_valsize = sizeof(one); + error = sosetopt(so, &opt); + if (error != 0) + return (error); + + return (0); +} + +static void +t4_nvme_set_tcb_field(struct toepcb *toep, uint16_t word, uint64_t mask, + uint64_t val) +{ + struct adapter *sc = td_adapter(toep->td); + + t4_set_tcb_field(sc, &toep->ofld_txq->wrq, toep, word, mask, val, 0, 0); +} + +static void +set_ulp_mode_nvme(struct toepcb *toep, u_int ulp_submode, uint8_t rxpda) +{ + uint64_t val; + + CTR(KTR_CXGBE, "%s: tid %u, ULP_MODE_NVMET, submode=%#x, rxpda=%u", + __func__, toep->tid, ulp_submode, rxpda); + + val = V_TCB_ULP_TYPE(ULP_MODE_NVMET) | V_TCB_ULP_RAW(ulp_submode); + t4_nvme_set_tcb_field(toep, W_TCB_ULP_TYPE, + V_TCB_ULP_TYPE(M_TCB_ULP_TYPE) | V_TCB_ULP_RAW(M_TCB_ULP_RAW), val); + + val = V_TF_RX_FLOW_CONTROL_DISABLE(1ULL); + t4_nvme_set_tcb_field(toep, W_TCB_T_FLAGS, val, val); + + val = V_TCB_RSVD((rxpda / 4) - 1); + t4_nvme_set_tcb_field(toep, W_TCB_RSVD, V_TCB_RSVD(M_TCB_RSVD), val); + + /* 0 disables CPL_NVMT_CMP_IMM which is not useful in this driver. */ + val = 0; + t4_nvme_set_tcb_field(toep, W_TCB_CMP_IMM_SZ, + V_TCB_CMP_IMM_SZ(M_TCB_CMP_IMM_SZ), val); +} + +static u_int +pdu_max_data_len(const nvlist_t *nvl, u_int max_pdu_len, u_int hlen, + uint8_t pda) +{ + u_int max_data_len; + + if (nvlist_get_bool(nvl, "header_digests")) + hlen += sizeof(uint32_t); + hlen = roundup(hlen, pda); + max_data_len = max_pdu_len - hlen; + if (nvlist_get_bool(nvl, "data_digests")) + max_data_len -= sizeof(uint32_t); + return (max_data_len); +} + +static struct nvmf_qpair * +che_allocate_qpair(bool controller, const nvlist_t *nvl) +{ + struct nvmf_che_adapter *nca; + struct nvmf_che_qpair *qp; + struct adapter *sc; + struct file *fp; + struct socket *so; + struct inpcb *inp; + struct tcpcb *tp; + struct toepcb *toep; + cap_rights_t rights; + u_int max_tx_pdu_len, num_ddp_tags; + int error, ulp_submode; + + if (!nvlist_exists_number(nvl, "fd") || + !nvlist_exists_number(nvl, "rxpda") || + !nvlist_exists_number(nvl, "txpda") || + !nvlist_exists_bool(nvl, "header_digests") || + !nvlist_exists_bool(nvl, "data_digests") || + !nvlist_exists_number(nvl, "maxr2t") || + !nvlist_exists_number(nvl, "maxh2cdata") || + !nvlist_exists_number(nvl, "max_icd")) + return (NULL); + + error = fget(curthread, nvlist_get_number(nvl, "fd"), + cap_rights_init_one(&rights, CAP_SOCK_CLIENT), &fp); + if (error != 0) + return (NULL); + if (fp->f_type != DTYPE_SOCKET) { + fdrop(fp, curthread); + return (NULL); + } + so = fp->f_data; + if (so->so_type != SOCK_STREAM || + so->so_proto->pr_protocol != IPPROTO_TCP) { + fdrop(fp, curthread); + return (NULL); + } + + sc = find_offload_adapter(so); + if (sc == NULL) { + fdrop(fp, curthread); + return (NULL); + } + nca = sc->nvme_ulp_softc; + + /* + * Controller: Require advertised MAXH2CDATA to be small + * enough. + */ + if (controller) { + u_int max_rx_data; + + max_rx_data = pdu_max_data_len(nvl, nca->max_receive_pdu, + sizeof(struct nvme_tcp_h2c_data_hdr), + nvlist_get_number(nvl, "rxpda")); + if (nvlist_get_number(nvl, "maxh2cdata") > max_rx_data) { + fdrop(fp, curthread); + return (NULL); + } + } + + /* + * Host: Require the queue size to be small enough that all of + * the command ids allocated by nvmf(4) will fit in the + * unallocated range. + * + * XXX: Alternatively this driver could just queue commands + * when an unallocated ID isn't available. + */ + if (!controller) { + u_int num_commands; + + num_commands = nvlist_get_number(nvl, "qsize") - 1; + if (nvlist_get_bool(nvl, "admin")) + num_commands += 8; /* Max AER */ + if (num_commands > CHE_NUM_FL_TAGS) { + fdrop(fp, curthread); + return (NULL); + } + } + + qp = malloc(sizeof(*qp), M_NVMF_CHE, M_WAITOK | M_ZERO); + qp->txpda = nvlist_get_number(nvl, "txpda"); + qp->rxpda = nvlist_get_number(nvl, "rxpda"); + qp->header_digests = nvlist_get_bool(nvl, "header_digests"); + qp->data_digests = nvlist_get_bool(nvl, "data_digests"); + qp->maxr2t = nvlist_get_number(nvl, "maxr2t"); + if (controller) + qp->maxh2cdata = nvlist_get_number(nvl, "maxh2cdata"); + + if (controller) { + /* NB: maxr2t is 0's based. */ + qp->num_fl_ttags = MIN(CHE_NUM_FL_TAGS, + nvlist_get_number(nvl, "qsize") * + ((uint64_t)qp->maxr2t + 1)); + qp->open_fl_ttags = mallocarray(qp->num_fl_ttags, + sizeof(*qp->open_fl_ttags), M_NVMF_CHE, M_WAITOK | M_ZERO); + } else { + qp->fl_cids = mallocarray(CHE_NUM_FL_TAGS, + sizeof(*qp->fl_cids), M_NVMF_CHE, M_WAITOK | M_ZERO); + qp->fl_cid_set = malloc(sizeof(*qp->fl_cid_set), M_NVMF_CHE, + M_WAITOK); + FL_CID_INIT(qp->fl_cid_set); + mtx_init(&qp->fl_cid_lock, "nvmf/che fl cids", NULL, MTX_DEF); + } + + inp = sotoinpcb(so); + INP_WLOCK(inp); + tp = intotcpcb(inp); + if (inp->inp_flags & INP_DROPPED) { + INP_WUNLOCK(inp); + free(qp->fl_cid_set, M_NVMF_CHE); + free(qp->fl_cids, M_NVMF_CHE); + free(qp->open_fl_ttags, M_NVMF_CHE); + free(qp, M_NVMF_CHE); + fdrop(fp, curthread); + return (NULL); + } + + MPASS(tp->t_flags & TF_TOE); + MPASS(tp->tod != NULL); + MPASS(tp->t_toe != NULL); + toep = tp->t_toe; + MPASS(toep->vi->adapter == sc); + + if (ulp_mode(toep) != ULP_MODE_NONE) { + INP_WUNLOCK(inp); + free(qp->fl_cid_set, M_NVMF_CHE); + free(qp->fl_cids, M_NVMF_CHE); + free(qp->open_fl_ttags, M_NVMF_CHE); + free(qp, M_NVMF_CHE); + fdrop(fp, curthread); + return (NULL); + } + + /* Claim socket from file descriptor. */ + fp->f_ops = &badfileops; + fp->f_data = NULL; + + qp->so = so; + qp->toep = toep; + qp->nca = nca; + refcount_init(&qp->refs, 1); + + /* NB: C2H and H2C headers are the same size. */ + qp->max_rx_data = pdu_max_data_len(nvl, nca->max_receive_pdu, + sizeof(struct nvme_tcp_c2h_data_hdr), qp->rxpda); + qp->max_tx_data = pdu_max_data_len(nvl, nca->max_transmit_pdu, + sizeof(struct nvme_tcp_c2h_data_hdr), qp->txpda); + if (!controller) { + qp->max_tx_data = min(qp->max_tx_data, + nvlist_get_number(nvl, "maxh2cdata")); + qp->max_icd = min(nvlist_get_number(nvl, "max_icd"), + pdu_max_data_len(nvl, nca->max_transmit_pdu, + sizeof(struct nvme_tcp_cmd), qp->txpda)); + } else { + /* + * IOCCSZ represents the size of a logical command + * capsule including the 64 byte SQE and the + * in-capsule data. Use pdu_max_data_len to compute + * the maximum supported ICD length. + */ + qp->max_ioccsz = rounddown(pdu_max_data_len(nvl, + nca->max_receive_pdu, sizeof(struct nvme_tcp_cmd), + qp->rxpda), 16) + sizeof(struct nvme_command); + } + + ulp_submode = 0; + if (qp->header_digests) + ulp_submode |= FW_NVMET_ULPSUBMODE_HCRC; + if (qp->data_digests) + ulp_submode |= FW_NVMET_ULPSUBMODE_DCRC; + if (!controller) + ulp_submode |= FW_NVMET_ULPSUBMODE_ING_DIR; + + max_tx_pdu_len = sizeof(struct nvme_tcp_h2c_data_hdr); + if (qp->header_digests) + max_tx_pdu_len += sizeof(uint32_t); + max_tx_pdu_len = roundup(max_tx_pdu_len, qp->txpda); + max_tx_pdu_len += qp->max_tx_data; + if (qp->data_digests) + max_tx_pdu_len += sizeof(uint32_t); + + /* TODO: ISO limits */ + + if (controller) { + /* Use the SUCCESS flag if SQ flow control is disabled. */ + qp->send_success = !nvlist_get_bool(nvl, "sq_flow_control"); + } + + toep->params.ulp_mode = ULP_MODE_NVMET; + toep->ulpcb = qp; + + send_txdataplen_max_flowc_wr(sc, toep, + roundup(/* max_iso_pdus * */ max_tx_pdu_len, tp->t_maxseg)); + set_ulp_mode_nvme(toep, ulp_submode, qp->rxpda); + INP_WUNLOCK(inp); + + fdrop(fp, curthread); + + error = nvmf_che_setsockopt(so, max_tx_pdu_len, nca->max_receive_pdu); + if (error != 0) { + free(qp->fl_cid_set, M_NVMF_CHE); + free(qp->fl_cids, M_NVMF_CHE); + free(qp->open_fl_ttags, M_NVMF_CHE); + free(qp, M_NVMF_CHE); + return (NULL); + } + + num_ddp_tags = ddp_tags_per_qp; + if (num_ddp_tags > 0) { + qp->tpt_offset = t4_stag_alloc(sc, num_ddp_tags); + if (qp->tpt_offset != T4_STAG_UNSET) { +#ifdef VERBOSE_TRACES + CTR(KTR_CXGBE, + "%s: tid %u using %u tags at offset 0x%x", + __func__, toep->tid, num_ddp_tags, qp->tpt_offset); +#endif + qp->num_ddp_tags = num_ddp_tags; + qp->open_ddp_tags = mallocarray(qp->num_ddp_tags, + sizeof(*qp->open_ddp_tags), M_NVMF_CHE, M_WAITOK | + M_ZERO); + + t4_nvme_set_tcb_field(toep, W_TCB_TPT_OFFSET, + M_TCB_TPT_OFFSET, V_TCB_TPT_OFFSET(qp->tpt_offset)); + } + } + + TAILQ_INIT(&qp->rx_buffers.head); + TAILQ_INIT(&qp->tx_buffers.head); + mtx_init(&qp->rx_buffers.lock, "nvmf/che rx buffers", NULL, MTX_DEF); + mtx_init(&qp->tx_buffers.lock, "nvmf/che tx buffers", NULL, MTX_DEF); + + cv_init(&qp->rx_cv, "-"); + cv_init(&qp->tx_cv, "-"); + mbufq_init(&qp->rx_data, 0); + mbufq_init(&qp->rx_pdus, 0); + STAILQ_INIT(&qp->tx_capsules); + + /* Register socket upcall for receive to handle remote FIN. */ + SOCKBUF_LOCK(&so->so_rcv); + soupcall_set(so, SO_RCV, nvmf_che_soupcall_receive, qp); + SOCKBUF_UNLOCK(&so->so_rcv); + + /* Spin up kthreads. */ + error = kthread_add(nvmf_che_receive, qp, NULL, &qp->rx_thread, 0, 0, + "nvmef che rx"); + if (error != 0) { + che_free_qpair(&qp->qp); + return (NULL); + } + error = kthread_add(nvmf_che_send, qp, NULL, &qp->tx_thread, 0, 0, + "nvmef che tx"); + if (error != 0) { + che_free_qpair(&qp->qp); + return (NULL); + } + + return (&qp->qp); +} + +static void +che_release_qpair(struct nvmf_che_qpair *qp) +{ + if (refcount_release(&qp->refs)) + free(qp, M_NVMF_CHE); +} + +static void +che_free_qpair(struct nvmf_qpair *nq) +{ + struct nvmf_che_qpair *qp = CQP(nq); + struct nvmf_che_command_buffer *ncb, *cb; + struct nvmf_che_capsule *ncc, *cc; + struct socket *so = qp->so; + struct toepcb *toep = qp->toep; + struct inpcb *inp = sotoinpcb(so); + + /* Shut down kthreads. */ + SOCKBUF_LOCK(&so->so_snd); + qp->tx_shutdown = true; + if (qp->tx_thread != NULL) { + cv_signal(&qp->tx_cv); + mtx_sleep(qp->tx_thread, SOCKBUF_MTX(&so->so_snd), 0, + "nvchetx", 0); + } + SOCKBUF_UNLOCK(&so->so_snd); + + SOCKBUF_LOCK(&so->so_rcv); + qp->rx_shutdown = true; + if (qp->rx_thread != NULL) { + cv_signal(&qp->rx_cv); + mtx_sleep(qp->rx_thread, SOCKBUF_MTX(&so->so_rcv), 0, + "nvcherx", 0); + } + soupcall_clear(so, SO_RCV); + SOCKBUF_UNLOCK(&so->so_rcv); + mbufq_drain(&qp->rx_data); + mbufq_drain(&qp->rx_pdus); + + STAILQ_FOREACH_SAFE(cc, &qp->tx_capsules, link, ncc) { + nvmf_abort_capsule_data(&cc->nc, ECONNABORTED); + che_release_capsule(cc); + } + + cv_destroy(&qp->tx_cv); + cv_destroy(&qp->rx_cv); + + if (qp->open_fl_ttags != NULL) { + for (u_int i = 0; i < qp->num_fl_ttags; i++) { + cb = qp->open_fl_ttags[i]; + if (cb != NULL) { + cb->cc->active_r2ts--; + cb->error = ECONNABORTED; + che_release_command_buffer(cb); + } + } + free(qp->open_fl_ttags, M_NVMF_CHE); + } + if (qp->num_ddp_tags != 0) { + for (u_int i = 0; i < qp->num_ddp_tags; i++) { + cb = qp->open_ddp_tags[i]; + if (cb != NULL) { + if (cb->cc != NULL) + cb->cc->active_r2ts--; + cb->error = ECONNABORTED; + mtx_lock(&qp->rx_buffers.lock); + che_free_ddp_tag(qp, cb, cb->ttag); + mtx_unlock(&qp->rx_buffers.lock); + che_release_command_buffer(cb); + } + } + free(qp->open_ddp_tags, M_NVMF_CHE); + } + + mtx_lock(&qp->rx_buffers.lock); + TAILQ_FOREACH_SAFE(cb, &qp->rx_buffers.head, link, ncb) { + che_remove_command_buffer(&qp->rx_buffers, cb); + mtx_unlock(&qp->rx_buffers.lock); +#ifdef INVARIANTS + if (cb->cc != NULL) + cb->cc->pending_r2ts--; +#endif + cb->error = ECONNABORTED; + che_release_command_buffer(cb); + mtx_lock(&qp->rx_buffers.lock); + } + mtx_destroy(&qp->rx_buffers.lock); + + mtx_lock(&qp->tx_buffers.lock); + TAILQ_FOREACH_SAFE(cb, &qp->tx_buffers.head, link, ncb) { + che_remove_command_buffer(&qp->tx_buffers, cb); + mtx_unlock(&qp->tx_buffers.lock); + cb->error = ECONNABORTED; + che_release_command_buffer(cb); + mtx_lock(&qp->tx_buffers.lock); + } + mtx_destroy(&qp->tx_buffers.lock); + + if (qp->num_ddp_tags != 0) + t4_stag_free(qp->nca->sc, qp->tpt_offset, qp->num_ddp_tags); + + if (!qp->qp.nq_controller) { + free(qp->fl_cids, M_NVMF_CHE); + free(qp->fl_cid_set, M_NVMF_CHE); + mtx_destroy(&qp->fl_cid_lock); + } + + INP_WLOCK(inp); + toep->ulpcb = NULL; + mbufq_drain(&toep->ulp_pduq); + + /* + * Grab a reference to use when waiting for the final CPL to + * be received. If toep->inp is NULL, then + * final_cpl_received() has already been called (e.g. due to + * the peer sending a RST). + */ + if (toep->inp != NULL) { + toep = hold_toepcb(toep); + toep->flags |= TPF_WAITING_FOR_FINAL; + } else + toep = NULL; + INP_WUNLOCK(inp); + + soclose(so); + + /* + * Wait for the socket to fully close. This ensures any + * pending received data has been received (and in particular, + * any data that would be received by DDP has been handled). + */ + if (toep != NULL) { + struct mtx *lock = mtx_pool_find(mtxpool_sleep, toep); + + mtx_lock(lock); + while ((toep->flags & TPF_WAITING_FOR_FINAL) != 0) + mtx_sleep(toep, lock, PSOCK, "conclo2", 0); + mtx_unlock(lock); + free_toepcb(toep); + } + + che_release_qpair(qp); +} + +static uint32_t +che_max_ioccsz(struct nvmf_qpair *nq) +{ + struct nvmf_che_qpair *qp = CQP(nq); + + /* + * Limit the command capsule size so that with maximum ICD it + * fits within the limit of the largest PDU the adapter can + * receive. + */ + return (qp->max_ioccsz); +} + +static uint64_t +che_max_xfer_size(struct nvmf_qpair *nq) +{ + struct nvmf_che_qpair *qp = CQP(nq); + + /* + * Limit host transfers to the size of the data payload in the + * largest PDU the adapter can receive. + */ + return (qp->max_rx_data); +} + +static struct nvmf_capsule * +che_allocate_capsule(struct nvmf_qpair *nq, int how) +{ + struct nvmf_che_qpair *qp = CQP(nq); + struct nvmf_che_capsule *cc; + + cc = malloc(sizeof(*cc), M_NVMF_CHE, how | M_ZERO); + if (cc == NULL) + return (NULL); + refcount_init(&cc->refs, 1); + refcount_acquire(&qp->refs); + return (&cc->nc); +} + +static void +che_release_capsule(struct nvmf_che_capsule *cc) +{ + struct nvmf_che_qpair *qp = CQP(cc->nc.nc_qpair); + + if (!refcount_release(&cc->refs)) + return; + + MPASS(cc->active_r2ts == 0); + MPASS(cc->pending_r2ts == 0); + + nvmf_che_free_pdu(&cc->rx_pdu); + free(cc, M_NVMF_CHE); + che_release_qpair(qp); +} + +static void +che_free_capsule(struct nvmf_capsule *nc) +{ + che_release_capsule(CCAP(nc)); +} + +static int +che_transmit_capsule(struct nvmf_capsule *nc) +{ + struct nvmf_che_qpair *qp = CQP(nc->nc_qpair); + struct nvmf_che_capsule *cc = CCAP(nc); + struct socket *so = qp->so; + + refcount_acquire(&cc->refs); + SOCKBUF_LOCK(&so->so_snd); + STAILQ_INSERT_TAIL(&qp->tx_capsules, cc, link); + cv_signal(&qp->tx_cv); + SOCKBUF_UNLOCK(&so->so_snd); + return (0); +} + +static uint8_t +che_validate_command_capsule(struct nvmf_capsule *nc) +{ + struct nvmf_che_capsule *cc = CCAP(nc); + struct nvme_sgl_descriptor *sgl; + + KASSERT(cc->rx_pdu.hdr != NULL, ("capsule wasn't received")); + + sgl = &nc->nc_sqe.sgl; + switch (sgl->type) { + case NVME_SGL_TYPE_ICD: + if (cc->rx_pdu.data_len != le32toh(sgl->length)) { + printf("NVMe/TCP: Command Capsule with mismatched ICD length\n"); + return (NVME_SC_DATA_SGL_LENGTH_INVALID); + } + break; + case NVME_SGL_TYPE_COMMAND_BUFFER: + if (cc->rx_pdu.data_len != 0) { + printf("NVMe/TCP: Command Buffer SGL with ICD\n"); + return (NVME_SC_INVALID_FIELD); + } + break; + default: + printf("NVMe/TCP: Invalid SGL type in Command Capsule\n"); + return (NVME_SC_SGL_DESCRIPTOR_TYPE_INVALID); + } + + if (sgl->address != 0) { + printf("NVMe/TCP: Invalid SGL offset in Command Capsule\n"); + return (NVME_SC_SGL_OFFSET_INVALID); + } + + return (NVME_SC_SUCCESS); +} + +static size_t +che_capsule_data_len(const struct nvmf_capsule *nc) +{ + MPASS(nc->nc_qe_len == sizeof(struct nvme_command)); + return (le32toh(nc->nc_sqe.sgl.length)); +} + +static void +che_receive_r2t_data(struct nvmf_capsule *nc, uint32_t data_offset, + struct nvmf_io_request *io) +{ + struct nvmf_che_qpair *qp = CQP(nc->nc_qpair); + struct nvmf_che_capsule *cc = CCAP(nc); + struct nvmf_che_command_buffer *cb; + + cb = che_alloc_command_buffer(qp, io, data_offset, io->io_len, + nc->nc_sqe.cid); + + cb->cc = cc; + refcount_acquire(&cc->refs); + + /* + * If this command has too many active R2Ts or there are no + * available transfer tags, queue the request for later. + * + * NB: maxr2t is 0's based. + */ + mtx_lock(&qp->rx_buffers.lock); + if (cc->active_r2ts > qp->maxr2t || + !nvmf_che_allocate_ttag(qp, cb)) { +#ifdef INVARIANTS + cc->pending_r2ts++; +#endif + TAILQ_INSERT_TAIL(&qp->rx_buffers.head, cb, link); + mtx_unlock(&qp->rx_buffers.lock); + return; + } + mtx_unlock(&qp->rx_buffers.lock); + + che_send_r2t(qp, nc->nc_sqe.cid, cb->ttag, data_offset, io->io_len); +} + +static void +che_receive_icd_data(struct nvmf_capsule *nc, uint32_t data_offset, + struct nvmf_io_request *io) +{ + struct nvmf_che_capsule *cc = CCAP(nc); + + /* + * The header is in rx_pdu.m, the padding is discarded, and + * the data starts at rx_pdu.m->m_next. + */ + mbuf_copyto_io(cc->rx_pdu.m->m_next, data_offset, io->io_len, io, 0); + nvmf_complete_io_request(io, io->io_len, 0); +} + +static int +che_receive_controller_data(struct nvmf_capsule *nc, uint32_t data_offset, + struct nvmf_io_request *io) +{ + struct nvme_sgl_descriptor *sgl; + size_t data_len; + + if (nc->nc_qe_len != sizeof(struct nvme_command) || + !nc->nc_qpair->nq_controller) + return (EINVAL); + + sgl = &nc->nc_sqe.sgl; + data_len = le32toh(sgl->length); + if (data_offset + io->io_len > data_len) + return (EFBIG); + + if (sgl->type == NVME_SGL_TYPE_ICD) + che_receive_icd_data(nc, data_offset, io); + else + che_receive_r2t_data(nc, data_offset, io); + return (0); +} + +/* NB: cid is little-endian already. */ +static void +che_send_c2h_pdu(struct nvmf_che_qpair *qp, uint16_t cid, uint32_t data_offset, + struct mbuf *m, size_t len, bool last_pdu, bool success) +{ + struct nvme_tcp_c2h_data_hdr c2h; + struct mbuf *top; + + memset(&c2h, 0, sizeof(c2h)); + c2h.common.pdu_type = NVME_TCP_PDU_TYPE_C2H_DATA; + if (last_pdu) + c2h.common.flags |= NVME_TCP_C2H_DATA_FLAGS_LAST_PDU; + if (success) + c2h.common.flags |= NVME_TCP_C2H_DATA_FLAGS_SUCCESS; + c2h.cccid = cid; + c2h.datao = htole32(data_offset); + c2h.datal = htole32(len); + + top = nvmf_che_construct_pdu(qp, &c2h, sizeof(c2h), m, len); + nvmf_che_write_pdu(qp, top); +} + +static u_int +che_send_controller_data(struct nvmf_capsule *nc, uint32_t data_offset, + struct mbuf *m, size_t len) +{ + struct nvmf_che_qpair *qp = CQP(nc->nc_qpair); + struct nvme_sgl_descriptor *sgl; + uint32_t data_len; + bool last_pdu, last_xfer; + + if (nc->nc_qe_len != sizeof(struct nvme_command) || + !qp->qp.nq_controller) { + m_freem(m); + return (NVME_SC_INVALID_FIELD); + } + + sgl = &nc->nc_sqe.sgl; + data_len = le32toh(sgl->length); + if (data_offset + len > data_len) { + m_freem(m); + return (NVME_SC_INVALID_FIELD); + } + last_xfer = (data_offset + len == data_len); + + if (sgl->type != NVME_SGL_TYPE_COMMAND_BUFFER) { + m_freem(m); + return (NVME_SC_INVALID_FIELD); + } + + KASSERT(data_offset == CCAP(nc)->tx_data_offset, + ("%s: starting data_offset %u doesn't match end of previous xfer %u", + __func__, data_offset, CCAP(nc)->tx_data_offset)); + + /* Queue one or more C2H_DATA PDUs containing the data from 'm'. */ + while (m != NULL) { + struct mbuf *n; + uint32_t todo; + + if (m->m_len > qp->max_tx_data) { + n = m_split(m, qp->max_tx_data, M_WAITOK); + todo = m->m_len; + } else { + struct mbuf *p; + + todo = m->m_len; + p = m; + n = p->m_next; + while (n != NULL) { + if (todo + n->m_len > qp->max_tx_data) { + p->m_next = NULL; + break; + } + todo += n->m_len; + p = n; + n = p->m_next; + } + MPASS(m_length(m, NULL) == todo); + } + + last_pdu = (n == NULL && last_xfer); + che_send_c2h_pdu(qp, nc->nc_sqe.cid, data_offset, m, todo, + last_pdu, last_pdu && qp->send_success); + + data_offset += todo; + data_len -= todo; + m = n; + } + MPASS(data_len == 0); + +#ifdef INVARIANTS + CCAP(nc)->tx_data_offset = data_offset; +#endif + if (!last_xfer) + return (NVMF_MORE); + else if (qp->send_success) + return (NVMF_SUCCESS_SENT); + else + return (NVME_SC_SUCCESS); +} + +struct nvmf_transport_ops che_ops = { + .allocate_qpair = che_allocate_qpair, + .free_qpair = che_free_qpair, + .max_ioccsz = che_max_ioccsz, + .max_xfer_size = che_max_xfer_size, + .allocate_capsule = che_allocate_capsule, + .free_capsule = che_free_capsule, + .transmit_capsule = che_transmit_capsule, + .validate_command_capsule = che_validate_command_capsule, + .capsule_data_len = che_capsule_data_len, + .receive_controller_data = che_receive_controller_data, + .send_controller_data = che_send_controller_data, + .trtype = NVMF_TRTYPE_TCP, + .priority = 10, +}; + +NVMF_TRANSPORT(che, che_ops); + +static void +read_pdu_limits(struct adapter *sc, u_int *max_tx_pdu_len, + uint32_t *max_rx_pdu_len) +{ + uint32_t tx_len, rx_len, r, v; + + /* Copied from cxgbei, but not sure if this is correct. */ + rx_len = t4_read_reg(sc, A_TP_PMM_RX_PAGE_SIZE); + tx_len = t4_read_reg(sc, A_TP_PMM_TX_PAGE_SIZE); + + r = t4_read_reg(sc, A_TP_PARA_REG2); + rx_len = min(rx_len, G_MAXRXDATA(r)); + tx_len = min(tx_len, G_MAXRXDATA(r)); + + r = t4_read_reg(sc, A_TP_PARA_REG7); + v = min(G_PMMAXXFERLEN0(r), G_PMMAXXFERLEN1(r)); + rx_len = min(rx_len, v); + tx_len = min(tx_len, v); + + /* Cannot be larger than 32KB - 256. */ + rx_len = min(rx_len, 32512); + tx_len = min(tx_len, 32512); + + *max_tx_pdu_len = tx_len; + *max_rx_pdu_len = rx_len; +} + +static int +nvmf_che_init(struct adapter *sc, struct nvmf_che_adapter *nca) +{ + struct sysctl_oid *oid; + struct sysctl_oid_list *children; + uint32_t val; + + read_pdu_limits(sc, &nca->max_transmit_pdu, &nca->max_receive_pdu); + if (nca->max_transmit_pdu > che_max_transmit_pdu) + nca->max_transmit_pdu = che_max_transmit_pdu; + if (nca->max_receive_pdu > che_max_receive_pdu) + nca->max_receive_pdu = che_max_receive_pdu; + val = t4_read_reg(sc, A_SGE_CONTROL2); + nca->nvmt_data_iqe = (val & F_RXCPLMODE_NVMT) != 0; + + sysctl_ctx_init(&nca->ctx); + oid = device_get_sysctl_tree(sc->dev); /* dev.che.X */ + children = SYSCTL_CHILDREN(oid); + + oid = SYSCTL_ADD_NODE(&nca->ctx, children, OID_AUTO, "nvme", + CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "NVMe ULP settings"); + children = SYSCTL_CHILDREN(oid); + + nca->ddp_threshold = 8192; + SYSCTL_ADD_UINT(&nca->ctx, children, OID_AUTO, "ddp_threshold", + CTLFLAG_RW, &nca->ddp_threshold, 0, "Rx zero copy threshold"); + + SYSCTL_ADD_UINT(&nca->ctx, children, OID_AUTO, "max_transmit_pdu", + CTLFLAG_RW, &nca->max_transmit_pdu, 0, + "Maximum size of a transmitted PDU"); + + SYSCTL_ADD_UINT(&nca->ctx, children, OID_AUTO, "max_receive_pdu", + CTLFLAG_RW, &nca->max_receive_pdu, 0, + "Maximum size of a received PDU"); + + return (0); +} + +static void +nvmf_che_destroy(struct nvmf_che_adapter *nca) +{ + sysctl_ctx_free(&nca->ctx); + free(nca, M_CXGBE); +} + +static int +nvmf_che_activate(struct adapter *sc) +{ + struct nvmf_che_adapter *nca; + int rc; + + ASSERT_SYNCHRONIZED_OP(sc); + + if (uld_active(sc, ULD_NVME)) { + KASSERT(0, ("%s: NVMe offload already enabled on adapter %p", + __func__, sc)); + return (0); + } + + if ((sc->nvmecaps & FW_CAPS_CONFIG_NVME_TCP) == 0) { + device_printf(sc->dev, + "not NVMe offload capable, or capability disabled\n"); + return (ENOSYS); + } + + /* per-adapter softc for NVMe */ + nca = malloc(sizeof(*nca), M_CXGBE, M_ZERO | M_WAITOK); + nca->sc = sc; + + rc = nvmf_che_init(sc, nca); + if (rc != 0) { + free(nca, M_CXGBE); + return (rc); + } + + sc->nvme_ulp_softc = nca; + + return (0); +} + +static int +nvmf_che_deactivate(struct adapter *sc) +{ + struct nvmf_che_adapter *nca = sc->nvme_ulp_softc; + + ASSERT_SYNCHRONIZED_OP(sc); + + if (nca != NULL) { + nvmf_che_destroy(nca); + sc->nvme_ulp_softc = NULL; + } + + return (0); +} + +static void +nvmf_che_activate_all(struct adapter *sc, void *arg __unused) +{ + if (begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t7nvact") != 0) + return; + + /* Activate NVMe if any port on this adapter has IFCAP_TOE enabled. */ + if (sc->offload_map && !uld_active(sc, ULD_NVME)) + (void) t4_activate_uld(sc, ULD_NVME); + + end_synchronized_op(sc, 0); +} + +static void +nvmf_che_deactivate_all(struct adapter *sc, void *arg __unused) +{ + if (begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t7nvdea") != 0) + return; + + if (uld_active(sc, ULD_NVME)) + (void) t4_deactivate_uld(sc, ULD_NVME); + + end_synchronized_op(sc, 0); +} + +static struct uld_info nvmf_che_uld_info = { + .uld_activate = nvmf_che_activate, + .uld_deactivate = nvmf_che_deactivate, +}; + +static int +nvmf_che_mod_load(void) +{ + int rc; + + t4_register_cpl_handler(CPL_NVMT_CMP, do_nvmt_cmp); + t4_register_cpl_handler(CPL_NVMT_DATA, do_nvmt_data); + + rc = t4_register_uld(&nvmf_che_uld_info, ULD_NVME); + if (rc != 0) + return (rc); + + t4_iterate(nvmf_che_activate_all, NULL); + + return (rc); +} + +static int +nvmf_che_mod_unload(void) +{ + t4_iterate(nvmf_che_deactivate_all, NULL); + + if (t4_unregister_uld(&nvmf_che_uld_info, ULD_NVME) == EBUSY) + return (EBUSY); + + t4_register_cpl_handler(CPL_NVMT_CMP, NULL); + t4_register_cpl_handler(CPL_NVMT_DATA, NULL); + + return (0); +} +#endif + +static int +nvmf_che_modevent(module_t mod, int cmd, void *arg) +{ + int rc; + +#ifdef TCP_OFFLOAD + switch (cmd) { + case MOD_LOAD: + rc = nvmf_che_mod_load(); + break; + case MOD_UNLOAD: + rc = nvmf_che_mod_unload(); + break; + default: + rc = EOPNOTSUPP; + break; + } +#else + printf("nvmf_che: compiled without TCP_OFFLOAD support.\n"); + rc = EOPNOTSUPP; +#endif + + return (rc); +} + +static moduledata_t nvmf_che_mod = { + "nvmf_che", + nvmf_che_modevent, + NULL, +}; + +MODULE_VERSION(nvmf_che, 1); +DECLARE_MODULE(nvmf_che, nvmf_che_mod, SI_SUB_EXEC, SI_ORDER_ANY); +MODULE_DEPEND(nvmf_che, t4_tom, 1, 1, 1); +MODULE_DEPEND(nvmf_che, cxgbe, 1, 1, 1); diff --git a/sys/dev/cxgbe/offload.h b/sys/dev/cxgbe/offload.h index 91a43785aaca..d63accf86e2a 100644 --- a/sys/dev/cxgbe/offload.h +++ b/sys/dev/cxgbe/offload.h @@ -196,7 +196,8 @@ enum { ULD_TOM = 0, ULD_IWARP, ULD_ISCSI, - ULD_MAX = ULD_ISCSI + ULD_NVME, + ULD_MAX = ULD_NVME }; struct adapter; diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 22d2f504c257..9bd5e02fabf0 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -611,7 +611,7 @@ static int t4_switchcaps_allowed = FW_CAPS_CONFIG_SWITCH_INGRESS | SYSCTL_INT(_hw_cxgbe, OID_AUTO, switchcaps_allowed, CTLFLAG_RDTUN, &t4_switchcaps_allowed, 0, "Default switch capabilities"); -static int t4_nvmecaps_allowed = 0; +static int t4_nvmecaps_allowed = -1; SYSCTL_INT(_hw_cxgbe, OID_AUTO, nvmecaps_allowed, CTLFLAG_RDTUN, &t4_nvmecaps_allowed, 0, "Default NVMe capabilities"); @@ -1327,6 +1327,8 @@ t4_attach(device_t dev) sc->dev = dev; sysctl_ctx_init(&sc->ctx); TUNABLE_INT_FETCH("hw.cxgbe.dflags", &sc->debug_flags); + if (TUNABLE_INT_FETCH("hw.cxgbe.iflags", &sc->intr_flags) == 0) + sc->intr_flags = IHF_INTR_CLEAR_ON_INIT | IHF_CLR_ALL_UNIGNORED; if ((pci_get_device(dev) & 0xff00) == 0x5400) t5_attribute_workaround(dev); @@ -3652,6 +3654,7 @@ port_mword(struct port_info *pi, uint32_t speed) case FW_PORT_TYPE_SFP28: case FW_PORT_TYPE_SFP56: case FW_PORT_TYPE_QSFP56: + case FW_PORT_TYPE_QSFPDD: /* Pluggable transceiver */ switch (pi->mod_type) { case FW_PORT_MOD_TYPE_LR: @@ -3671,6 +3674,8 @@ port_mword(struct port_info *pi, uint32_t speed) return (IFM_100G_LR4); case FW_PORT_CAP32_SPEED_200G: return (IFM_200G_LR4); + case FW_PORT_CAP32_SPEED_400G: + return (IFM_400G_LR8); } break; case FW_PORT_MOD_TYPE_SR: @@ -3689,6 +3694,8 @@ port_mword(struct port_info *pi, uint32_t speed) return (IFM_100G_SR4); case FW_PORT_CAP32_SPEED_200G: return (IFM_200G_SR4); + case FW_PORT_CAP32_SPEED_400G: + return (IFM_400G_SR8); } break; case FW_PORT_MOD_TYPE_ER: @@ -3712,6 +3719,8 @@ port_mword(struct port_info *pi, uint32_t speed) return (IFM_100G_CR4); case FW_PORT_CAP32_SPEED_200G: return (IFM_200G_CR4_PAM4); + case FW_PORT_CAP32_SPEED_400G: + return (IFM_400G_CR8); } break; case FW_PORT_MOD_TYPE_LRM: @@ -3723,10 +3732,12 @@ port_mword(struct port_info *pi, uint32_t speed) return (IFM_100G_DR); if (speed == FW_PORT_CAP32_SPEED_200G) return (IFM_200G_DR4); + if (speed == FW_PORT_CAP32_SPEED_400G) + return (IFM_400G_DR4); break; case FW_PORT_MOD_TYPE_NA: MPASS(0); /* Not pluggable? */ - /* fall throough */ + /* fall through */ case FW_PORT_MOD_TYPE_ERROR: case FW_PORT_MOD_TYPE_UNKNOWN: case FW_PORT_MOD_TYPE_NOTSUPPORTED: @@ -3735,6 +3746,10 @@ port_mword(struct port_info *pi, uint32_t speed) return (IFM_NONE); } break; + case M_FW_PORT_CMD_PTYPE: /* FW_PORT_TYPE_NONE for old firmware */ + if (chip_id(pi->adapter) >= CHELSIO_T7) + return (IFM_UNKNOWN); + /* fall through */ case FW_PORT_TYPE_NONE: return (IFM_NONE); } @@ -3930,8 +3945,6 @@ fatal_error_task(void *arg, int pending) void t4_fatal_err(struct adapter *sc, bool fw_error) { - const bool verbose = (sc->debug_flags & DF_VERBOSE_SLOWINTR) != 0; - stop_adapter(sc); if (atomic_testandset_int(&sc->error_flags, ilog2(ADAP_FATAL_ERR))) return; @@ -3944,7 +3957,7 @@ t4_fatal_err(struct adapter *sc, bool fw_error) * main INT_CAUSE registers here to make sure we haven't missed * anything interesting. */ - t4_slow_intr_handler(sc, verbose); + t4_slow_intr_handler(sc, sc->intr_flags); atomic_set_int(&sc->error_flags, ADAP_CIM_ERR); } t4_report_fw_error(sc); @@ -5408,6 +5421,7 @@ apply_cfg_and_initialize(struct adapter *sc, char *cfg_file, caps.toecaps = 0; caps.rdmacaps = 0; caps.iscsicaps = 0; + caps.nvmecaps = 0; } caps.op_to_write = htobe32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) | @@ -5881,61 +5895,63 @@ get_params__post_init(struct adapter *sc) * that will never be used. */ sc->iscsicaps = 0; + sc->nvmecaps = 0; sc->rdmacaps = 0; } - if (sc->rdmacaps) { + if (sc->nvmecaps || sc->rdmacaps) { param[0] = FW_PARAM_PFVF(STAG_START); param[1] = FW_PARAM_PFVF(STAG_END); - param[2] = FW_PARAM_PFVF(RQ_START); - param[3] = FW_PARAM_PFVF(RQ_END); - param[4] = FW_PARAM_PFVF(PBL_START); - param[5] = FW_PARAM_PFVF(PBL_END); - rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val); + param[2] = FW_PARAM_PFVF(PBL_START); + param[3] = FW_PARAM_PFVF(PBL_END); + rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 4, param, val); if (rc != 0) { device_printf(sc->dev, - "failed to query RDMA parameters(1): %d.\n", rc); + "failed to query NVMe/RDMA parameters: %d.\n", rc); return (rc); } sc->vres.stag.start = val[0]; sc->vres.stag.size = val[1] - val[0] + 1; - sc->vres.rq.start = val[2]; - sc->vres.rq.size = val[3] - val[2] + 1; - sc->vres.pbl.start = val[4]; - sc->vres.pbl.size = val[5] - val[4] + 1; - - param[0] = FW_PARAM_PFVF(SQRQ_START); - param[1] = FW_PARAM_PFVF(SQRQ_END); - param[2] = FW_PARAM_PFVF(CQ_START); - param[3] = FW_PARAM_PFVF(CQ_END); - param[4] = FW_PARAM_PFVF(OCQ_START); - param[5] = FW_PARAM_PFVF(OCQ_END); + sc->vres.pbl.start = val[2]; + sc->vres.pbl.size = val[3] - val[2] + 1; + } + if (sc->rdmacaps) { + param[0] = FW_PARAM_PFVF(RQ_START); + param[1] = FW_PARAM_PFVF(RQ_END); + param[2] = FW_PARAM_PFVF(SQRQ_START); + param[3] = FW_PARAM_PFVF(SQRQ_END); + param[4] = FW_PARAM_PFVF(CQ_START); + param[5] = FW_PARAM_PFVF(CQ_END); rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val); if (rc != 0) { device_printf(sc->dev, - "failed to query RDMA parameters(2): %d.\n", rc); + "failed to query RDMA parameters(1): %d.\n", rc); return (rc); } - sc->vres.qp.start = val[0]; - sc->vres.qp.size = val[1] - val[0] + 1; - sc->vres.cq.start = val[2]; - sc->vres.cq.size = val[3] - val[2] + 1; - sc->vres.ocq.start = val[4]; - sc->vres.ocq.size = val[5] - val[4] + 1; - - param[0] = FW_PARAM_PFVF(SRQ_START); - param[1] = FW_PARAM_PFVF(SRQ_END); - param[2] = FW_PARAM_DEV(MAXORDIRD_QP); - param[3] = FW_PARAM_DEV(MAXIRD_ADAPTER); - rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 4, param, val); + sc->vres.rq.start = val[0]; + sc->vres.rq.size = val[1] - val[0] + 1; + sc->vres.qp.start = val[2]; + sc->vres.qp.size = val[3] - val[2] + 1; + sc->vres.cq.start = val[4]; + sc->vres.cq.size = val[5] - val[4] + 1; + + param[0] = FW_PARAM_PFVF(OCQ_START); + param[1] = FW_PARAM_PFVF(OCQ_END); + param[2] = FW_PARAM_PFVF(SRQ_START); + param[3] = FW_PARAM_PFVF(SRQ_END); + param[4] = FW_PARAM_DEV(MAXORDIRD_QP); + param[5] = FW_PARAM_DEV(MAXIRD_ADAPTER); + rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val); if (rc != 0) { device_printf(sc->dev, - "failed to query RDMA parameters(3): %d.\n", rc); + "failed to query RDMA parameters(2): %d.\n", rc); return (rc); } - sc->vres.srq.start = val[0]; - sc->vres.srq.size = val[1] - val[0] + 1; - sc->params.max_ordird_qp = val[2]; - sc->params.max_ird_adapter = val[3]; + sc->vres.ocq.start = val[0]; + sc->vres.ocq.size = val[1] - val[0] + 1; + sc->vres.srq.start = val[2]; + sc->vres.srq.size = val[3] - val[2] + 1; + sc->params.max_ordird_qp = val[4]; + sc->params.max_ird_adapter = val[5]; } if (sc->iscsicaps) { param[0] = FW_PARAM_PFVF(ISCSI_START); @@ -7892,6 +7908,9 @@ t4_sysctls(struct adapter *sc) SYSCTL_ADD_INT(ctx, children, OID_AUTO, "dflags", CTLFLAG_RW, &sc->debug_flags, 0, "flags to enable runtime debugging"); + SYSCTL_ADD_INT(ctx, children, OID_AUTO, "iflags", CTLFLAG_RW, + &sc->intr_flags, 0, "flags for the slow interrupt handler"); + SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "tp_version", CTLFLAG_RD, sc->tp_version, 0, "TP microcode version"); @@ -8988,7 +9007,7 @@ sysctl_requested_fec(SYSCTL_HANDLER_ARGS) struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; int rc; - int8_t old; + int8_t old = lc->requested_fec; if (req->newptr == NULL) { struct sbuf *sb; @@ -8997,16 +9016,15 @@ sysctl_requested_fec(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); - sbuf_printf(sb, "%b", lc->requested_fec, t4_fec_bits); + sbuf_printf(sb, "%b", old, t4_fec_bits); rc = sbuf_finish(sb); sbuf_delete(sb); } else { char s[8]; int n; - snprintf(s, sizeof(s), "%d", - lc->requested_fec == FEC_AUTO ? -1 : - lc->requested_fec & (M_FW_PORT_CAP32_FEC | FEC_MODULE)); + snprintf(s, sizeof(s), "%d", old == FEC_AUTO ? -1 : + old & (M_FW_PORT_CAP32_FEC | FEC_MODULE)); rc = sysctl_handle_string(oidp, s, sizeof(s), req); if (rc != 0) @@ -9023,7 +9041,10 @@ sysctl_requested_fec(SYSCTL_HANDLER_ARGS) if (rc) return (rc); PORT_LOCK(pi); - old = lc->requested_fec; + if (lc->requested_fec != old) { + rc = EBUSY; + goto done; + } if (n == FEC_AUTO) lc->requested_fec = FEC_AUTO; else if (n == 0 || n == FEC_NONE) @@ -12984,6 +13005,9 @@ clear_stats(struct adapter *sc, u_int port_id) counter_u64_zero(ofld_txq->tx_iscsi_pdus); counter_u64_zero(ofld_txq->tx_iscsi_octets); counter_u64_zero(ofld_txq->tx_iscsi_iso_wrs); + counter_u64_zero(ofld_txq->tx_nvme_pdus); + counter_u64_zero(ofld_txq->tx_nvme_octets); + counter_u64_zero(ofld_txq->tx_nvme_iso_wrs); counter_u64_zero(ofld_txq->tx_aio_jobs); counter_u64_zero(ofld_txq->tx_aio_octets); counter_u64_zero(ofld_txq->tx_toe_tls_records); @@ -13003,6 +13027,22 @@ clear_stats(struct adapter *sc, u_int port_id) ofld_rxq->rx_iscsi_ddp_octets = 0; ofld_rxq->rx_iscsi_fl_pdus = 0; ofld_rxq->rx_iscsi_fl_octets = 0; + counter_u64_zero( + ofld_rxq->rx_nvme_ddp_setup_ok); + counter_u64_zero( + ofld_rxq->rx_nvme_ddp_setup_no_stag); + counter_u64_zero( + ofld_rxq->rx_nvme_ddp_setup_error); + counter_u64_zero(ofld_rxq->rx_nvme_ddp_pdus); + counter_u64_zero(ofld_rxq->rx_nvme_ddp_octets); + counter_u64_zero(ofld_rxq->rx_nvme_fl_pdus); + counter_u64_zero(ofld_rxq->rx_nvme_fl_octets); + counter_u64_zero( + ofld_rxq->rx_nvme_invalid_headers); + counter_u64_zero( + ofld_rxq->rx_nvme_header_digest_errors); + counter_u64_zero( + ofld_rxq->rx_nvme_data_digest_errors); ofld_rxq->rx_aio_ddp_jobs = 0; ofld_rxq->rx_aio_ddp_octets = 0; ofld_rxq->rx_toe_tls_records = 0; @@ -13409,11 +13449,16 @@ toe_capability(struct vi_info *vi, bool enable) ("%s: TOM activated but flag not set", __func__)); } - /* Activate iWARP and iSCSI too, if the modules are loaded. */ + /* + * Activate iWARP, iSCSI, and NVMe too, if the modules + * are loaded. + */ if (!uld_active(sc, ULD_IWARP)) (void) t4_activate_uld(sc, ULD_IWARP); if (!uld_active(sc, ULD_ISCSI)) (void) t4_activate_uld(sc, ULD_ISCSI); + if (!uld_active(sc, ULD_NVME)) + (void) t4_activate_uld(sc, ULD_NVME); if (pi->uld_vis++ == 0) setbit(&sc->offload_map, pi->port_id); @@ -13694,6 +13739,9 @@ tweak_tunables(void) FW_CAPS_CONFIG_ISCSI_T10DIF; } + if (t4_nvmecaps_allowed == -1) + t4_nvmecaps_allowed = FW_CAPS_CONFIG_NVME_TCP; + if (t4_tmr_idx_ofld < 0 || t4_tmr_idx_ofld >= SGE_NTIMERS) t4_tmr_idx_ofld = TMR_IDX_OFLD; @@ -13705,6 +13753,9 @@ tweak_tunables(void) if (t4_iscsicaps_allowed == -1) t4_iscsicaps_allowed = 0; + + if (t4_nvmecaps_allowed == -1) + t4_nvmecaps_allowed = 0; #endif #ifdef DEV_NETMAP diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c index 2f9cb1a4ebb5..e9754ace27c2 100644 --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -852,6 +852,11 @@ t4_tweak_chip_settings(struct adapter *sc) /* We use multiple DDP page sizes both in plain-TOE and ISCSI modes. */ m = v = F_TDDPTAGTCB | F_ISCSITAGTCB; + if (sc->nvmecaps != 0) { + /* Request DDP status bit for NVMe PDU completions. */ + m |= F_NVME_TCP_DDP_VAL_EN; + v |= F_NVME_TCP_DDP_VAL_EN; + } t4_set_reg_field(sc, A_ULP_RX_CTL, m, v); m = V_INDICATESIZE(M_INDICATESIZE) | F_REARMDDPOFFSET | @@ -1335,7 +1340,6 @@ t4_intr_err(void *arg) { struct adapter *sc = arg; uint32_t v; - const bool verbose = (sc->debug_flags & DF_VERBOSE_SLOWINTR) != 0; if (atomic_load_int(&sc->error_flags) & ADAP_FATAL_ERR) return; @@ -1346,7 +1350,7 @@ t4_intr_err(void *arg) t4_write_reg(sc, MYPF_REG(A_PL_PF_INT_CAUSE), v); } - if (t4_slow_intr_handler(sc, verbose)) + if (t4_slow_intr_handler(sc, sc->intr_flags)) t4_fatal_err(sc, false); } @@ -4170,6 +4174,20 @@ alloc_ofld_rxq(struct vi_info *vi, struct sge_ofld_rxq *ofld_rxq, int idx, ofld_rxq->rx_iscsi_ddp_setup_ok = counter_u64_alloc(M_WAITOK); ofld_rxq->rx_iscsi_ddp_setup_error = counter_u64_alloc(M_WAITOK); + ofld_rxq->rx_nvme_ddp_setup_ok = counter_u64_alloc(M_WAITOK); + ofld_rxq->rx_nvme_ddp_setup_no_stag = + counter_u64_alloc(M_WAITOK); + ofld_rxq->rx_nvme_ddp_setup_error = + counter_u64_alloc(M_WAITOK); + ofld_rxq->rx_nvme_ddp_octets = counter_u64_alloc(M_WAITOK); + ofld_rxq->rx_nvme_ddp_pdus = counter_u64_alloc(M_WAITOK); + ofld_rxq->rx_nvme_fl_octets = counter_u64_alloc(M_WAITOK); + ofld_rxq->rx_nvme_fl_pdus = counter_u64_alloc(M_WAITOK); + ofld_rxq->rx_nvme_invalid_headers = counter_u64_alloc(M_WAITOK); + ofld_rxq->rx_nvme_header_digest_errors = + counter_u64_alloc(M_WAITOK); + ofld_rxq->rx_nvme_data_digest_errors = + counter_u64_alloc(M_WAITOK); ofld_rxq->ddp_buffer_alloc = counter_u64_alloc(M_WAITOK); ofld_rxq->ddp_buffer_reuse = counter_u64_alloc(M_WAITOK); ofld_rxq->ddp_buffer_free = counter_u64_alloc(M_WAITOK); @@ -4207,6 +4225,16 @@ free_ofld_rxq(struct vi_info *vi, struct sge_ofld_rxq *ofld_rxq) MPASS(!(ofld_rxq->iq.flags & IQ_SW_ALLOCATED)); counter_u64_free(ofld_rxq->rx_iscsi_ddp_setup_ok); counter_u64_free(ofld_rxq->rx_iscsi_ddp_setup_error); + counter_u64_free(ofld_rxq->rx_nvme_ddp_setup_ok); + counter_u64_free(ofld_rxq->rx_nvme_ddp_setup_no_stag); + counter_u64_free(ofld_rxq->rx_nvme_ddp_setup_error); + counter_u64_free(ofld_rxq->rx_nvme_ddp_octets); + counter_u64_free(ofld_rxq->rx_nvme_ddp_pdus); + counter_u64_free(ofld_rxq->rx_nvme_fl_octets); + counter_u64_free(ofld_rxq->rx_nvme_fl_pdus); + counter_u64_free(ofld_rxq->rx_nvme_invalid_headers); + counter_u64_free(ofld_rxq->rx_nvme_header_digest_errors); + counter_u64_free(ofld_rxq->rx_nvme_data_digest_errors); counter_u64_free(ofld_rxq->ddp_buffer_alloc); counter_u64_free(ofld_rxq->ddp_buffer_reuse); counter_u64_free(ofld_rxq->ddp_buffer_free); @@ -4218,12 +4246,12 @@ static void add_ofld_rxq_sysctls(struct sysctl_ctx_list *ctx, struct sysctl_oid *oid, struct sge_ofld_rxq *ofld_rxq) { - struct sysctl_oid_list *children; + struct sysctl_oid_list *children, *top; if (ctx == NULL || oid == NULL) return; - children = SYSCTL_CHILDREN(oid); + top = children = SYSCTL_CHILDREN(oid); SYSCTL_ADD_U64(ctx, children, OID_AUTO, "rx_aio_ddp_jobs", CTLFLAG_RD, &ofld_rxq->rx_aio_ddp_jobs, 0, "# of aio_read(2) jobs completed via DDP"); @@ -4280,6 +4308,41 @@ add_ofld_rxq_sysctls(struct sysctl_ctx_list *ctx, struct sysctl_oid *oid, SYSCTL_ADD_U64(ctx, children, OID_AUTO, "data_digest_errors", CTLFLAG_RD, &ofld_rxq->rx_iscsi_data_digest_errors, 0, "# of PDUs with invalid data digests"); + + oid = SYSCTL_ADD_NODE(ctx, top, OID_AUTO, "nvme", + CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "TOE NVMe statistics"); + children = SYSCTL_CHILDREN(oid); + + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "ddp_setup_ok", + CTLFLAG_RD, &ofld_rxq->rx_nvme_ddp_setup_ok, + "# of times DDP buffer was setup successfully"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "ddp_setup_no_stag", + CTLFLAG_RD, &ofld_rxq->rx_nvme_ddp_setup_no_stag, + "# of times STAG was not available for DDP buffer setup"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "ddp_setup_error", + CTLFLAG_RD, &ofld_rxq->rx_nvme_ddp_setup_error, + "# of times DDP buffer setup failed"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "ddp_octets", + CTLFLAG_RD, &ofld_rxq->rx_nvme_ddp_octets, + "# of octets placed directly"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "ddp_pdus", + CTLFLAG_RD, &ofld_rxq->rx_nvme_ddp_pdus, + "# of PDUs with data placed directly"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "fl_octets", + CTLFLAG_RD, &ofld_rxq->rx_nvme_fl_octets, + "# of data octets delivered in freelist"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "fl_pdus", + CTLFLAG_RD, &ofld_rxq->rx_nvme_fl_pdus, + "# of PDUs with data delivered in freelist"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "invalid_headers", + CTLFLAG_RD, &ofld_rxq->rx_nvme_invalid_headers, + "# of PDUs with invalid header field"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "header_digest_errors", + CTLFLAG_RD, &ofld_rxq->rx_nvme_header_digest_errors, + "# of PDUs with invalid header digests"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "data_digest_errors", + CTLFLAG_RD, &ofld_rxq->rx_nvme_data_digest_errors, + "# of PDUs with invalid data digests"); } #endif @@ -4957,6 +5020,9 @@ alloc_ofld_txq(struct vi_info *vi, struct sge_ofld_txq *ofld_txq, int idx) ofld_txq->tx_iscsi_pdus = counter_u64_alloc(M_WAITOK); ofld_txq->tx_iscsi_octets = counter_u64_alloc(M_WAITOK); ofld_txq->tx_iscsi_iso_wrs = counter_u64_alloc(M_WAITOK); + ofld_txq->tx_nvme_pdus = counter_u64_alloc(M_WAITOK); + ofld_txq->tx_nvme_octets = counter_u64_alloc(M_WAITOK); + ofld_txq->tx_nvme_iso_wrs = counter_u64_alloc(M_WAITOK); ofld_txq->tx_aio_jobs = counter_u64_alloc(M_WAITOK); ofld_txq->tx_aio_octets = counter_u64_alloc(M_WAITOK); ofld_txq->tx_toe_tls_records = counter_u64_alloc(M_WAITOK); @@ -5000,6 +5066,9 @@ free_ofld_txq(struct vi_info *vi, struct sge_ofld_txq *ofld_txq) counter_u64_free(ofld_txq->tx_iscsi_pdus); counter_u64_free(ofld_txq->tx_iscsi_octets); counter_u64_free(ofld_txq->tx_iscsi_iso_wrs); + counter_u64_free(ofld_txq->tx_nvme_pdus); + counter_u64_free(ofld_txq->tx_nvme_octets); + counter_u64_free(ofld_txq->tx_nvme_iso_wrs); counter_u64_free(ofld_txq->tx_aio_jobs); counter_u64_free(ofld_txq->tx_aio_octets); counter_u64_free(ofld_txq->tx_toe_tls_records); @@ -5029,6 +5098,15 @@ add_ofld_txq_sysctls(struct sysctl_ctx_list *ctx, struct sysctl_oid *oid, SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "tx_iscsi_iso_wrs", CTLFLAG_RD, &ofld_txq->tx_iscsi_iso_wrs, "# of iSCSI segmentation offload work requests"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "tx_nvme_pdus", + CTLFLAG_RD, &ofld_txq->tx_nvme_pdus, + "# of NVMe PDUs transmitted"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "tx_nvme_octets", + CTLFLAG_RD, &ofld_txq->tx_nvme_octets, + "# of payload octets in transmitted NVMe PDUs"); + SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "tx_nvme_iso_wrs", + CTLFLAG_RD, &ofld_txq->tx_nvme_iso_wrs, + "# of NVMe segmentation offload work requests"); SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "tx_aio_jobs", CTLFLAG_RD, &ofld_txq->tx_aio_jobs, "# of zero-copy aio_write(2) jobs transmitted"); diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c index 84e31efa8b58..5c39ae5fa8f3 100644 --- a/sys/dev/cxgbe/tom/t4_cpl_io.c +++ b/sys/dev/cxgbe/tom/t4_cpl_io.c @@ -66,6 +66,7 @@ #include <vm/vm_page.h> #include <dev/iscsi/iscsi_proto.h> +#include <dev/nvmf/nvmf_proto.h> #include "common/common.h" #include "common/t4_msg.h" @@ -495,6 +496,9 @@ t4_close_conn(struct adapter *sc, struct toepcb *toep) #define MIN_ISO_TX_CREDITS (howmany(sizeof(struct cpl_tx_data_iso), 16)) #define MIN_TX_CREDITS(iso) \ (MIN_OFLD_TX_CREDITS + ((iso) ? MIN_ISO_TX_CREDITS : 0)) +#define MIN_OFLD_TX_V2_CREDITS (howmany(sizeof(struct fw_ofld_tx_data_v2_wr) + 1, 16)) +#define MIN_TX_V2_CREDITS(iso) \ + (MIN_OFLD_TX_V2_CREDITS + ((iso) ? MIN_ISO_TX_CREDITS : 0)) _Static_assert(MAX_OFLD_TX_CREDITS <= MAX_OFLD_TX_SDESC_CREDITS, "MAX_OFLD_TX_SDESC_CREDITS too small"); @@ -542,6 +546,46 @@ max_dsgl_nsegs(int tx_credits, int iso) return (nseg); } +/* Maximum amount of immediate data we could stuff in a WR */ +static inline int +max_imm_payload_v2(int tx_credits, int iso) +{ + const int iso_cpl_size = iso ? sizeof(struct cpl_tx_data_iso) : 0; + + KASSERT(tx_credits >= 0 && + tx_credits <= MAX_OFLD_TX_CREDITS, + ("%s: %d credits", __func__, tx_credits)); + + if (tx_credits < MIN_TX_V2_CREDITS(iso)) + return (0); + + return (tx_credits * 16 - sizeof(struct fw_ofld_tx_data_v2_wr) - + iso_cpl_size); +} + +/* Maximum number of SGL entries we could stuff in a WR */ +static inline int +max_dsgl_nsegs_v2(int tx_credits, int iso, int imm_payload) +{ + int nseg = 1; /* ulptx_sgl has room for 1, rest ulp_tx_sge_pair */ + int sge_pair_credits = tx_credits - MIN_TX_V2_CREDITS(iso); + + KASSERT(tx_credits >= 0 && + tx_credits <= MAX_OFLD_TX_CREDITS, + ("%s: %d credits", __func__, tx_credits)); + + if (tx_credits < MIN_TX_V2_CREDITS(iso) || + sge_pair_credits <= howmany(imm_payload, 16)) + return (0); + sge_pair_credits -= howmany(imm_payload, 16); + + nseg += 2 * (sge_pair_credits * 16 / 24); + if ((sge_pair_credits * 16) % 24 == 16) + nseg++; + + return (nseg); +} + static inline void write_tx_wr(void *dst, struct toepcb *toep, int fw_wr_opcode, unsigned int immdlen, unsigned int plen, uint8_t credits, int shove, @@ -569,6 +613,35 @@ write_tx_wr(void *dst, struct toepcb *toep, int fw_wr_opcode, } } +static inline void +write_tx_v2_wr(void *dst, struct toepcb *toep, int fw_wr_opcode, + unsigned int immdlen, unsigned int plen, uint8_t credits, int shove, + int ulp_submode) +{ + struct fw_ofld_tx_data_v2_wr *txwr = dst; + uint32_t flags; + + memset(txwr, 0, sizeof(*txwr)); + txwr->op_to_immdlen = htobe32(V_WR_OP(fw_wr_opcode) | + V_FW_WR_IMMDLEN(immdlen)); + txwr->flowid_len16 = htobe32(V_FW_WR_FLOWID(toep->tid) | + V_FW_WR_LEN16(credits)); + txwr->plen = htobe32(plen); + flags = V_TX_ULP_MODE(ULP_MODE_NVMET) | V_TX_ULP_SUBMODE(ulp_submode) | + V_TX_URG(0) | V_TX_SHOVE(shove); + + if (toep->params.tx_align > 0) { + if (plen < 2 * toep->params.emss) + flags |= F_FW_OFLD_TX_DATA_WR_LSODISABLE; + else + flags |= F_FW_OFLD_TX_DATA_WR_ALIGNPLD | + (toep->params.nagle == 0 ? 0 : + F_FW_OFLD_TX_DATA_WR_ALIGNPLDSHOVE); + } + + txwr->lsodisable_to_flags = htobe32(flags); +} + /* * Generate a DSGL from a starting mbuf. The total number of segments and the * maximum segments in any one mbuf are provided. @@ -982,8 +1055,8 @@ rqdrop_locked(struct mbufq *q, int plen) #define ULP_ISO G_TX_ULP_SUBMODE(F_FW_ISCSI_TX_DATA_WR_ULPSUBMODE_ISO) static void -write_tx_data_iso(void *dst, u_int ulp_submode, uint8_t flags, uint16_t mss, - int len, int npdu) +write_iscsi_tx_data_iso(void *dst, u_int ulp_submode, uint8_t flags, + uint16_t mss, int len, int npdu) { struct cpl_tx_data_iso *cpl; unsigned int burst_size; @@ -1147,7 +1220,7 @@ write_iscsi_mbuf_wr(struct toepcb *toep, struct mbuf *sndptr) adjusted_plen, credits, shove, ulp_submode | ULP_ISO); cpl_iso = (struct cpl_tx_data_iso *)(txwr + 1); MPASS(plen == sndptr->m_pkthdr.len); - write_tx_data_iso(cpl_iso, ulp_submode, + write_iscsi_tx_data_iso(cpl_iso, ulp_submode, mbuf_iscsi_iso_flags(sndptr), iso_mss, plen, npdu); p = cpl_iso + 1; } else { @@ -1183,21 +1256,269 @@ write_iscsi_mbuf_wr(struct toepcb *toep, struct mbuf *sndptr) return (wr); } +static void +write_nvme_tx_data_iso(void *dst, u_int ulp_submode, u_int iso_type, + uint16_t mss, int len, int npdu, int pdo) +{ + struct cpl_t7_tx_data_iso *cpl; + unsigned int burst_size; + + /* + * TODO: Need to figure out how the LAST_PDU and SUCCESS flags + * are handled. + * + * - Does len need padding bytes? (If so, does padding need + * to be in DSGL input?) + * + * - burst always 0? + */ + burst_size = 0; + + cpl = (struct cpl_t7_tx_data_iso *)dst; + cpl->op_to_scsi = htonl(V_CPL_T7_TX_DATA_ISO_OPCODE(CPL_TX_DATA_ISO) | + V_CPL_T7_TX_DATA_ISO_FIRST(1) | + V_CPL_T7_TX_DATA_ISO_LAST(1) | + V_CPL_T7_TX_DATA_ISO_CPLHDRLEN(0) | + V_CPL_T7_TX_DATA_ISO_HDRCRC(!!(ulp_submode & ULP_CRC_HEADER)) | + V_CPL_T7_TX_DATA_ISO_PLDCRC(!!(ulp_submode & ULP_CRC_DATA)) | + V_CPL_T7_TX_DATA_ISO_IMMEDIATE(0) | + V_CPL_T7_TX_DATA_ISO_SCSI(iso_type)); + + cpl->nvme_tcp_pkd = F_CPL_T7_TX_DATA_ISO_NVME_TCP; + cpl->ahs = 0; + cpl->mpdu = htons(DIV_ROUND_UP(mss, 4)); + cpl->burst = htonl(DIV_ROUND_UP(burst_size, 4)); + cpl->size = htonl(len); + cpl->num_pi_bytes_seglen_offset = htonl(0); + cpl->datasn_offset = htonl(0); + cpl->buffer_offset = htonl(0); + cpl->pdo_pkd = pdo; +} + +static struct wrqe * +write_nvme_mbuf_wr(struct toepcb *toep, struct mbuf *sndptr) +{ + struct mbuf *m; + const struct nvme_tcp_common_pdu_hdr *hdr; + struct fw_v2_nvmet_tx_data_wr *txwr; + struct cpl_tx_data_iso *cpl_iso; + void *p; + struct wrqe *wr; + u_int plen, nsegs, credits, max_imm, max_nsegs, max_nsegs_1mbuf; + u_int adjusted_plen, imm_data, ulp_submode; + struct inpcb *inp = toep->inp; + struct tcpcb *tp = intotcpcb(inp); + int tx_credits, shove, npdu, wr_len; + uint16_t iso_mss; + bool iso, nomap_mbuf_seen; + + M_ASSERTPKTHDR(sndptr); + + tx_credits = min(toep->tx_credits, MAX_OFLD_TX_CREDITS); + if (mbuf_raw_wr(sndptr)) { + plen = sndptr->m_pkthdr.len; + KASSERT(plen <= SGE_MAX_WR_LEN, + ("raw WR len %u is greater than max WR len", plen)); + if (plen > tx_credits * 16) + return (NULL); + + wr = alloc_wrqe(roundup2(plen, 16), &toep->ofld_txq->wrq); + if (__predict_false(wr == NULL)) + return (NULL); + + m_copydata(sndptr, 0, plen, wrtod(wr)); + return (wr); + } + + /* + * The first mbuf is the PDU header that is always sent as + * immediate data. + */ + imm_data = sndptr->m_len; + + iso = mbuf_iscsi_iso(sndptr); + max_imm = max_imm_payload_v2(tx_credits, iso); + + /* + * Not enough credits for the PDU header. + */ + if (imm_data > max_imm) + return (NULL); + + max_nsegs = max_dsgl_nsegs_v2(tx_credits, iso, imm_data); + iso_mss = mbuf_iscsi_iso_mss(sndptr); + + plen = imm_data; + nsegs = 0; + max_nsegs_1mbuf = 0; /* max # of SGL segments in any one mbuf */ + nomap_mbuf_seen = false; + for (m = sndptr->m_next; m != NULL; m = m->m_next) { + int n; + + if (m->m_flags & M_EXTPG) + n = sglist_count_mbuf_epg(m, mtod(m, vm_offset_t), + m->m_len); + else + n = sglist_count(mtod(m, void *), m->m_len); + + nsegs += n; + plen += m->m_len; + + /* + * This mbuf would send us _over_ the nsegs limit. + * Suspend tx because the PDU can't be sent out. + */ + if ((nomap_mbuf_seen || plen > max_imm) && nsegs > max_nsegs) + return (NULL); + + if (m->m_flags & M_EXTPG) + nomap_mbuf_seen = true; + if (max_nsegs_1mbuf < n) + max_nsegs_1mbuf = n; + } + + if (__predict_false(toep->flags & TPF_FIN_SENT)) + panic("%s: excess tx.", __func__); + + /* + * We have a PDU to send. All of it goes out in one WR so 'm' + * is NULL. A PDU's length is always a multiple of 4. + */ + MPASS(m == NULL); + MPASS((plen & 3) == 0); + MPASS(sndptr->m_pkthdr.len == plen); + + shove = !(tp->t_flags & TF_MORETOCOME); + + /* + * plen doesn't include header digests, padding, and data + * digests which are generated and inserted in the right + * places by the TOE, but they do occupy TCP sequence space + * and need to be accounted for. + * + * To determine the overhead, check the PDU header in sndptr. + * Note that only certain PDU types can use digests and + * padding, and PDO accounts for all but the data digests for + * those PDUs. + */ + MPASS((sndptr->m_flags & M_EXTPG) == 0); + ulp_submode = mbuf_ulp_submode(sndptr); + hdr = mtod(sndptr, const void *); + switch (hdr->pdu_type) { + case NVME_TCP_PDU_TYPE_H2C_TERM_REQ: + case NVME_TCP_PDU_TYPE_C2H_TERM_REQ: + MPASS(ulp_submode == 0); + MPASS(!iso); + break; + case NVME_TCP_PDU_TYPE_CAPSULE_RESP: + case NVME_TCP_PDU_TYPE_R2T: + MPASS((ulp_submode & ULP_CRC_DATA) == 0); + /* FALLTHROUGH */ + case NVME_TCP_PDU_TYPE_CAPSULE_CMD: + MPASS(!iso); + break; + case NVME_TCP_PDU_TYPE_H2C_DATA: + case NVME_TCP_PDU_TYPE_C2H_DATA: + if (le32toh(hdr->plen) + ((ulp_submode & ULP_CRC_DATA) != 0 ? + sizeof(uint32_t) : 0) == plen) + MPASS(!iso); + break; + default: + __assert_unreachable(); + } + + if (iso) { + npdu = howmany(plen - hdr->hlen, iso_mss); + adjusted_plen = hdr->pdo * npdu + (plen - hdr->hlen); + if ((ulp_submode & ULP_CRC_DATA) != 0) + adjusted_plen += npdu * sizeof(uint32_t); + } else { + npdu = 1; + adjusted_plen = le32toh(hdr->plen); + } + wr_len = sizeof(*txwr); + if (iso) + wr_len += sizeof(struct cpl_tx_data_iso); + if (plen <= max_imm && !nomap_mbuf_seen) { + /* Immediate data tx for full PDU */ + imm_data = plen; + wr_len += plen; + nsegs = 0; + } else { + /* DSGL tx for PDU data */ + wr_len += roundup2(imm_data, 16); + wr_len += sizeof(struct ulptx_sgl) + + ((3 * (nsegs - 1)) / 2 + ((nsegs - 1) & 1)) * 8; + } + + wr = alloc_wrqe(roundup2(wr_len, 16), &toep->ofld_txq->wrq); + if (wr == NULL) { + /* XXX: how will we recover from this? */ + return (NULL); + } + txwr = wrtod(wr); + credits = howmany(wr->wr_len, 16); + + if (iso) { + write_tx_v2_wr(txwr, toep, FW_V2_NVMET_TX_DATA_WR, + imm_data + sizeof(struct cpl_tx_data_iso), + adjusted_plen, credits, shove, ulp_submode | ULP_ISO); + cpl_iso = (struct cpl_tx_data_iso *)(txwr + 1); + MPASS(plen == sndptr->m_pkthdr.len); + write_nvme_tx_data_iso(cpl_iso, ulp_submode, + (hdr->pdu_type & 0x1) == 0 ? 1 : 2, iso_mss, plen, npdu, + hdr->pdo); + p = cpl_iso + 1; + } else { + write_tx_v2_wr(txwr, toep, FW_V2_NVMET_TX_DATA_WR, imm_data, + adjusted_plen, credits, shove, ulp_submode); + p = txwr + 1; + } + + /* PDU header (and immediate data payload). */ + m_copydata(sndptr, 0, imm_data, p); + if (nsegs != 0) { + p = roundup2((char *)p + imm_data, 16); + write_tx_sgl(p, sndptr->m_next, NULL, nsegs, max_nsegs_1mbuf); + if (wr_len & 0xf) { + uint64_t *pad = (uint64_t *)((uintptr_t)txwr + wr_len); + *pad = 0; + } + } + + KASSERT(toep->tx_credits >= credits, + ("%s: not enough credits: credits %u " + "toep->tx_credits %u tx_credits %u nsegs %u " + "max_nsegs %u iso %d", __func__, credits, + toep->tx_credits, tx_credits, nsegs, max_nsegs, iso)); + + tp->snd_nxt += adjusted_plen; + tp->snd_max += adjusted_plen; + + counter_u64_add(toep->ofld_txq->tx_nvme_pdus, npdu); + counter_u64_add(toep->ofld_txq->tx_nvme_octets, plen); + if (iso) + counter_u64_add(toep->ofld_txq->tx_nvme_iso_wrs, 1); + + return (wr); +} + void t4_push_pdus(struct adapter *sc, struct toepcb *toep, int drop) { struct mbuf *sndptr, *m; struct fw_wr_hdr *wrhdr; struct wrqe *wr; - u_int plen, credits; + u_int plen, credits, mode; struct inpcb *inp = toep->inp; struct ofld_tx_sdesc *txsd = &toep->txsd[toep->txsd_pidx]; struct mbufq *pduq = &toep->ulp_pduq; INP_WLOCK_ASSERT(inp); + mode = ulp_mode(toep); KASSERT(toep->flags & TPF_FLOWC_WR_SENT, ("%s: flowc_wr not sent for tid %u.", __func__, toep->tid)); - KASSERT(ulp_mode(toep) == ULP_MODE_ISCSI, + KASSERT(mode == ULP_MODE_ISCSI || mode == ULP_MODE_NVMET, ("%s: ulp_mode %u for toep %p", __func__, ulp_mode(toep), toep)); if (__predict_false(toep->flags & TPF_ABORT_SHUTDOWN)) @@ -1230,7 +1551,7 @@ t4_push_pdus(struct adapter *sc, struct toepcb *toep, int drop) if (sbu > 0) { /* * The data transmitted before the - * tid's ULP mode changed to ISCSI is + * tid's ULP mode changed to ISCSI/NVMET is * still in so_snd. Incoming credits * should account for so_snd first. */ @@ -1243,7 +1564,10 @@ t4_push_pdus(struct adapter *sc, struct toepcb *toep, int drop) } while ((sndptr = mbufq_first(pduq)) != NULL) { - wr = write_iscsi_mbuf_wr(toep, sndptr); + if (mode == ULP_MODE_ISCSI) + wr = write_iscsi_mbuf_wr(toep, sndptr); + else + wr = write_nvme_mbuf_wr(toep, sndptr); if (wr == NULL) { toep->flags |= TPF_TX_SUSPENDED; return; @@ -1302,7 +1626,8 @@ static inline void t4_push_data(struct adapter *sc, struct toepcb *toep, int drop) { - if (ulp_mode(toep) == ULP_MODE_ISCSI) + if (ulp_mode(toep) == ULP_MODE_ISCSI || + ulp_mode(toep) == ULP_MODE_NVMET) t4_push_pdus(sc, toep, drop); else if (toep->flags & TPF_KTLS) t4_push_ktls(sc, toep, drop); @@ -1462,7 +1787,8 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) socantrcvmore(so); if (ulp_mode(toep) == ULP_MODE_RDMA || - (ulp_mode(toep) == ULP_MODE_ISCSI && chip_id(sc) >= CHELSIO_T6)) { + (ulp_mode(toep) == ULP_MODE_ISCSI && chip_id(sc) >= CHELSIO_T6) || + ulp_mode(toep) == ULP_MODE_NVMET) { /* * There might be data received via DDP before the FIN * not reported to the driver. Just assume the @@ -2008,7 +2334,8 @@ do_fw4_ack(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) SOCKBUF_LOCK(sb); sbu = sbused(sb); - if (ulp_mode(toep) == ULP_MODE_ISCSI) { + if (ulp_mode(toep) == ULP_MODE_ISCSI || + ulp_mode(toep) == ULP_MODE_NVMET) { if (__predict_false(sbu > 0)) { /* * The data transmitted before the diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c index 53a945f8b4cc..8dfffd465345 100644 --- a/sys/dev/cxgbe/tom/t4_tom.c +++ b/sys/dev/cxgbe/tom/t4_tom.c @@ -1990,8 +1990,10 @@ t4_tom_deactivate(struct adapter *sc) if (td == NULL) return (0); /* XXX. KASSERT? */ - if (uld_active(sc, ULD_IWARP) || uld_active(sc, ULD_ISCSI)) - return (EBUSY); /* both iWARP and iSCSI rely on the TOE. */ + /* These ULDs rely on the TOE. */ + if (uld_active(sc, ULD_IWARP) || uld_active(sc, ULD_ISCSI) || + uld_active(sc, ULD_NVME)) + return (EBUSY); if (sc->offload_map != 0) { for_each_port(sc, i) { diff --git a/sys/dev/dpaa2/dpaa2_ni.c b/sys/dev/dpaa2/dpaa2_ni.c index 698b440376e3..98a6c6047188 100644 --- a/sys/dev/dpaa2/dpaa2_ni.c +++ b/sys/dev/dpaa2/dpaa2_ni.c @@ -559,7 +559,8 @@ dpaa2_ni_attach(device_t dev) if_settransmitfn(ifp, dpaa2_ni_transmit); if_setqflushfn(ifp, dpaa2_ni_qflush); - if_setcapabilities(ifp, IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_JUMBO_MTU); + if_setcapabilities(ifp, IFCAP_VLAN_MTU | IFCAP_HWCSUM | + IFCAP_HWCSUM_IPV6 | IFCAP_JUMBO_MTU); if_setcapenable(ifp, if_getcapabilities(ifp)); DPAA2_CMD_INIT(&cmd); @@ -627,6 +628,12 @@ dpaa2_ni_attach(device_t dev) __func__, error); goto close_ni; } + error = dpaa2_ni_setup_if_caps(sc); + if (error) { + device_printf(dev, "%s: failed to setup interface capabilities: " + "error=%d\n", __func__, error); + goto close_ni; + } ether_ifattach(sc->ifp, sc->mac.addr); callout_init(&sc->mii_callout, 0); @@ -1569,8 +1576,7 @@ dpaa2_ni_setup_msi(struct dpaa2_ni_softc *sc) static int dpaa2_ni_setup_if_caps(struct dpaa2_ni_softc *sc) { - const bool en_rxcsum = if_getcapenable(sc->ifp) & IFCAP_RXCSUM; - const bool en_txcsum = if_getcapenable(sc->ifp) & IFCAP_TXCSUM; + bool en_rxcsum, en_txcsum; device_t pdev = device_get_parent(sc->dev); device_t dev = sc->dev; device_t child = dev; @@ -1582,6 +1588,17 @@ dpaa2_ni_setup_if_caps(struct dpaa2_ni_softc *sc) DPAA2_CMD_INIT(&cmd); + /* + * XXX-DSL: DPAA2 allows to validate L3/L4 checksums on reception and/or + * generate L3/L4 checksums on transmission without + * differentiating between IPv4/v6, i.e. enable for both + * protocols if requested. + */ + en_rxcsum = if_getcapenable(sc->ifp) & + (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6); + en_txcsum = if_getcapenable(sc->ifp) & + (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6); + error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token); if (error) { device_printf(dev, "%s: failed to open resource container: " @@ -1627,6 +1644,13 @@ dpaa2_ni_setup_if_caps(struct dpaa2_ni_softc *sc) goto close_ni; } + if (bootverbose) { + device_printf(dev, "%s: L3/L4 checksum validation %s\n", + __func__, en_rxcsum ? "enabled" : "disabled"); + device_printf(dev, "%s: L3/L4 checksum generation %s\n", + __func__, en_txcsum ? "enabled" : "disabled"); + } + (void)DPAA2_CMD_NI_CLOSE(dev, child, &cmd); (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); return (0); @@ -2574,13 +2598,27 @@ dpaa2_ni_ioctl(if_t ifp, u_long c, caddr_t data) break; case SIOCSIFCAP: changed = if_getcapenable(ifp) ^ ifr->ifr_reqcap; - if (changed & IFCAP_HWCSUM) { - if ((ifr->ifr_reqcap & changed) & IFCAP_HWCSUM) { - if_setcapenablebit(ifp, IFCAP_HWCSUM, 0); + if (changed & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) { + if ((ifr->ifr_reqcap & changed) & + (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) { + if_setcapenablebit(ifp, + IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6, 0); } else { - if_setcapenablebit(ifp, 0, IFCAP_HWCSUM); + if_setcapenablebit(ifp, 0, + IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6); } } + if (changed & (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6)) { + if ((ifr->ifr_reqcap & changed) & + (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6)) { + if_setcapenablebit(ifp, + IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6, 0); + } else { + if_setcapenablebit(ifp, 0, + IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6); + } + } + rc = dpaa2_ni_setup_if_caps(sc); if (rc) { printf("%s: failed to update iface capabilities: " diff --git a/sys/dev/drm2/drm_os_freebsd.h b/sys/dev/drm2/drm_os_freebsd.h index ec1042f8f0d4..ef417e950a62 100644 --- a/sys/dev/drm2/drm_os_freebsd.h +++ b/sys/dev/drm2/drm_os_freebsd.h @@ -158,7 +158,7 @@ typedef void irqreturn_t; #else #define DRM_MSG "WARNING! drm2 module is deprecated.\n" #endif -#define DRM_OBSOLETE(dev) gone_in_dev(dev, 13, DRM_MSG) +#define DRM_OBSOLETE(dev) gone_in_dev(dev, 16, DRM_MSG) #endif /* __arm__ */ /* DRM_READMEMORYBARRIER() prevents reordering of reads. diff --git a/sys/dev/e1000/e1000_82571.c b/sys/dev/e1000/e1000_82571.c index e8970adf996f..650169663f56 100644 --- a/sys/dev/e1000/e1000_82571.c +++ b/sys/dev/e1000/e1000_82571.c @@ -1118,7 +1118,8 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) case e1000_82574: case e1000_82583: reg_data = E1000_READ_REG(hw, E1000_GCR); - reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; + /* 82574 Errata 25, 82583 Errata 12 */ + reg_data &= ~E1000_GCR_L1_ACT_WITHOUT_L0S_RX; E1000_WRITE_REG(hw, E1000_GCR, reg_data); break; default: diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index e3d839b828ed..02f4c431badd 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -3080,9 +3080,13 @@ em_reset(if_ctx_t ctx) case e1000_82573: pba = E1000_PBA_12K; /* 12K for Rx, 20K for Tx */ break; + /* 82574/82583: Total Packet Buffer is 40K */ case e1000_82574: case e1000_82583: - pba = E1000_PBA_20K; /* 20K for Rx, 20K for Tx */ + if (hw->mac.max_frame_size > 8192) + pba = E1000_PBA_22K; /* 22K for Rx, 18K for Tx */ + else + pba = E1000_PBA_32K; /* 32K for RX, 8K for Tx */ break; case e1000_ich8lan: pba = E1000_PBA_8K; @@ -4023,7 +4027,15 @@ em_if_vlan_register(if_ctx_t ctx, u16 vtag) bit = vtag & 0x1F; sc->shadow_vfta[index] |= (1 << bit); ++sc->num_vlans; - em_if_vlan_filter_write(sc); + if (!sc->vf_ifp) + em_if_vlan_filter_write(sc); + else + /* + * Physical funtion may reject registering VLAN + * but we have no way to inform the stack + * about that. + */ + e1000_vfta_set_vf(&sc->hw, vtag, true); } static void @@ -4036,7 +4048,10 @@ em_if_vlan_unregister(if_ctx_t ctx, u16 vtag) bit = vtag & 0x1F; sc->shadow_vfta[index] &= ~(1 << bit); --sc->num_vlans; - em_if_vlan_filter_write(sc); + if (!sc->vf_ifp) + em_if_vlan_filter_write(sc); + else + e1000_vfta_set_vf(&sc->hw, vtag, false); } static bool @@ -4094,22 +4109,15 @@ em_if_vlan_filter_write(struct e1000_softc *sc) { struct e1000_hw *hw = &sc->hw; - if (sc->vf_ifp) - return; + KASSERT(!sc->vf_ifp, ("VLAN filter write on VF\n")); /* Disable interrupts for lem(4) devices during the filter change */ if (hw->mac.type < em_mac_min) em_if_intr_disable(sc->ctx); for (int i = 0; i < EM_VFTA_SIZE; i++) - if (sc->shadow_vfta[i] != 0) { - /* XXXKB: incomplete VF support, we returned above */ - if (sc->vf_ifp) - e1000_vfta_set_vf(hw, sc->shadow_vfta[i], - true); - else - e1000_write_vfta(hw, i, sc->shadow_vfta[i]); - } + if (sc->shadow_vfta[i] != 0) + e1000_write_vfta(hw, i, sc->shadow_vfta[i]); /* Re-enable interrupts for lem-class devices */ if (hw->mac.type < em_mac_min) @@ -4124,8 +4132,10 @@ em_setup_vlan_hw_support(if_ctx_t ctx) if_t ifp = iflib_get_ifp(ctx); u32 reg; - /* XXXKB: Return early if we are a VF until VF decap and filter - * management is ready and tested. + /* + * Only PFs have control over VLAN HW filtering + * configuration. VFs have to act as if it's always + * enabled. */ if (sc->vf_ifp) return; diff --git a/sys/dev/fdt/simplebus.c b/sys/dev/fdt/simplebus.c index a301fb0f247c..3e77f13104ff 100644 --- a/sys/dev/fdt/simplebus.c +++ b/sys/dev/fdt/simplebus.c @@ -40,6 +40,9 @@ #include <dev/fdt/simplebus.h> +#include "pci_if.h" +#include "pcib_if.h" + /* * Bus interface. */ @@ -63,6 +66,21 @@ static const struct ofw_bus_devinfo *simplebus_get_devinfo(device_t bus, device_t child); /* + * PCI interface for MSI interrupts + */ +static pci_get_id_t simplebus_get_id; +static pci_alloc_msi_t simplebus_alloc_msi; + +/* + * PCIB interface + */ +static pcib_alloc_msi_t simplebus_pcib_alloc_msi; +static pcib_release_msi_t simplebus_pcib_release_msi; +static pcib_alloc_msix_t simplebus_pcib_alloc_msix; +static pcib_release_msix_t simplebus_pcib_release_msix; +static pcib_map_msi_t simplebus_pcib_map_msi; + +/* * Driver methods. */ static device_method_t simplebus_methods[] = { @@ -105,6 +123,17 @@ static device_method_t simplebus_methods[] = { DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), + /* PCI interface for MSI interrupts */ + DEVMETHOD(pci_get_id, simplebus_get_id), + DEVMETHOD(pci_alloc_msi, simplebus_alloc_msi), + + /* PCIB interface */ + DEVMETHOD(pcib_alloc_msi, simplebus_pcib_alloc_msi), + DEVMETHOD(pcib_release_msi, simplebus_pcib_release_msi), + DEVMETHOD(pcib_alloc_msix, simplebus_pcib_alloc_msix), + DEVMETHOD(pcib_release_msix, simplebus_pcib_release_msix), + DEVMETHOD(pcib_map_msi, simplebus_pcib_map_msi), + DEVMETHOD_END }; @@ -534,3 +563,108 @@ simplebus_print_child(device_t bus, device_t child) rv += bus_print_child_footer(bus, child); return (rv); } + +static int +simplebus_get_id(device_t dev, device_t child, enum pci_id_type type, + uintptr_t *id) +{ + phandle_t node, xref; + pcell_t *cells; + uintptr_t rid; + int error, ncells; + + if (type != PCI_ID_MSI) + return (EINVAL); + + node = ofw_bus_get_node(child); + error = ofw_bus_parse_xref_list_alloc(node, "msi-parent", "#msi-cells", + 0, &xref, &ncells, &cells); + if (error != 0) + return (error); + + rid = 0; + if (ncells > 0) + rid = cells[0]; + + *id = rid; + return (0); +} + +static int +simplebus_alloc_msi(device_t bus, device_t child, int *count) +{ + struct simplebus_devinfo *ndi; + struct resource_list_entry *rle; + int error, i, irq_count, *irqs; + + if (*count < 1) + return (EINVAL); + + ndi = device_get_ivars(child); + if (ndi == NULL) + return (ENXIO); + + /* Only MSI or non-MSI for now */ + rle = resource_list_find(&ndi->rl, SYS_RES_IRQ, 0); + if (rle != NULL && rle->res != NULL) + return (ENXIO); + + irq_count = *count; + irqs = mallocarray(irq_count, sizeof(int), M_DEVBUF, M_WAITOK | M_ZERO); + + error = PCIB_ALLOC_MSI(bus, child, irq_count, irq_count, irqs); + if (error != 0) + goto out; + + for (i = 0; i < irq_count; i++) { + error = bus_generic_rl_set_resource(bus, child, SYS_RES_IRQ, + i + 1, irqs[i], 1); + if (error != 0) + break; + } + + /* Clean up resources if something failed */ + if (error != 0) { + for (int j = 0; j < i; j++) { + bus_generic_rl_delete_resource(bus, child, SYS_RES_IRQ, + j + 1); + } + } +out: + free(irqs, M_DEVBUF); + return (error); +} + +static int +simplebus_pcib_alloc_msi(device_t dev, device_t child, int count, int maxcount, + int *irqs) +{ + return (PCIB_ALLOC_MSI(device_get_parent(dev), child, count, maxcount, + irqs)); +} + +static int +simplebus_pcib_release_msi(device_t dev, device_t child, int count, int *irqs) +{ + return (PCIB_RELEASE_MSI(device_get_parent(dev), child, count, irqs)); +} + +static int +simplebus_pcib_alloc_msix(device_t dev, device_t child, int *irq) +{ + return (PCIB_ALLOC_MSIX(device_get_parent(dev), child, irq)); +} + +static int +simplebus_pcib_release_msix(device_t dev, device_t child, int irq) +{ + return (PCIB_RELEASE_MSIX(device_get_parent(dev), child, irq)); +} + +static int +simplebus_pcib_map_msi(device_t dev, device_t child, int irq, uint64_t *addr, + uint32_t *data) +{ + return (PCIB_MAP_MSI(device_get_parent(dev), child, irq, addr, + data)); +} diff --git a/sys/dev/iicbus/iichid.c b/sys/dev/iicbus/iichid.c index 5ca3f1b84e48..430066bd8f52 100644 --- a/sys/dev/iicbus/iichid.c +++ b/sys/dev/iicbus/iichid.c @@ -271,6 +271,8 @@ static int iichid_cmd_read(struct iichid_softc* sc, void *buf, iichid_size_t maxlen, iichid_size_t *actual_len) { + int error; + /* * 6.1.3 - Retrieval of Input Reports * DEVICE returns the length (2 Bytes) and the entire Input Report. @@ -280,7 +282,10 @@ iichid_cmd_read(struct iichid_softc* sc, void *buf, iichid_size_t maxlen, struct iic_msg msgs[] = { { sc->addr, IIC_M_RD, maxlen, buf }, }; - int error; + + if (!sc->reset_acked) { + msgs[0].len = 2; + } error = iicbus_transfer(sc->dev, msgs, nitems(msgs)); if (error != 0) diff --git a/sys/dev/iwx/if_iwx.c b/sys/dev/iwx/if_iwx.c index 04ed09f04604..3c953e522973 100644 --- a/sys/dev/iwx/if_iwx.c +++ b/sys/dev/iwx/if_iwx.c @@ -3429,6 +3429,14 @@ iwx_sta_rx_agg(struct iwx_softc *sc, struct ieee80211_node *ni, uint8_t tid, sc->sc_rx_ba_sessions--; } +/** + * @brief Allocate an A-MPDU / aggregation session for the given node and TID. + * + * This allocates a TX queue specifically for that TID. + * + * Note that this routine currently doesn't return any status/errors, + * so the caller can't know if the aggregation session was setup or not. + */ static void iwx_sta_tx_agg_start(struct iwx_softc *sc, struct ieee80211_node *ni, uint8_t tid) @@ -3502,6 +3510,14 @@ iwx_ba_rx_task(void *arg, int npending __unused) IWX_UNLOCK(sc); } +/** + * @brief Task called to setup a deferred block-ack session. + * + * This sets up any/all pending blockack sessions as defined + * in sc->ba_tx.start_tidmask. + * + * Note: the call to iwx_sta_tx_agg_start() isn't being error checked. + */ static void iwx_ba_tx_task(void *arg, int npending __unused) { @@ -3509,22 +3525,38 @@ iwx_ba_tx_task(void *arg, int npending __unused) struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni = vap->iv_bss; + uint32_t started_mask = 0; int tid; IWX_LOCK(sc); for (tid = 0; tid < IWX_MAX_TID_COUNT; tid++) { + const struct ieee80211_tx_ampdu *tap; + if (sc->sc_flags & IWX_FLAG_SHUTDOWN) break; + tap = &ni->ni_tx_ampdu[tid]; + if (IEEE80211_AMPDU_RUNNING(tap)) + break; if (sc->ba_tx.start_tidmask & (1 << tid)) { - DPRINTF(("%s: ampdu tx start for tid %i\n", __func__, - tid)); + IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT, + "%s: ampdu tx start for tid %i\n", __func__, tid); iwx_sta_tx_agg_start(sc, ni, tid); sc->ba_tx.start_tidmask &= ~(1 << tid); - sc->sc_flags |= IWX_FLAG_AMPDUTX; + started_mask |= (1 << tid); } } IWX_UNLOCK(sc); + + /* Iterate over the sessions we started; mark them as active */ + for (tid = 0; tid < IWX_MAX_TID_COUNT; tid++) { + if (started_mask & (1 << tid)) { + IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT, + "%s: informing net80211 to start ampdu on tid %i\n", + __func__, tid); + ieee80211_ampdu_tx_request_active_ext(ni, tid, 1); + } + } } static void @@ -4575,37 +4607,39 @@ iwx_rx_mpdu_mq(struct iwx_softc *sc, struct mbuf *m, void *pktdata, pad = 1; } -// /* -// * Hardware de-aggregates A-MSDUs and copies the same MAC header -// * in place for each subframe. But it leaves the 'A-MSDU present' -// * bit set in the frame header. We need to clear this bit ourselves. -// * (XXX This workaround is not required on AX200/AX201 devices that -// * have been tested by me, but it's unclear when this problem was -// * fixed in the hardware. It definitely affects the 9k generation. -// * Leaving this in place for now since some 9k/AX200 hybrids seem -// * to exist that we may eventually add support for.) -// * -// * And we must allow the same CCMP PN for subframes following the -// * first subframe. Otherwise they would be discarded as replays. -// */ + /* If it's a HT node then perform re-order processing */ + if (ni->ni_flags & IEEE80211_NODE_HT) + m->m_flags |= M_AMPDU; + + /* + * Hardware de-aggregates A-MSDUs and copies the same MAC header + * in place for each subframe. But it leaves the 'A-MSDU present' + * bit set in the frame header. We need to clear this bit ourselves. + * (XXX This workaround is not required on AX200/AX201 devices that + * have been tested by me, but it's unclear when this problem was + * fixed in the hardware. It definitely affects the 9k generation. + * Leaving this in place for now since some 9k/AX200 hybrids seem + * to exist that we may eventually add support for.) + * + * And we must allow the same CCMP PN for subframes following the + * first subframe. Otherwise they would be discarded as replays. + */ if (desc->mac_flags2 & IWX_RX_MPDU_MFLG2_AMSDU) { - DPRINTF(("%s: === IWX_RX_MPDU_MFLG2_AMSDU\n", __func__)); -// struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); -// uint8_t subframe_idx = (desc->amsdu_info & -// IWX_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK); -// if (subframe_idx > 0) -// rxi.rxi_flags |= IEEE80211_RXI_HWDEC_SAME_PN; -// if (ieee80211_has_qos(wh) && ieee80211_has_addr4(wh) && -// m->m_len >= sizeof(struct ieee80211_qosframe_addr4)) { -// struct ieee80211_qosframe_addr4 *qwh4 = mtod(m, -// struct ieee80211_qosframe_addr4 *); -// qwh4->i_qos[0] &= htole16(~IEEE80211_QOS_AMSDU); -// } else if (ieee80211_has_qos(wh) && -// m->m_len >= sizeof(struct ieee80211_qosframe)) { -// struct ieee80211_qosframe *qwh = mtod(m, -// struct ieee80211_qosframe *); -// qwh->i_qos[0] &= htole16(~IEEE80211_QOS_AMSDU); -// } + struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); + uint8_t subframe_idx = (desc->amsdu_info & + IWX_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK); + uint8_t *qos; + + rxs.c_pktflags |= IEEE80211_RX_F_AMSDU; + if (subframe_idx > 0) + rxs.c_pktflags |= IEEE80211_RX_F_AMSDU_MORE; + + /* XXX should keep driver statistics about this */ + IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT, + "%s: === IWX_RX_MPDU_MFLG2_AMSDU\n", __func__); + + qos = ieee80211_getqos(wh); + qos[0] &= ~IEEE80211_QOS_AMSDU; } /* @@ -5627,7 +5661,6 @@ iwx_tx(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni) u_int hdrlen; uint32_t rate_n_flags; uint16_t num_tbs, flags, offload_assist = 0; - uint8_t type, subtype; int i, totlen, err, pad, qid; #define IWM_MAX_SCATTER 20 bus_dma_segment_t *seg, segs[IWM_MAX_SCATTER]; @@ -5638,38 +5671,32 @@ iwx_tx(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni) IWX_ASSERT_LOCKED(sc); wh = mtod(m, struct ieee80211_frame *); - type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; - subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; hdrlen = ieee80211_anyhdrsize(wh); qid = sc->first_data_qid; /* Put QoS frames on the data queue which maps to their TID. */ - if (IEEE80211_QOS_HAS_SEQ(wh) && (sc->sc_flags & IWX_FLAG_AMPDUTX)) { + if (IEEE80211_QOS_HAS_SEQ(wh)) { uint16_t qos = ieee80211_gettid(wh); uint8_t tid = qos & IEEE80211_QOS_TID; -#if 0 + struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid]; + /* - * XXX-THJ: TODO when we enable ba we need to manage the - * mappings + * Note: we're currently putting all frames into one queue + * except for A-MPDU queues. We should be able to choose + * other WME queues but first we need to verify they've been + * correctly setup for data. */ - struct ieee80211_tx_ba *ba; - ba = &ni->ni_tx_ba[tid]; - if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && - type == IEEE80211_FC0_TYPE_DATA && - subtype != IEEE80211_FC0_SUBTYPE_NODATA && - subtype != IEEE80211_FC0_SUBTYPE_BAR && - sc->aggqid[tid] != 0 /*&& - ba->ba_state == IEEE80211_BA_AGREED*/) { - qid = sc->aggqid[tid]; -#else - if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && - type == IEEE80211_FC0_TYPE_DATA && - subtype != IEEE80211_FC0_SUBTYPE_NODATA && + /* + * Only QoS data goes into an A-MPDU queue; + * don't add QoS null, the other data types, etc. + */ + if (IEEE80211_AMPDU_RUNNING(tap) && + IEEE80211_IS_QOSDATA(wh) && + !IEEE80211_IS_MULTICAST(wh->i_addr1) && sc->aggqid[tid] != 0) { qid = sc->aggqid[tid]; -#endif } } @@ -10711,9 +10738,13 @@ iwx_suspend(device_t dev) struct iwx_softc *sc = device_get_softc(dev); struct ieee80211com *ic = &sc->sc_ic; - if (sc->sc_flags & IWX_FLAG_HW_INITED) { - ieee80211_suspend_all(ic); + /* + * Suspend everything first, then shutdown hardware if it's + * still up. + */ + ieee80211_suspend_all(ic); + if (sc->sc_flags & IWX_FLAG_HW_INITED) { iwx_stop(sc); sc->sc_flags &= ~IWX_FLAG_HW_INITED; } @@ -10725,7 +10756,6 @@ iwx_resume(device_t dev) { struct iwx_softc *sc = device_get_softc(dev); struct ieee80211com *ic = &sc->sc_ic; - int err; /* * We disable the RETRY_TIMEOUT register (0x41) to keep @@ -10735,15 +10765,15 @@ iwx_resume(device_t dev) IWX_LOCK(sc); - err = iwx_init(sc); - if (err) { - iwx_stop_device(sc); - IWX_UNLOCK(sc); - return err; + /* Stop the hardware here if it's still thought of as "up" */ + if (sc->sc_flags & IWX_FLAG_HW_INITED) { + iwx_stop(sc); + sc->sc_flags &= ~IWX_FLAG_HW_INITED; } IWX_UNLOCK(sc); + /* Start the VAPs, which will bring the hardware back up again */ ieee80211_resume_all(ic); return (0); } @@ -10900,6 +10930,26 @@ iwx_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap) return; } +/** + * @brief Called by net80211 to request an A-MPDU session be established. + * + * This is called by net80211 to see if an A-MPDU session can be established. + * However, the iwx(4) firmware will take care of establishing the BA + * session for us. net80211 doesn't have to send any action frames here; + * it just needs to plumb up the ampdu session once the BA has been sent. + * + * If we return 0 here then the firmware will set up the state but net80211 + * will not; so it's on us to actually complete it via a call to + * ieee80211_ampdu_tx_request_active_ext() . + * + * @param ni ieee80211_node to establish A-MPDU session for + * @param tap pointer to the per-TID state struct + * @param dialogtoken dialogtoken field from the BA request + * @param baparamset baparamset field from the BA request + * @param batimeout batimeout field from the BA request + * + * @returns 0 so net80211 doesn't send the BA action frame to establish A-MPDU. + */ static int iwx_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int dialogtoken, int baparamset, int batimeout) @@ -10908,10 +10958,22 @@ iwx_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int tid; tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID); - DPRINTF(("%s: tid=%i\n", __func__, tid)); + IWX_DPRINTF(sc, IWX_DEBUG_AMPDU_MGMT, + "%s: queuing AMPDU start on tid %i\n", __func__, tid); + + /* There's no nice way right now to tell net80211 that we're in the + * middle of an asynchronous ADDBA setup session. So, bump the timeout + * to hz ticks, hopefully we'll get a response by then. + */ + tap->txa_nextrequest = ticks + hz; + + IWX_LOCK(sc); sc->ba_tx.start_tidmask |= (1 << tid); + IWX_UNLOCK(sc); + taskqueue_enqueue(sc->sc_tq, &sc->ba_tx_task); - return 0; + + return (0); } @@ -10940,28 +11002,20 @@ iwx_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, { if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) { - return 1; + return (1); } - if (!(&vap->iv_nw_keys[0] <= k && - k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) { - /* - * Not in the global key table, the driver should handle this - * by allocating a slot in the h/w key table/cache. In - * lieu of that return key slot 0 for any unicast key - * request. We disallow the request if this is a group key. - * This default policy does the right thing for legacy hardware - * with a 4 key table. It also handles devices that pass - * packets through untouched when marked with the WEP bit - * and key index 0. - */ - if (k->wk_flags & IEEE80211_KEY_GROUP) - return 0; + + if (ieee80211_is_key_unicast(vap, k)) { *keyix = 0; /* NB: use key index 0 for ucast key */ - } else { + } else if (ieee80211_is_key_global(vap, k)) { *keyix = ieee80211_crypto_get_key_wepidx(vap, k); + } else { + net80211_vap_printf(vap, "%s: invalid crypto key type\n", + __func__); + return (0); } *rxkeyix = IEEE80211_KEYIX_NONE; /* XXX maybe *keyix? */ - return 1; + return (1); } static int @@ -10978,7 +11032,6 @@ iwx_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) return 1; } - IWX_LOCK(sc); /* * Keys are stored in 'ni' so 'k' is valid if 'ni' is valid. * Currently we only implement station mode where 'ni' is always @@ -10987,37 +11040,45 @@ iwx_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) memset(&cmd, 0, sizeof(cmd)); - if (k->wk_flags & IEEE80211_KEY_GROUP) { - DPRINTF(("%s: adding group key\n", __func__)); + if (ieee80211_is_key_global(vap, k)) { + id = ieee80211_crypto_get_key_wepidx(vap, k); + IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding group key\n", + __func__); + } else if (ieee80211_is_key_unicast(vap, k)) { + IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: adding key\n", + __func__); + id = 0; /* net80211 currently only supports unicast key 0 */ } else { - DPRINTF(("%s: adding key\n", __func__)); + net80211_vap_printf(vap, "%s: unknown key type\n", __func__); + return (ENXIO); } - if (k >= &vap->iv_nw_keys[0] && - k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]) - id = (k - vap->iv_nw_keys); - else - id = (0); - DPRINTF(("%s: setting keyid=%i\n", __func__, id)); + + IWX_LOCK(sc); + cmd.common.key_flags = htole16(IWX_STA_KEY_FLG_CCM | IWX_STA_KEY_FLG_WEP_KEY_MAP | ((id << IWX_STA_KEY_FLG_KEYID_POS) & IWX_STA_KEY_FLG_KEYID_MSK)); - if (k->wk_flags & IEEE80211_KEY_GROUP) { + if (ieee80211_is_key_global(vap, k)) { cmd.common.key_offset = 1; cmd.common.key_flags |= htole16(IWX_STA_KEY_MULTICAST); - } else { + } else if (ieee80211_is_key_unicast(vap, k)) { cmd.common.key_offset = 0; + } else { + net80211_vap_printf(vap, "%s: unknown key type\n", __func__); + IWX_UNLOCK(sc); + return (ENXIO); } memcpy(cmd.common.key, k->wk_key, MIN(sizeof(cmd.common.key), k->wk_keylen)); - DPRINTF(("%s: wk_keylen=%i\n", __func__, k->wk_keylen)); - for (int i=0; i<k->wk_keylen; i++) { - DPRINTF(("%s: key[%d]=%x\n", __func__, i, k->wk_key[i])); - } + IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: key: id=%d, len=%i, key=%*D\n", + __func__, id, k->wk_keylen, k->wk_keylen, + (const unsigned char *) k->wk_key, ""); cmd.common.sta_id = IWX_STATION_ID; cmd.transmit_seq_cnt = htole64(k->wk_keytsc); - DPRINTF(("%s: k->wk_keytsc=%lu\n", __func__, k->wk_keytsc)); + IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, "%s: k->wk_keytsc=%lu\n", __func__, + k->wk_keytsc); status = IWX_ADD_STA_SUCCESS; err = iwx_send_cmd_pdu_status(sc, IWX_ADD_STA_KEY, sizeof(cmd), &cmd, @@ -11025,19 +11086,28 @@ iwx_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k) if (!err && (status & IWX_ADD_STA_STATUS_MASK) != IWX_ADD_STA_SUCCESS) err = EIO; if (err) { - printf("%s: can't set wpa2 keys (error %d)\n", __func__, err); + net80211_vap_printf(vap, + "%s: can't set wpa2 keys (error %d)\n", __func__, err); IWX_UNLOCK(sc); return err; } else - DPRINTF(("%s: key added successfully\n", __func__)); + IWX_DPRINTF(sc, IWX_DEBUG_KEYMGMT, + "%s: key added successfully\n", __func__); IWX_UNLOCK(sc); - return 1; + return (1); } static int iwx_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) { - return 1; + /* + * Note: since there's no key allocations to track - it's either + * the 4 static WEP keys or the single unicast key - there's nothing + * else to do here. + * + * This would need some further work to support IBSS/mesh/AP modes. + */ + return (1); } static device_method_t iwx_pci_methods[] = { diff --git a/sys/dev/iwx/if_iwx_debug.h b/sys/dev/iwx/if_iwx_debug.h index 0079a7e7e753..5fc127d986a9 100644 --- a/sys/dev/iwx/if_iwx_debug.h +++ b/sys/dev/iwx/if_iwx_debug.h @@ -37,7 +37,9 @@ enum { IWX_DEBUG_FW = 0x00200000, /* Firmware management */ IWX_DEBUG_LAR = 0x00400000, /* Location Aware Regulatory */ IWX_DEBUG_TE = 0x00800000, /* Time Event handling */ - /* 0x0n000000 are available */ + IWX_DEBUG_KEYMGMT = 0x01000000, /* Encryption key management */ + IWX_DEBUG_AMPDU_MGMT = 0x02000000, /* AMPDU TX/RX management */ + /* 0x0c000000 are available */ IWX_DEBUG_NI = 0x10000000, /* Not Implemented */ IWX_DEBUG_REGISTER = 0x20000000, /* print chipset register */ IWX_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */ diff --git a/sys/dev/iwx/if_iwxvar.h b/sys/dev/iwx/if_iwxvar.h index 1ac0bc24577c..5ed749db631e 100644 --- a/sys/dev/iwx/if_iwxvar.h +++ b/sys/dev/iwx/if_iwxvar.h @@ -290,7 +290,6 @@ struct iwx_rx_ring { #define IWX_FLAG_BGSCAN 0x200 /* background scan in progress */ #define IWX_FLAG_TXFLUSH 0x400 /* Tx queue flushing in progress */ #define IWX_FLAG_HW_INITED 0x800 /* Hardware initialized */ -#define IWX_FLAG_AMPDUTX 0x1000 struct iwx_ucode_status { uint32_t uc_lmac_error_event_table[2]; diff --git a/sys/dev/mlx5/mlx5_en/en_hw_tls.h b/sys/dev/mlx5/mlx5_en/en_hw_tls.h index d637314e040e..cd57d2ac5f72 100644 --- a/sys/dev/mlx5/mlx5_en/en_hw_tls.h +++ b/sys/dev/mlx5/mlx5_en/en_hw_tls.h @@ -82,6 +82,8 @@ struct mlx5e_tls { struct sysctl_ctx_list ctx; struct mlx5e_tls_stats stats; struct workqueue_struct *wq; + struct workqueue_struct *prealloc_wq; + struct work_struct prealloc_work; uma_zone_t zone; uint32_t max_resources; /* max number of resources */ int zone_max; @@ -92,6 +94,7 @@ struct mlx5e_tls { int mlx5e_tls_init(struct mlx5e_priv *); void mlx5e_tls_cleanup(struct mlx5e_priv *); int mlx5e_sq_tls_xmit(struct mlx5e_sq *, struct mlx5e_xmit_args *, struct mbuf **); +void mlx5e_tls_prealloc_tags(struct mlx5e_priv *priv); if_snd_tag_alloc_t mlx5e_tls_snd_tag_alloc; diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls.c b/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls.c index 6c83de5f3580..851316ccfcd7 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_hw_tls.c @@ -80,23 +80,39 @@ static const char *mlx5e_tls_stats_desc[] = { }; static void mlx5e_tls_work(struct work_struct *); +static void mlx5e_tls_prealloc_work(struct work_struct *); /* - * Expand the tls tag UMA zone in a sleepable context + * Expand the tls tag UMA zone in an async context */ static void -mlx5e_prealloc_tags(struct mlx5e_priv *priv, int nitems) +mlx5e_tls_prealloc_work(struct work_struct *work) { + struct mlx5e_priv *priv; + struct mlx5e_tls *ptls; struct mlx5e_tls_tag **tags; - int i; + int i, nitems; + + ptls = container_of(work, struct mlx5e_tls, prealloc_work); + priv = container_of(ptls, struct mlx5e_priv, tls); + nitems = ptls->zone_max; tags = malloc(sizeof(tags[0]) * nitems, - M_MLX5E_TLS, M_WAITOK); - for (i = 0; i < nitems; i++) - tags[i] = uma_zalloc(priv->tls.zone, M_WAITOK); + M_MLX5E_TLS, M_WAITOK | M_ZERO); + for (i = 0; i < nitems; i++) { + tags[i] = uma_zalloc(priv->tls.zone, M_NOWAIT); + /* + * If the allocation fails, its likely we are competing + * with real consumers of tags and the zone is full, + * so exit the loop, and release the tags like we would + * if we allocated all "nitems" + */ + if (tags[i] == NULL) + break; + } __compiler_membar(); - for (i = 0; i < nitems; i++) + for (i = 0; i < nitems && tags[i] != NULL; i++) uma_zfree(priv->tls.zone, tags[i]); free(tags, M_MLX5E_TLS); } @@ -244,8 +260,6 @@ mlx5e_tls_init(struct mlx5e_priv *priv) } uma_zone_set_max(ptls->zone, ptls->zone_max); - if (prealloc_tags != 0) - mlx5e_prealloc_tags(priv, ptls->zone_max); for (x = 0; x != MLX5E_TLS_STATS_NUM; x++) ptls->stats.arg[x] = counter_u64_alloc(M_WAITOK); @@ -271,6 +285,23 @@ mlx5e_tls_init(struct mlx5e_priv *priv) } void +mlx5e_tls_prealloc_tags(struct mlx5e_priv *priv) +{ + struct mlx5e_tls *ptls = &priv->tls; + int prealloc_tags = 0; + + if (ptls->prealloc_wq != NULL) + return; + + TUNABLE_INT_FETCH("hw.mlx5.tls_prealloc_tags", &prealloc_tags); + if (prealloc_tags == 0) + return; + ptls->prealloc_wq = create_singlethread_workqueue("mlx5-tls-prealloc_wq"); + INIT_WORK(&ptls->prealloc_work, mlx5e_tls_prealloc_work); + queue_work(ptls->prealloc_wq, &ptls->prealloc_work); +} + +void mlx5e_tls_cleanup(struct mlx5e_priv *priv) { struct mlx5e_tls *ptls = &priv->tls; @@ -280,6 +311,10 @@ mlx5e_tls_cleanup(struct mlx5e_priv *priv) return; ptls->init = 0; + if (ptls->prealloc_wq != NULL) { + flush_workqueue(ptls->prealloc_wq); + destroy_workqueue(ptls->prealloc_wq); + } flush_workqueue(ptls->wq); sysctl_ctx_free(&ptls->ctx); uma_zdestroy(ptls->zone); diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c index f83506bda1aa..4658bebb7845 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c @@ -3335,6 +3335,11 @@ mlx5e_open_locked(if_t ifp) mlx5e_update_carrier(priv); +#ifdef KERN_TLS + if ((if_getcapenable(ifp) & (IFCAP_TXTLS4 | IFCAP_TXTLS6)) != 0) + mlx5e_tls_prealloc_tags(priv); +#endif + return (0); err_close_channels: diff --git a/sys/dev/nvd/nvd.c b/sys/dev/nvd/nvd.c index 33b43efd24c1..4737b2b03ae9 100644 --- a/sys/dev/nvd/nvd.c +++ b/sys/dev/nvd/nvd.c @@ -61,6 +61,7 @@ static void nvd_done(void *arg, const struct nvme_completion *cpl); static void nvd_gone(struct nvd_disk *ndisk); static void *nvd_new_disk(struct nvme_namespace *ns, void *ctrlr); +static void *nvd_ns_changed(struct nvme_namespace *ns, void *ctrlr); static void *nvd_new_controller(struct nvme_controller *ctrlr); static void nvd_controller_fail(void *ctrlr); @@ -154,7 +155,7 @@ nvd_load(void) TAILQ_INIT(&ctrlr_head); TAILQ_INIT(&disk_head); - consumer_handle = nvme_register_consumer(nvd_new_disk, + consumer_handle = nvme_register_consumer(nvd_ns_changed, nvd_new_controller, NULL, nvd_controller_fail); return (consumer_handle != NULL ? 0 : -1); @@ -513,6 +514,48 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg) } static void +nvd_resize(struct nvd_disk *ndisk) +{ + struct disk *disk = ndisk->disk; + struct nvme_namespace *ns = ndisk->ns; + + disk->d_sectorsize = nvme_ns_get_sector_size(ns); + disk->d_mediasize = (off_t)nvme_ns_get_size(ns); + disk->d_maxsize = nvme_ns_get_max_io_xfer_size(ns); + disk->d_delmaxsize = (off_t)nvme_ns_get_size(ns); + if (disk->d_delmaxsize > nvd_delete_max) + disk->d_delmaxsize = nvd_delete_max; + + disk_resize(disk, M_NOWAIT); + + printf(NVD_STR"%u: NVMe namespace resized\n", ndisk->unit); + printf(NVD_STR"%u: %juMB (%ju %u byte sectors)\n", disk->d_unit, + (uintmax_t)disk->d_mediasize / (1024*1024), + (uintmax_t)disk->d_mediasize / disk->d_sectorsize, + disk->d_sectorsize); +} + +static void * +nvd_ns_changed(struct nvme_namespace *ns, void *ctrlr_arg) +{ + struct nvd_disk *ndisk; + struct nvd_controller *ctrlr = ctrlr_arg; + + if ((ns->flags & NVME_NS_CHANGED) == 0) + return (nvd_new_disk(ns, ctrlr_arg)); + + mtx_lock(&nvd_lock); + TAILQ_FOREACH(ndisk, &ctrlr->disk_head, ctrlr_tailq) { + if (ndisk->ns->id != ns->id) + continue; + nvd_resize(ndisk); + break; + } + mtx_unlock(&nvd_lock); + return (ctrlr_arg); +} + +static void nvd_controller_fail(void *ctrlr_arg) { struct nvd_controller *ctrlr = ctrlr_arg; diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h index f4ea08f129c0..c8eba3df9c2a 100644 --- a/sys/dev/nvme/nvme.h +++ b/sys/dev/nvme/nvme.h @@ -1910,6 +1910,8 @@ void nvme_sc_sbuf(const struct nvme_completion *cpl, struct sbuf *sbuf); void nvme_strvis(uint8_t *dst, const uint8_t *src, int dstlen, int srclen); #ifdef _KERNEL +#include <sys/systm.h> +#include <sys/disk.h> struct bio; struct thread; @@ -1928,8 +1930,11 @@ typedef void (*nvme_cons_async_fn_t)(void *, const struct nvme_completion *, typedef void (*nvme_cons_fail_fn_t)(void *); enum nvme_namespace_flags { - NVME_NS_DEALLOCATE_SUPPORTED = 0x1, - NVME_NS_FLUSH_SUPPORTED = 0x2, + NVME_NS_DEALLOCATE_SUPPORTED = 0x01, + NVME_NS_FLUSH_SUPPORTED = 0x02, + NVME_NS_ADDED = 0x04, + NVME_NS_CHANGED = 0x08, + NVME_NS_GONE = 0x10, }; int nvme_ctrlr_passthrough_cmd(struct nvme_controller *ctrlr, @@ -1995,6 +2000,24 @@ nvme_ctrlr_has_dataset_mgmt(const struct nvme_controller_data *cd) return (NVMEV(NVME_CTRLR_DATA_ONCS_DSM, cd->oncs) != 0); } +/* + * Copy the NVME device's serial number to the provided buffer, which must be + * at least DISK_IDENT_SIZE bytes large. + */ +static inline void +nvme_cdata_get_disk_ident(const struct nvme_controller_data *cdata, uint8_t *sn) +{ + _Static_assert(NVME_SERIAL_NUMBER_LENGTH < DISK_IDENT_SIZE, + "NVME serial number too big for disk ident"); + + memmove(sn, cdata->sn, NVME_SERIAL_NUMBER_LENGTH); + sn[NVME_SERIAL_NUMBER_LENGTH] = '\0'; + for (int i = 0; sn[i] != '\0'; i++) { + if (sn[i] < 0x20 || sn[i] >= 0x80) + sn[i] = ' '; + } +} + /* Namespace helper functions */ uint32_t nvme_ns_get_max_io_xfer_size(struct nvme_namespace *ns); uint32_t nvme_ns_get_sector_size(struct nvme_namespace *ns); diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index e607667decf5..41542d24c107 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -33,7 +33,6 @@ #include <sys/buf.h> #include <sys/bus.h> #include <sys/conf.h> -#include <sys/disk.h> #include <sys/ioccom.h> #include <sys/proc.h> #include <sys/smp.h> @@ -1154,7 +1153,7 @@ nvme_ctrlr_aer_task(void *arg, int pending) mtx_sleep(aer, &aer->mtx, PRIBIO, "nvme_pt", 0); mtx_unlock(&aer->mtx); - if (aer->log_page_size != (uint32_t)-1) { + if (aer->log_page_size == (uint32_t)-1) { /* * If the log page fetch for some reason completed with an * error, don't pass log page data to the consumers. In @@ -1217,10 +1216,20 @@ nvme_ctrlr_aer_task(void *arg, int pending) } else if (aer->log_page_id == NVME_LOG_CHANGED_NAMESPACE) { struct nvme_ns_list *nsl = (struct nvme_ns_list *)aer->log_page_buffer; + struct nvme_controller *ctrlr = aer->ctrlr; + for (int i = 0; i < nitems(nsl->ns) && nsl->ns[i] != 0; i++) { + struct nvme_namespace *ns; + uint32_t id = nsl->ns[i]; + if (nsl->ns[i] > NVME_MAX_NAMESPACES) break; - nvme_notify_ns(aer->ctrlr, nsl->ns[i]); + + ns = &ctrlr->ns[id - 1]; + ns->flags |= NVME_NS_CHANGED; + nvme_ns_construct(ns, id, ctrlr); + nvme_notify_ns(ctrlr, id); + ns->flags &= ~NVME_NS_CHANGED; } } @@ -1255,24 +1264,6 @@ nvme_ctrlr_poll(struct nvme_controller *ctrlr) } /* - * Copy the NVME device's serial number to the provided buffer, which must be - * at least DISK_IDENT_SIZE bytes large. - */ -void -nvme_ctrlr_get_ident(const struct nvme_controller *ctrlr, uint8_t *sn) -{ - _Static_assert(NVME_SERIAL_NUMBER_LENGTH < DISK_IDENT_SIZE, - "NVME serial number too big for disk ident"); - - memmove(sn, ctrlr->cdata.sn, NVME_SERIAL_NUMBER_LENGTH); - sn[NVME_SERIAL_NUMBER_LENGTH] = '\0'; - for (int i = 0; sn[i] != '\0'; i++) { - if (sn[i] < 0x20 || sn[i] >= 0x80) - sn[i] = ' '; - } -} - -/* * Poll the single-vector interrupt case: num_io_queues will be 1 and * there's only a single vector. While we're polling, we mask further * interrupts in the controller. @@ -1516,7 +1507,7 @@ nvme_ctrlr_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, break; case DIOCGIDENT: { uint8_t *sn = arg; - nvme_ctrlr_get_ident(ctrlr, sn); + nvme_cdata_get_disk_ident(&ctrlr->cdata, sn); break; } /* Linux Compatible (see nvme_linux.h) */ diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c index 17684cc14ba2..4ebcc03c4f04 100644 --- a/sys/dev/nvme/nvme_ns.c +++ b/sys/dev/nvme/nvme_ns.c @@ -78,7 +78,7 @@ nvme_ns_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, break; case NVME_PASSTHROUGH_CMD: pt = (struct nvme_pt_command *)arg; - return (nvme_ctrlr_passthrough_cmd(ctrlr, pt, ns->id, + return (nvme_ctrlr_passthrough_cmd(ctrlr, pt, ns->id, 1 /* is_user_buffer */, 0 /* is_admin_cmd */)); case NVME_GET_NSID: { @@ -90,7 +90,7 @@ nvme_ns_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, } case DIOCGIDENT: { uint8_t *sn = arg; - nvme_ctrlr_get_ident(ctrlr, sn); + nvme_cdata_get_disk_ident(&ctrlr->cdata, sn); break; } case DIOCGMEDIASIZE: @@ -558,8 +558,10 @@ nvme_ns_construct(struct nvme_namespace *ns, uint32_t id, * standard says the entire id will be zeros, so this is a * cheap way to test for that. */ - if (ns->data.nsze == 0) - return (ENXIO); + if (ns->data.nsze == 0) { + ns->flags |= NVME_NS_GONE; + return ((ns->flags & NVME_NS_ADDED) ? 0 : ENXIO); + } flbas_fmt = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, ns->data.flbas); @@ -623,6 +625,7 @@ nvme_ns_construct(struct nvme_namespace *ns, uint32_t id, ns->cdev->si_drv2 = make_dev_alias(ns->cdev, "%sns%d", device_get_nameunit(ctrlr->dev), ns->id); ns->cdev->si_flags |= SI_UNMAPPED; + ns->flags |= NVME_NS_ADDED; return (0); } diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h index dd45e1acd0aa..a425a6a5ad62 100644 --- a/sys/dev/nvme/nvme_private.h +++ b/sys/dev/nvme/nvme_private.h @@ -565,7 +565,6 @@ void nvme_notify_new_controller(struct nvme_controller *ctrlr); void nvme_notify_ns(struct nvme_controller *ctrlr, int nsid); void nvme_ctrlr_shared_handler(void *arg); -void nvme_ctrlr_get_ident(const struct nvme_controller *ctrlr, uint8_t *sn); void nvme_ctrlr_poll(struct nvme_controller *ctrlr); int nvme_ctrlr_suspend(struct nvme_controller *ctrlr); diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c index 7693aa6d54d3..e015fbe4d072 100644 --- a/sys/dev/nvme/nvme_sim.c +++ b/sys/dev/nvme/nvme_sim.c @@ -352,25 +352,35 @@ static void * nvme_sim_ns_change(struct nvme_namespace *ns, void *sc_arg) { struct nvme_sim_softc *sc = sc_arg; + struct cam_path *tmppath; union ccb *ccb; + if (xpt_create_path(&tmppath, /*periph*/NULL, + cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) { + printf("unable to create path for rescan\n"); + return (NULL); + } + /* + * If it's gone, then signal that and leave. + */ + if (ns->flags & NVME_NS_GONE) { + xpt_async(AC_LOST_DEVICE, tmppath, NULL); + xpt_free_path(tmppath); + return (sc_arg); + } + ccb = xpt_alloc_ccb_nowait(); if (ccb == NULL) { printf("unable to alloc CCB for rescan\n"); return (NULL); } + ccb->ccb_h.path = tmppath; /* - * We map the NVMe namespace idea onto the CAM unit LUN. For - * each new namespace, we create a new CAM path for it. We then - * rescan the path to get it to enumerate. + * We map the NVMe namespace idea onto the CAM unit LUN. For each new + * namespace, scan or rescan the path to enumerate it. tmppath freed at + * end of scan. */ - if (xpt_create_path(&ccb->ccb_h.path, /*periph*/NULL, - cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) { - printf("unable to create path for rescan\n"); - xpt_free_ccb(ccb); - return (NULL); - } xpt_rescan(ccb); return (sc_arg); diff --git a/sys/dev/nvmf/controller/nvmft_controller.c b/sys/dev/nvmf/controller/nvmft_controller.c index e618972f46cf..1618c1f96dac 100644 --- a/sys/dev/nvmf/controller/nvmft_controller.c +++ b/sys/dev/nvmf/controller/nvmft_controller.c @@ -103,6 +103,19 @@ nvmft_keep_alive_timer(void *arg) callout_schedule_sbt(&ctrlr->ka_timer, ctrlr->ka_sbt, 0, C_HARDCLOCK); } +static void +nvmft_update_cdata(struct nvmft_controller *ctrlr) +{ + uint32_t ioccsz, val; + + val = nvmft_max_ioccsz(ctrlr->admin); + if (val != 0) { + ioccsz = le32toh(ctrlr->cdata.ioccsz) * 16; + if (val < ioccsz) + ctrlr->cdata.ioccsz = htole32(val / 16); + } +} + int nvmft_handoff_admin_queue(struct nvmft_port *np, enum nvmf_trtype trtype, const nvlist_t *params, const struct nvmf_fabric_connect_cmd *cmd, @@ -160,6 +173,7 @@ nvmft_handoff_admin_queue(struct nvmft_port *np, enum nvmf_trtype trtype, (int)sizeof(data->hostnqn), data->hostnqn); ctrlr->admin = qp; ctrlr->trtype = trtype; + nvmft_update_cdata(ctrlr); /* * The spec requires a non-zero KeepAlive timer, but allow a diff --git a/sys/dev/nvmf/controller/nvmft_qpair.c b/sys/dev/nvmf/controller/nvmft_qpair.c index 73c7bb280780..1300c9ec91fc 100644 --- a/sys/dev/nvmf/controller/nvmft_qpair.c +++ b/sys/dev/nvmf/controller/nvmft_qpair.c @@ -182,6 +182,12 @@ nvmft_qpair_name(struct nvmft_qpair *qp) return (qp->name); } +uint32_t +nvmft_max_ioccsz(struct nvmft_qpair *qp) +{ + return (nvmf_max_ioccsz(qp->qp)); +} + static int _nvmft_send_response(struct nvmft_qpair *qp, const void *cqe) { diff --git a/sys/dev/nvmf/controller/nvmft_var.h b/sys/dev/nvmf/controller/nvmft_var.h index 85032b2dc55f..b3a5278a639c 100644 --- a/sys/dev/nvmf/controller/nvmft_var.h +++ b/sys/dev/nvmf/controller/nvmft_var.h @@ -145,6 +145,7 @@ struct nvmft_controller *nvmft_qpair_ctrlr(struct nvmft_qpair *qp); void nvmft_qpair_datamove(struct nvmft_qpair *qp, union ctl_io *io); uint16_t nvmft_qpair_id(struct nvmft_qpair *qp); const char *nvmft_qpair_name(struct nvmft_qpair *qp); +uint32_t nvmft_max_ioccsz(struct nvmft_qpair *qp); void nvmft_command_completed(struct nvmft_qpair *qp, struct nvmf_capsule *nc); int nvmft_send_response(struct nvmft_qpair *qp, const void *cqe); diff --git a/sys/dev/nvmf/host/nvmf.c b/sys/dev/nvmf/host/nvmf.c index 1ac0d142443b..8ed801524089 100644 --- a/sys/dev/nvmf/host/nvmf.c +++ b/sys/dev/nvmf/host/nvmf.c @@ -498,7 +498,7 @@ nvmf_attach(device_t dev) nvlist_t *nvl = device_get_ivars(dev); const nvlist_t * const *io; struct sysctl_oid *oid; - uint64_t val; + uint64_t mpsmin, val; u_int i; int error; @@ -545,13 +545,20 @@ nvmf_attach(device_t dev) sc->vs = val; /* Honor MDTS if it is set. */ + mpsmin = (uint64_t)1 << (NVME_MPS_SHIFT + + NVME_CAP_HI_MPSMIN(sc->cap >> 32)); sc->max_xfer_size = maxphys; if (sc->cdata->mdts != 0) { sc->max_xfer_size = ulmin(sc->max_xfer_size, - 1 << (sc->cdata->mdts + NVME_MPS_SHIFT + - NVME_CAP_HI_MPSMIN(sc->cap >> 32))); + mpsmin << sc->cdata->mdts); } + /* Honor any transfer size restriction imposed by the transport. */ + val = nvmf_max_xfer_size_qp(sc->io[0]); + if (val >= mpsmin) + sc->max_xfer_size = ulmin(sc->max_xfer_size, + rounddown2(val, mpsmin)); + io = nvlist_get_nvlist_array(nvl, "io", NULL); sc->max_pending_io = nvlist_get_number(io[0], "qsize") * sc->num_io_queues; @@ -1230,6 +1237,9 @@ nvmf_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, case NVME_GET_CONTROLLER_DATA: memcpy(arg, sc->cdata, sizeof(*sc->cdata)); return (0); + case DIOCGIDENT: + nvme_cdata_get_disk_ident(sc->cdata, (uint8_t *)arg); + return (0); case NVMF_RECONNECT_PARAMS: nv = (struct nvmf_ioc_nv *)arg; return (nvmf_reconnect_params(sc, nv)); diff --git a/sys/dev/nvmf/host/nvmf_ns.c b/sys/dev/nvmf/host/nvmf_ns.c index 4215c8295d2e..d57280e19d41 100644 --- a/sys/dev/nvmf/host/nvmf_ns.c +++ b/sys/dev/nvmf/host/nvmf_ns.c @@ -278,6 +278,9 @@ nvmf_ns_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, sizeof(gnsid->cdev)); gnsid->nsid = ns->id; return (0); + case DIOCGIDENT: + nvme_cdata_get_disk_ident(ns->sc->cdata, (uint8_t *)arg); + return (0); case DIOCGMEDIASIZE: *(off_t *)arg = ns->size; return (0); diff --git a/sys/dev/nvmf/host/nvmf_qpair.c b/sys/dev/nvmf/host/nvmf_qpair.c index 2f511cf0406d..adb57e52d002 100644 --- a/sys/dev/nvmf/host/nvmf_qpair.c +++ b/sys/dev/nvmf/host/nvmf_qpair.c @@ -416,6 +416,12 @@ nvmf_destroy_qp(struct nvmf_host_qpair *qp) free(qp, M_NVMF); } +uint64_t +nvmf_max_xfer_size_qp(struct nvmf_host_qpair *qp) +{ + return (nvmf_max_xfer_size(qp->qp)); +} + void nvmf_submit_request(struct nvmf_request *req) { diff --git a/sys/dev/nvmf/host/nvmf_var.h b/sys/dev/nvmf/host/nvmf_var.h index 606245b3969c..9190da300d85 100644 --- a/sys/dev/nvmf/host/nvmf_var.h +++ b/sys/dev/nvmf/host/nvmf_var.h @@ -210,6 +210,7 @@ struct nvmf_host_qpair *nvmf_init_qp(struct nvmf_softc *sc, enum nvmf_trtype trtype, const nvlist_t *nvl, const char *name, u_int qid); void nvmf_shutdown_qp(struct nvmf_host_qpair *qp); void nvmf_destroy_qp(struct nvmf_host_qpair *qp); +uint64_t nvmf_max_xfer_size_qp(struct nvmf_host_qpair *qp); struct nvmf_request *nvmf_allocate_request(struct nvmf_host_qpair *qp, void *sqe, nvmf_request_complete_t *cb, void *cb_arg, int how); void nvmf_submit_request(struct nvmf_request *req); diff --git a/sys/dev/nvmf/nvmf_tcp.c b/sys/dev/nvmf/nvmf_tcp.c index e50d7ff48d2b..481c769cedcb 100644 --- a/sys/dev/nvmf/nvmf_tcp.c +++ b/sys/dev/nvmf/nvmf_tcp.c @@ -1602,6 +1602,18 @@ tcp_free_qpair(struct nvmf_qpair *nq) tcp_release_qpair(qp); } +static uint32_t +tcp_max_ioccsz(struct nvmf_qpair *nq) +{ + return (0); +} + +static uint64_t +tcp_max_xfer_size(struct nvmf_qpair *nq) +{ + return (0); +} + static struct nvmf_capsule * tcp_allocate_capsule(struct nvmf_qpair *nq, int how) { @@ -1872,6 +1884,8 @@ tcp_send_controller_data(struct nvmf_capsule *nc, uint32_t data_offset, struct nvmf_transport_ops tcp_ops = { .allocate_qpair = tcp_allocate_qpair, .free_qpair = tcp_free_qpair, + .max_ioccsz = tcp_max_ioccsz, + .max_xfer_size = tcp_max_xfer_size, .allocate_capsule = tcp_allocate_capsule, .free_capsule = tcp_free_capsule, .transmit_capsule = tcp_transmit_capsule, diff --git a/sys/dev/nvmf/nvmf_transport.c b/sys/dev/nvmf/nvmf_transport.c index 1d3f5ea4cf69..92d71d1b13fd 100644 --- a/sys/dev/nvmf/nvmf_transport.c +++ b/sys/dev/nvmf/nvmf_transport.c @@ -188,6 +188,18 @@ nvmf_sqhd_valid(struct nvmf_capsule *nc) return (nc->nc_sqhd_valid); } +uint64_t +nvmf_max_xfer_size(struct nvmf_qpair *qp) +{ + return (qp->nq_ops->max_xfer_size(qp)); +} + +uint32_t +nvmf_max_ioccsz(struct nvmf_qpair *qp) +{ + return (qp->nq_ops->max_ioccsz(qp)); +} + uint8_t nvmf_validate_command_capsule(struct nvmf_capsule *nc) { diff --git a/sys/dev/nvmf/nvmf_transport.h b/sys/dev/nvmf/nvmf_transport.h index b192baeaccc1..495e0dbc8c37 100644 --- a/sys/dev/nvmf/nvmf_transport.h +++ b/sys/dev/nvmf/nvmf_transport.h @@ -81,9 +81,23 @@ void *nvmf_capsule_sqe(struct nvmf_capsule *nc); void *nvmf_capsule_cqe(struct nvmf_capsule *nc); bool nvmf_sqhd_valid(struct nvmf_capsule *nc); +/* Host-specific APIs. */ + +/* + * Largest I/O request size for a single command supported by the + * transport. If the transport does not have a limit, returns 0. + */ +uint64_t nvmf_max_xfer_size(struct nvmf_qpair *qp); + /* Controller-specific APIs. */ /* + * Largest I/O command capsule size (IOCCSZ) supported by the + * transport. If the transport does not have a limit, returns 0. + */ +uint32_t nvmf_max_ioccsz(struct nvmf_qpair *qp); + +/* * A controller calls this function to check for any * transport-specific errors (invalid fields) in a received command * capsule. The callback returns a generic command status value: diff --git a/sys/dev/nvmf/nvmf_transport_internal.h b/sys/dev/nvmf/nvmf_transport_internal.h index eb819a5c83b9..9b459716168a 100644 --- a/sys/dev/nvmf/nvmf_transport_internal.h +++ b/sys/dev/nvmf/nvmf_transport_internal.h @@ -25,6 +25,12 @@ struct nvmf_transport_ops { const nvlist_t *nvl); void (*free_qpair)(struct nvmf_qpair *qp); + /* Limit on I/O command capsule size. */ + uint32_t (*max_ioccsz)(struct nvmf_qpair *qp); + + /* Limit on transfer size. */ + uint64_t (*max_xfer_size)(struct nvmf_qpair *qp); + /* Capsule operations. */ struct nvmf_capsule *(*allocate_capsule)(struct nvmf_qpair *qp, int how); diff --git a/sys/dev/ofw/ofw_cpu.c b/sys/dev/ofw/ofw_cpu.c index 4b12f2e994e3..852ce6ea3759 100644 --- a/sys/dev/ofw/ofw_cpu.c +++ b/sys/dev/ofw/ofw_cpu.c @@ -35,6 +35,7 @@ #include <sys/malloc.h> #include <sys/bus.h> #include <sys/cpu.h> +#include <sys/smp.h> #include <machine/bus.h> #include <dev/ofw/openfirm.h> @@ -280,6 +281,28 @@ ofw_cpu_attach(device_t dev) } else sc->sc_reg_valid = true; +#ifdef __aarch64__ + if (sc->sc_reg_valid) { + uint64_t target_mpidr; + + target_mpidr = sc->sc_reg[0]; + if (psc->sc_addr_cells > 1) { + MPASS(psc->sc_addr_cells == 2); + target_mpidr <<= 32; + target_mpidr |= sc->sc_reg[1]; + } + target_mpidr &= CPU_AFF_MASK; + for (int cpu = 0; cpu <= mp_maxid; cpu++) { + if (cpuid_to_pcpu[cpu] == NULL) + continue; + + if (cpuid_to_pcpu[cpu]->pc_mpidr == target_mpidr) { + sc->sc_cpu_pcpu = cpuid_to_pcpu[cpu]; + break; + } + } + } +#endif #ifdef __powerpc__ /* * On powerpc, "interrupt-servers" denotes a SMT CPU. Look for any @@ -315,9 +338,10 @@ ofw_cpu_attach(device_t dev) device_printf(dev, "No CPU found for this device.\n"); return (ENXIO); } - } else + } #endif - sc->sc_cpu_pcpu = pcpu_find(device_get_unit(dev)); + if (sc->sc_cpu_pcpu == NULL) + sc->sc_cpu_pcpu = pcpu_find(device_get_unit(dev)); if (OF_getencprop(node, "clock-frequency", &cell, sizeof(cell)) < 0) { if (get_freq_from_clk(dev, sc) != 0) { diff --git a/sys/dev/random/fenestrasX/fx_pool.c b/sys/dev/random/fenestrasX/fx_pool.c index b6ffc202769e..59273a0a3f9d 100644 --- a/sys/dev/random/fenestrasX/fx_pool.c +++ b/sys/dev/random/fenestrasX/fx_pool.c @@ -167,10 +167,7 @@ static const struct fxrng_ent_char { [RANDOM_RANDOMDEV] = { .entc_cls = &fxrng_lo_push, }, - [RANDOM_PURE_SAFE] = { - .entc_cls = &fxrng_hi_push, - }, - [RANDOM_PURE_GLXSB] = { + [RANDOM_PURE_TPM] = { .entc_cls = &fxrng_hi_push, }, [RANDOM_PURE_RDRAND] = { @@ -197,9 +194,6 @@ static const struct fxrng_ent_char { [RANDOM_PURE_DARN] = { .entc_cls = &fxrng_hi_pull, }, - [RANDOM_PURE_TPM] = { - .entc_cls = &fxrng_hi_push, - }, [RANDOM_PURE_VMGENID] = { .entc_cls = &fxrng_hi_push, }, @@ -212,6 +206,12 @@ static const struct fxrng_ent_char { [RANDOM_PURE_ARM_TRNG] = { .entc_cls = &fxrng_hi_pull, }, + [RANDOM_PURE_SAFE] = { + .entc_cls = &fxrng_hi_push, + }, + [RANDOM_PURE_GLXSB] = { + .entc_cls = &fxrng_hi_push, + }, }; CTASSERT(nitems(fxrng_ent_char) == ENTROPYSOURCE); diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c index b591ffd3b544..296721d2c4e9 100644 --- a/sys/dev/random/random_harvestq.c +++ b/sys/dev/random/random_harvestq.c @@ -662,8 +662,7 @@ static const char *random_source_descr[/*ENTROPYSOURCE*/] = { [RANDOM_UMA] = "UMA", [RANDOM_CALLOUT] = "CALLOUT", [RANDOM_RANDOMDEV] = "RANDOMDEV", /* ENVIRONMENTAL_END */ - [RANDOM_PURE_SAFE] = "PURE_SAFE", /* PURE_START */ - [RANDOM_PURE_GLXSB] = "PURE_GLXSB", + [RANDOM_PURE_TPM] = "PURE_TPM", /* PURE_START */ [RANDOM_PURE_RDRAND] = "PURE_RDRAND", [RANDOM_PURE_RDSEED] = "PURE_RDSEED", [RANDOM_PURE_NEHEMIAH] = "PURE_NEHEMIAH", @@ -672,11 +671,12 @@ static const char *random_source_descr[/*ENTROPYSOURCE*/] = { [RANDOM_PURE_BROADCOM] = "PURE_BROADCOM", [RANDOM_PURE_CCP] = "PURE_CCP", [RANDOM_PURE_DARN] = "PURE_DARN", - [RANDOM_PURE_TPM] = "PURE_TPM", [RANDOM_PURE_VMGENID] = "PURE_VMGENID", [RANDOM_PURE_QUALCOMM] = "PURE_QUALCOMM", [RANDOM_PURE_ARMV8] = "PURE_ARMV8", [RANDOM_PURE_ARM_TRNG] = "PURE_ARM_TRNG", + [RANDOM_PURE_SAFE] = "PURE_SAFE", + [RANDOM_PURE_GLXSB] = "PURE_GLXSB", /* "ENTROPYSOURCE" */ }; CTASSERT(nitems(random_source_descr) == ENTROPYSOURCE); diff --git a/sys/dev/rtwn/if_rtwn_cam.c b/sys/dev/rtwn/if_rtwn_cam.c index d142cd0476e4..83f774b56814 100644 --- a/sys/dev/rtwn/if_rtwn_cam.c +++ b/sys/dev/rtwn/if_rtwn_cam.c @@ -182,6 +182,7 @@ end: static int rtwn_key_set_cb0(struct rtwn_softc *sc, const struct ieee80211_key *k) { + const char *key_data; uint8_t algo, keyid; int i, error; @@ -194,7 +195,7 @@ rtwn_key_set_cb0(struct rtwn_softc *sc, const struct ieee80211_key *k) /* Map net80211 cipher to HW crypto algorithm. */ switch (k->wk_cipher->ic_cipher) { case IEEE80211_CIPHER_WEP: - if (k->wk_keylen < 8) + if (ieee80211_crypto_get_key_len(k) < 8) algo = R92C_CAM_ALGO_WEP40; else algo = R92C_CAM_ALGO_WEP104; @@ -211,11 +212,18 @@ rtwn_key_set_cb0(struct rtwn_softc *sc, const struct ieee80211_key *k) return (EINVAL); } + /* Get key data. */ + key_data = ieee80211_crypto_get_key_data(k); + if (key_data == NULL) { + error = ENXIO; + goto fail; + } + RTWN_DPRINTF(sc, RTWN_DEBUG_KEY, "%s: keyix %u, keyid %u, algo %u/%u, flags %04X, len %u, " "macaddr %s\n", __func__, k->wk_keyix, keyid, - k->wk_cipher->ic_cipher, algo, k->wk_flags, k->wk_keylen, - ether_sprintf(k->wk_macaddr)); + k->wk_cipher->ic_cipher, algo, k->wk_flags, + ieee80211_crypto_get_key_len(k), ether_sprintf(k->wk_macaddr)); /* Clear high bits. */ rtwn_cam_write(sc, R92C_CAM_CTL6(k->wk_keyix), 0); @@ -224,7 +232,7 @@ rtwn_key_set_cb0(struct rtwn_softc *sc, const struct ieee80211_key *k) /* Write key. */ for (i = 0; i < 4; i++) { error = rtwn_cam_write(sc, R92C_CAM_KEY(k->wk_keyix, i), - le32dec(&k->wk_key[i * 4])); + le32dec(&key_data[i * 4])); if (error != 0) goto fail; } diff --git a/sys/dev/safe/safe.c b/sys/dev/safe/safe.c index c512f3fc62c0..21824ba8de8d 100644 --- a/sys/dev/safe/safe.c +++ b/sys/dev/safe/safe.c @@ -424,6 +424,8 @@ safe_attach(device_t dev) #ifdef SAFE_DEBUG safec = sc; /* for use by hw.safe.dump */ #endif + gone_in(16, "%s(4) is deprecated in 15.0 and removed in 16.0\n", + safe_driver.name); return (0); bad4: crypto_unregister_all(sc->sc_cid); diff --git a/sys/dev/sound/dummy.c b/sys/dev/sound/dummy.c index 39214a141bf9..74ca1d0c924c 100644 --- a/sys/dev/sound/dummy.c +++ b/sys/dev/sound/dummy.c @@ -64,7 +64,7 @@ struct dummy_softc { int chnum; struct dummy_chan chans[DUMMY_NCHAN]; struct callout callout; - struct mtx *lock; + struct mtx lock; bool stopped; }; @@ -74,7 +74,7 @@ dummy_active(struct dummy_softc *sc) struct dummy_chan *ch; int i; - snd_mtxassert(sc->lock); + mtx_assert(&sc->lock, MA_OWNED); for (i = 0; i < sc->chnum; i++) { ch = &sc->chans[i]; @@ -105,13 +105,13 @@ dummy_chan_io(void *arg) if (!ch->run) continue; if (ch->dir == PCMDIR_PLAY) { - ch->ptr += sndbuf_getblksz(ch->buf); - ch->ptr %= sndbuf_getsize(ch->buf); + ch->ptr += ch->buf->blksz; + ch->ptr %= ch->buf->bufsize; } else sndbuf_fillsilence(ch->buf); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(ch->chan); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } if (!sc->stopped) callout_schedule(&sc->callout, 1); @@ -123,7 +123,7 @@ dummy_chan_free(kobj_t obj, void *data) struct dummy_chan *ch =data; uint8_t *buf; - buf = sndbuf_getbuf(ch->buf); + buf = ch->buf->buf; if (buf != NULL) free(buf, M_DEVBUF); @@ -141,7 +141,7 @@ dummy_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, sc = devinfo; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); ch = &sc->chans[sc->chnum++]; ch->sc = sc; @@ -150,7 +150,7 @@ dummy_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, ch->buf = b; ch->caps = &sc->caps; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); bufsz = pcm_getbuffersize(sc->dev, 2048, 2048, 65536); buf = malloc(bufsz, M_DEVBUF, M_WAITOK | M_ZERO); @@ -190,7 +190,7 @@ dummy_chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) { struct dummy_chan *ch = data; - return (sndbuf_getblksz(ch->buf)); + return (ch->buf->blksz); } static int @@ -199,10 +199,10 @@ dummy_chan_trigger(kobj_t obj, void *data, int go) struct dummy_chan *ch = data; struct dummy_softc *sc = ch->sc; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (sc->stopped) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -222,7 +222,7 @@ dummy_chan_trigger(kobj_t obj, void *data, int go) break; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -320,8 +320,9 @@ dummy_attach(device_t dev) sc = device_get_softc(dev); sc->dev = dev; - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_dummy softc"); - callout_init_mtx(&sc->callout, sc->lock, 0); + mtx_init(&sc->lock, device_get_nameunit(dev), "snd_dummy softc", + MTX_DEF); + callout_init_mtx(&sc->callout, &sc->lock, 0); sc->cap_fmts[0] = SND_FORMAT(AFMT_S32_LE, 2, 0); sc->cap_fmts[1] = SND_FORMAT(AFMT_S24_LE, 2, 0); @@ -362,12 +363,12 @@ dummy_detach(device_t dev) struct dummy_softc *sc = device_get_softc(dev); int err; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->stopped = true; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); callout_drain(&sc->callout); err = pcm_unregister(dev); - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); return (err); } diff --git a/sys/dev/sound/fdt/audio_soc.c b/sys/dev/sound/fdt/audio_soc.c index c2bdea399364..84867cb3d781 100644 --- a/sys/dev/sound/fdt/audio_soc.c +++ b/sys/dev/sound/fdt/audio_soc.c @@ -249,7 +249,7 @@ audio_soc_chan_free(kobj_t obj, void *data) ausoc_chan = (struct audio_soc_channel *)data; - buffer = sndbuf_getbuf(ausoc_chan->buf); + buffer = ausoc_chan->buf->buf; if (buffer) free(buffer, M_DEVBUF); diff --git a/sys/dev/sound/macio/aoa.c b/sys/dev/sound/macio/aoa.c index 9861bbd92a0c..e0a6206c19a6 100644 --- a/sys/dev/sound/macio/aoa.c +++ b/sys/dev/sound/macio/aoa.c @@ -73,8 +73,8 @@ aoa_dma_set_program(struct aoa_dma *dma) u_int32_t addr; int i; - addr = (u_int32_t) sndbuf_getbufaddr(dma->buf); - KASSERT(dma->bufsz == sndbuf_getsize(dma->buf), ("bad size")); + addr = (u_int32_t)dma->buf->buf_addr; + KASSERT(dma->bufsz == dma->buf->bufsize, ("bad size")); dma->slots = dma->bufsz / dma->blksz; diff --git a/sys/dev/sound/midi/midi.c b/sys/dev/sound/midi/midi.c index 6753f864ba9c..e14a28557406 100644 --- a/sys/dev/sound/midi/midi.c +++ b/sys/dev/sound/midi/midi.c @@ -32,45 +32,30 @@ #include <sys/param.h> #include <sys/systm.h> -#include <sys/queue.h> +#include <sys/conf.h> +#include <sys/fcntl.h> #include <sys/kernel.h> +#include <sys/kobj.h> #include <sys/lock.h> +#include <sys/module.h> #include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/signalvar.h> -#include <sys/conf.h> +#include <sys/poll.h> +#include <sys/queue.h> #include <sys/selinfo.h> -#include <sys/sysctl.h> -#include <sys/malloc.h> #include <sys/sx.h> -#include <sys/proc.h> -#include <sys/fcntl.h> -#include <sys/types.h> +#include <sys/sysctl.h> #include <sys/uio.h> -#include <sys/poll.h> -#include <sys/sbuf.h> -#include <sys/kobj.h> -#include <sys/module.h> #ifdef HAVE_KERNEL_OPTION_HEADERS #include "opt_snd.h" #endif #include <dev/sound/midi/midi.h> -#include "mpu_if.h" - #include <dev/sound/midi/midiq.h> -MALLOC_DEFINE(M_MIDI, "midi buffers", "Midi data allocation area"); - -#ifndef KOBJMETHOD_END -#define KOBJMETHOD_END { NULL, NULL } -#endif -#define MIDI_DEV_MIDICTL 12 +#include "mpu_if.h" -enum midi_states { - MIDI_IN_START, MIDI_IN_SYSEX, MIDI_IN_DATA -}; +MALLOC_DEFINE(M_MIDI, "midi buffers", "Midi data allocation area"); #define MIDI_NAMELEN 16 struct snd_midi { @@ -90,12 +75,6 @@ struct snd_midi { struct selinfo rsel, wsel; int hiwat; /* QLEN(outq)>High-water -> disable * writes from userland */ - enum midi_states inq_state; - int inq_status, inq_left; /* Variables for the state machine in - * Midi_in, this is to provide that - * signals only get issued only - * complete command packets. */ - struct proc *async; struct cdev *dev; TAILQ_ENTRY(snd_midi) link; }; @@ -330,10 +309,8 @@ static int midi_lengths[] = {2, 2, 2, 2, 1, 1, 2, 0}; int midi_in(struct snd_midi *m, uint8_t *buf, int size) { - /* int i, sig, enq; */ int used; - /* uint8_t data; */ MIDI_DEBUG(5, printf("midi_in: m=%p size=%d\n", m, size)); /* @@ -345,111 +322,22 @@ midi_in(struct snd_midi *m, uint8_t *buf, int size) used = 0; mtx_lock(&m->qlock); -#if 0 - /* - * Don't bother queuing if not in read mode. Discard everything and - * return size so the caller doesn't freak out. - */ - - if (!(m->flags & M_RX)) - return size; - - for (i = sig = 0; i < size; i++) { - data = buf[i]; - enq = 0; - if (data == MIDI_ACK) - continue; - - switch (m->inq_state) { - case MIDI_IN_START: - if (MIDI_IS_STATUS(data)) { - switch (data) { - case 0xf0: /* Sysex */ - m->inq_state = MIDI_IN_SYSEX; - break; - case 0xf1: /* MTC quarter frame */ - case 0xf3: /* Song select */ - m->inq_state = MIDI_IN_DATA; - enq = 1; - m->inq_left = 1; - break; - case 0xf2: /* Song position pointer */ - m->inq_state = MIDI_IN_DATA; - enq = 1; - m->inq_left = 2; - break; - default: - if (MIDI_IS_COMMON(data)) { - enq = 1; - sig = 1; - } else { - m->inq_state = MIDI_IN_DATA; - enq = 1; - m->inq_status = data; - m->inq_left = MIDI_LENGTH(data); - } - break; - } - } else if (MIDI_IS_STATUS(m->inq_status)) { - m->inq_state = MIDI_IN_DATA; - if (!MIDIQ_FULL(m->inq)) { - used++; - MIDIQ_ENQ(m->inq, &m->inq_status, 1); - } - enq = 1; - m->inq_left = MIDI_LENGTH(m->inq_status) - 1; - } - break; - /* - * End of case MIDI_IN_START: - */ - - case MIDI_IN_DATA: - enq = 1; - if (--m->inq_left <= 0) - sig = 1;/* deliver data */ - break; - case MIDI_IN_SYSEX: - if (data == MIDI_SYSEX_END) - m->inq_state = MIDI_IN_START; - break; - } - - if (enq) - if (!MIDIQ_FULL(m->inq)) { - MIDIQ_ENQ(m->inq, &data, 1); - used++; - } - /* - * End of the state machines main "for loop" - */ + MIDI_DEBUG(6, printf("midi_in: len %jd avail %jd\n", + (intmax_t)MIDIQ_LEN(m->inq), + (intmax_t)MIDIQ_AVAIL(m->inq))); + if (MIDIQ_AVAIL(m->inq) > size) { + used = size; + MIDIQ_ENQ(m->inq, buf, size); + } else { + MIDI_DEBUG(4, printf("midi_in: Discarding data qu\n")); + mtx_unlock(&m->qlock); + return 0; } - if (sig) { -#endif - MIDI_DEBUG(6, printf("midi_in: len %jd avail %jd\n", - (intmax_t)MIDIQ_LEN(m->inq), - (intmax_t)MIDIQ_AVAIL(m->inq))); - if (MIDIQ_AVAIL(m->inq) > size) { - used = size; - MIDIQ_ENQ(m->inq, buf, size); - } else { - MIDI_DEBUG(4, printf("midi_in: Discarding data qu\n")); - mtx_unlock(&m->qlock); - return 0; - } - if (m->rchan) { - wakeup(&m->rchan); - m->rchan = 0; - } - selwakeup(&m->rsel); - if (m->async) { - PROC_LOCK(m->async); - kern_psignal(m->async, SIGIO); - PROC_UNLOCK(m->async); - } -#if 0 + if (m->rchan) { + wakeup(&m->rchan); + m->rchan = 0; } -#endif + selwakeup(&m->rsel); mtx_unlock(&m->qlock); return used; } @@ -484,11 +372,6 @@ midi_out(struct snd_midi *m, uint8_t *buf, int size) m->wchan = 0; } selwakeup(&m->wsel); - if (m->async) { - PROC_LOCK(m->async); - kern_psignal(m->async, SIGIO); - PROC_UNLOCK(m->async); - } } mtx_unlock(&m->qlock); return used; @@ -530,7 +413,6 @@ midi_open(struct cdev *i_dev, int flags, int mode, struct thread *td) m->rchan = 0; m->wchan = 0; - m->async = 0; if (flags & FREAD) { m->flags |= M_RX | M_RXEN; diff --git a/sys/dev/sound/midi/mpu401.c b/sys/dev/sound/midi/mpu401.c index 224ebb1b01f4..7d3edb6323ef 100644 --- a/sys/dev/sound/midi/mpu401.c +++ b/sys/dev/sound/midi/mpu401.c @@ -27,17 +27,10 @@ */ #include <sys/param.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/queue.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/proc.h> #include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> #include <sys/kobj.h> -#include <sys/malloc.h> -#include <sys/bus.h> /* to get driver_intr_t */ #ifdef HAVE_KERNEL_OPTION_HEADERS #include "opt_snd.h" @@ -49,10 +42,6 @@ #include "mpu_if.h" #include "mpufoi_if.h" -#ifndef KOBJMETHOD_END -#define KOBJMETHOD_END { NULL, NULL } -#endif - #define MPU_DATAPORT 0 #define MPU_CMDPORT 1 #define MPU_STATPORT 1 diff --git a/sys/dev/sound/pci/als4000.c b/sys/dev/sound/pci/als4000.c index 9d86713b379e..aea7cc6d3a64 100644 --- a/sys/dev/sound/pci/als4000.c +++ b/sys/dev/sound/pci/als4000.c @@ -79,7 +79,7 @@ struct sc_info { struct resource *reg, *irq; int regid, irqid; void *ih; - struct mtx *lock; + struct mtx lock; unsigned int bufsz; struct sc_chinfo pch, rch; @@ -208,7 +208,7 @@ alschan_init(kobj_t obj, void *devinfo, struct sc_info *sc = devinfo; struct sc_chinfo *ch; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (dir == PCMDIR_PLAY) { ch = &sc->pch; ch->gcr_fifo_status = ALS_GCR_FIFO0_STATUS; @@ -221,9 +221,9 @@ alschan_init(kobj_t obj, void *devinfo, ch->channel = c; ch->bps = 1; ch->format = SND_FORMAT(AFMT_U8, 1, 0); - ch->speed = DSP_DEFAULT_SPEED; + ch->speed = 8000; ch->buffer = b; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) != 0) return NULL; @@ -278,10 +278,10 @@ alschan_getptr(kobj_t obj, void *data) struct sc_info *sc = ch->parent; int32_t pos, sz; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); pos = als_gcr_rd(ch->parent, ch->gcr_fifo_status) & 0xffff; - snd_mtxunlock(sc->lock); - sz = sndbuf_getsize(ch->buffer); + mtx_unlock(&sc->lock); + sz = ch->buffer->bufsize; return (2 * sz - pos - 1) % sz; } @@ -348,8 +348,8 @@ als_playback_start(struct sc_chinfo *ch) struct sc_info *sc = ch->parent; u_int32_t buf, bufsz, count, dma_prog; - buf = sndbuf_getbufaddr(ch->buffer); - bufsz = sndbuf_getsize(ch->buffer); + buf = ch->buffer->buf_addr; + bufsz = ch->buffer->bufsize; count = bufsz / 2; if (ch->format & AFMT_16BIT) count /= 2; @@ -397,7 +397,7 @@ alspchan_trigger(kobj_t obj, void *data, int go) if (!PCMTRIG_COMMON(go)) return 0; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); switch(go) { case PCMTRIG_START: als_playback_start(ch); @@ -409,7 +409,7 @@ alspchan_trigger(kobj_t obj, void *data, int go) default: break; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -451,8 +451,8 @@ als_capture_start(struct sc_chinfo *ch) struct sc_info *sc = ch->parent; u_int32_t buf, bufsz, count, dma_prog; - buf = sndbuf_getbufaddr(ch->buffer); - bufsz = sndbuf_getsize(ch->buffer); + buf = ch->buffer->buf_addr; + bufsz = ch->buffer->bufsize; count = bufsz / 2; if (ch->format & AFMT_16BIT) count /= 2; @@ -493,7 +493,7 @@ alsrchan_trigger(kobj_t obj, void *data, int go) struct sc_chinfo *ch = data; struct sc_info *sc = ch->parent; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); switch(go) { case PCMTRIG_START: als_capture_start(ch); @@ -503,7 +503,7 @@ alsrchan_trigger(kobj_t obj, void *data, int go) als_capture_stop(ch); break; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -637,19 +637,19 @@ als_intr(void *p) struct sc_info *sc = (struct sc_info *)p; u_int8_t intr, sb_status; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); intr = als_intr_rd(sc); if (intr & 0x80) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(sc->pch.channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } if (intr & 0x40) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(sc->rch.channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } /* ACK interrupt in PCI core */ @@ -667,7 +667,7 @@ als_intr(void *p) if (sb_status & ALS_IRQ_CR1E) als_ack_read(sc, ALS_CR1E_ACK_PORT); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return; } @@ -749,10 +749,7 @@ als_resource_free(device_t dev, struct sc_info *sc) bus_dma_tag_destroy(sc->parent_dmat); sc->parent_dmat = 0; } - if (sc->lock) { - snd_mtxfree(sc->lock); - sc->lock = NULL; - } + mtx_destroy(&sc->lock); } static int @@ -808,7 +805,8 @@ als_pci_attach(device_t dev) char status[SND_STATUSLEN]; sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_als4000 softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "snd_als4000 softc", + MTX_DEF); sc->dev = dev; pci_enable_busmaster(dev); @@ -882,11 +880,11 @@ als_pci_suspend(device_t dev) { struct sc_info *sc = pcm_getdevinfo(dev); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->pch.dma_was_active = als_playback_stop(&sc->pch); sc->rch.dma_was_active = als_capture_stop(&sc->rch); als_uninit(sc); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -895,16 +893,16 @@ als_pci_resume(device_t dev) { struct sc_info *sc = pcm_getdevinfo(dev); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (als_init(sc) != 0) { device_printf(dev, "unable to reinitialize the card\n"); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return ENXIO; } if (mixer_reinit(dev) != 0) { device_printf(dev, "unable to reinitialize the mixer\n"); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return ENXIO; } @@ -915,7 +913,7 @@ als_pci_resume(device_t dev) if (sc->rch.dma_was_active) { als_capture_start(&sc->rch); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } diff --git a/sys/dev/sound/pci/atiixp.c b/sys/dev/sound/pci/atiixp.c index 90e5742e6523..12906ecc6253 100644 --- a/sys/dev/sound/pci/atiixp.c +++ b/sys/dev/sound/pci/atiixp.c @@ -129,7 +129,7 @@ struct atiixp_info { uint32_t blkcnt; int registered_channels; - struct mtx *lock; + struct mtx lock; struct callout poll_timer; int poll_ticks, polling; }; @@ -139,9 +139,9 @@ struct atiixp_info { #define atiixp_wr(_sc, _reg, _val) \ bus_space_write_4((_sc)->st, (_sc)->sh, _reg, _val) -#define atiixp_lock(_sc) snd_mtxlock((_sc)->lock) -#define atiixp_unlock(_sc) snd_mtxunlock((_sc)->lock) -#define atiixp_assert(_sc) snd_mtxassert((_sc)->lock) +#define atiixp_lock(_sc) mtx_lock(&(_sc)->lock) +#define atiixp_unlock(_sc) mtx_unlock(&(_sc)->lock) +#define atiixp_assert(_sc) mtx_assert(&(_sc)->lock, MA_OWNED) static uint32_t atiixp_fmt_32bit[] = { SND_FORMAT(AFMT_S16_LE, 2, 0), @@ -535,8 +535,8 @@ atiixp_chan_setfragments(kobj_t obj, void *data, blksz &= ATI_IXP_BLK_ALIGN; - if (blksz > (sndbuf_getmaxsize(ch->buffer) / ATI_IXP_DMA_CHSEGS_MIN)) - blksz = sndbuf_getmaxsize(ch->buffer) / ATI_IXP_DMA_CHSEGS_MIN; + if (blksz > (ch->buffer->maxsize / ATI_IXP_DMA_CHSEGS_MIN)) + blksz = ch->buffer->maxsize / ATI_IXP_DMA_CHSEGS_MIN; if (blksz < ATI_IXP_BLK_MIN) blksz = ATI_IXP_BLK_MIN; if (blkcnt > ATI_IXP_DMA_CHSEGS_MAX) @@ -544,7 +544,7 @@ atiixp_chan_setfragments(kobj_t obj, void *data, if (blkcnt < ATI_IXP_DMA_CHSEGS_MIN) blkcnt = ATI_IXP_DMA_CHSEGS_MIN; - while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) { + while ((blksz * blkcnt) > ch->buffer->maxsize) { if ((blkcnt >> 1) >= ATI_IXP_DMA_CHSEGS_MIN) blkcnt >>= 1; else if ((blksz >> 1) >= ATI_IXP_BLK_MIN) @@ -553,14 +553,14 @@ atiixp_chan_setfragments(kobj_t obj, void *data, break; } - if ((sndbuf_getblksz(ch->buffer) != blksz || - sndbuf_getblkcnt(ch->buffer) != blkcnt) && + if ((ch->buffer->blksz != blksz || + ch->buffer->blkcnt != blkcnt) && sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n", __func__, blksz, blkcnt); - ch->blksz = sndbuf_getblksz(ch->buffer); - ch->blkcnt = sndbuf_getblkcnt(ch->buffer); + ch->blksz = ch->buffer->blksz; + ch->blkcnt = ch->buffer->blkcnt; return (0); } @@ -583,7 +583,7 @@ atiixp_buildsgdt(struct atiixp_chinfo *ch) uint32_t addr, blksz, blkcnt; int i; - addr = sndbuf_getbufaddr(ch->buffer); + addr = ch->buffer->buf_addr; if (sc->polling != 0) { blksz = ch->blksz * ch->blkcnt; @@ -610,7 +610,7 @@ atiixp_dmapos(struct atiixp_chinfo *ch) volatile uint32_t ptr; reg = ch->dt_cur_bit; - addr = sndbuf_getbufaddr(ch->buffer); + addr = ch->buffer->buf_addr; sz = ch->blkcnt * ch->blksz; retry = ATI_IXP_DMA_RETRY_MAX; @@ -739,8 +739,7 @@ atiixp_chan_trigger(kobj_t obj, void *data, int go) ch->ptr = 0; ch->prevptr = 0; pollticks = ((uint64_t)hz * ch->blksz) / - ((uint64_t)sndbuf_getalign(ch->buffer) * - sndbuf_getspd(ch->buffer)); + ((uint64_t)ch->buffer->align * ch->buffer->spd); pollticks >>= 2; if (pollticks > hz) pollticks = hz; @@ -781,8 +780,8 @@ atiixp_chan_trigger(kobj_t obj, void *data, int go) else ch = &sc->rch; pollticks = ((uint64_t)hz * ch->blksz) / - ((uint64_t)sndbuf_getalign(ch->buffer) * - sndbuf_getspd(ch->buffer)); + ((uint64_t)ch->buffer->align * + ch->buffer->spd); pollticks >>= 2; if (pollticks > hz) pollticks = hz; @@ -1020,7 +1019,7 @@ atiixp_chip_post_init(void *arg) if (sc->codec_not_ready_bits == 0) { /* wait for the interrupts to happen */ do { - msleep(sc, sc->lock, PWAIT, "ixpslp", max(hz / 10, 1)); + msleep(sc, &sc->lock, PWAIT, "ixpslp", max(hz / 10, 1)); if (sc->codec_not_ready_bits != 0) break; } while (--timeout); @@ -1158,10 +1157,7 @@ atiixp_release_resource(struct atiixp_info *sc) bus_dma_tag_destroy(sc->sgd_dmat); sc->sgd_dmat = NULL; } - if (sc->lock) { - snd_mtxfree(sc->lock); - sc->lock = NULL; - } + mtx_destroy(&sc->lock); free(sc, M_DEVBUF); } @@ -1191,7 +1187,8 @@ atiixp_pci_attach(device_t dev) int i; sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_atiixp softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "snd_atiixp softc", + MTX_DEF); sc->dev = dev; callout_init(&sc->poll_timer, 1); diff --git a/sys/dev/sound/pci/cmi.c b/sys/dev/sound/pci/cmi.c index 22f1e76a4d1f..99925d236c08 100644 --- a/sys/dev/sound/pci/cmi.c +++ b/sys/dev/sound/pci/cmi.c @@ -116,7 +116,7 @@ struct sc_info { struct resource *reg, *irq; int regid, irqid; void *ih; - struct mtx *lock; + struct mtx lock; int spdif_enabled; unsigned int bufsz; @@ -255,10 +255,10 @@ cmi_dma_prog(struct sc_info *sc, struct sc_chinfo *ch, u_int32_t base) { u_int32_t s, i, sz; - ch->phys_buf = sndbuf_getbufaddr(ch->buffer); + ch->phys_buf = ch->buffer->buf_addr; cmi_wr(sc, base, ch->phys_buf, 4); - sz = (u_int32_t)sndbuf_getsize(ch->buffer); + sz = (u_int32_t)ch->buffer->bufsize; s = sz / ch->bps - 1; cmi_wr(sc, base + 4, s, 2); @@ -352,7 +352,7 @@ cmichan_init(kobj_t obj, void *devinfo, ch->channel = c; ch->bps = 1; ch->fmt = SND_FORMAT(AFMT_U8, 1, 0); - ch->spd = DSP_DEFAULT_SPEED; + ch->spd = 8000; ch->buffer = b; ch->dma_active = 0; if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) != 0) { @@ -361,13 +361,13 @@ cmichan_init(kobj_t obj, void *devinfo, } ch->dir = dir; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->dir == PCMDIR_PLAY) { cmi_dma_prog(sc, ch, CMPCI_REG_DMA0_BASE); } else { cmi_dma_prog(sc, ch, CMPCI_REG_DMA1_BASE); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return ch; } @@ -394,7 +394,7 @@ cmichan_setformat(kobj_t obj, void *data, u_int32_t format) f |= CMPCI_REG_FORMAT_MONO; } - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->dir == PCMDIR_PLAY) { cmi_partial_wr4(ch->parent, CMPCI_REG_CHANNEL_FORMAT, @@ -408,7 +408,7 @@ cmichan_setformat(kobj_t obj, void *data, u_int32_t format) CMPCI_REG_CH1_FORMAT_MASK, f); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); ch->fmt = format; return 0; @@ -422,7 +422,7 @@ cmichan_setspeed(kobj_t obj, void *data, u_int32_t speed) u_int32_t r, rsp __unused; r = cmpci_rate_to_regvalue(speed); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->dir == PCMDIR_PLAY) { if (speed < 44100) { /* disable if req before rate change */ @@ -450,7 +450,7 @@ cmichan_setspeed(kobj_t obj, void *data, u_int32_t speed) rsp >>= CMPCI_REG_ADC_FS_SHIFT; rsp &= CMPCI_REG_ADC_FS_MASK; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); ch->spd = cmpci_regvalue_to_rate(r); DEB(printf("cmichan_setspeed (%s) %d -> %d (%d)\n", @@ -484,7 +484,7 @@ cmichan_trigger(kobj_t obj, void *data, int go) if (!PCMTRIG_COMMON(go)) return 0; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->dir == PCMDIR_PLAY) { switch(go) { case PCMTRIG_START: @@ -506,7 +506,7 @@ cmichan_trigger(kobj_t obj, void *data, int go) break; } } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -517,15 +517,15 @@ cmichan_getptr(kobj_t obj, void *data) struct sc_info *sc = ch->parent; u_int32_t physptr, bufptr, sz; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->dir == PCMDIR_PLAY) { physptr = cmi_rd(sc, CMPCI_REG_DMA0_BASE, 4); } else { physptr = cmi_rd(sc, CMPCI_REG_DMA1_BASE, 4); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); - sz = sndbuf_getsize(ch->buffer); + sz = ch->buffer->bufsize; bufptr = (physptr - ch->phys_buf + sz - ch->bps) % sz; return bufptr; @@ -538,7 +538,7 @@ cmi_intr(void *data) u_int32_t intrstat; u_int32_t toclear; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); intrstat = cmi_rd(sc, CMPCI_REG_INTR_STATUS, 4); if ((intrstat & CMPCI_REG_ANY_INTR) != 0) { toclear = 0; @@ -554,7 +554,7 @@ cmi_intr(void *data) if (toclear) { cmi_clr4(sc, CMPCI_REG_INTR_CTRL, toclear); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); /* Signal interrupts to channel */ if (intrstat & CMPCI_REG_CH0_INTR) { @@ -565,14 +565,14 @@ cmi_intr(void *data) chn_intr(sc->rch.channel); } - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); cmi_set4(sc, CMPCI_REG_INTR_CTRL, toclear); } } if(sc->mpu_intr) { (sc->mpu_intr)(sc->mpu); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return; } @@ -799,10 +799,10 @@ cmi_muninit(struct mpu401 *arg, void *cookie) { struct sc_info *sc = cookie; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->mpu_intr = NULL; sc->mpu = NULL; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -933,7 +933,8 @@ cmi_attach(device_t dev) char status[SND_STATUSLEN]; sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_cmi softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "snd_cmi softc", + MTX_DEF); pci_enable_busmaster(dev); sc->dev = dev; @@ -1007,8 +1008,7 @@ cmi_attach(device_t dev) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); if (sc->reg) bus_release_resource(dev, SYS_RES_IOPORT, sc->regid, sc->reg); - if (sc->lock) - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); if (sc) free(sc, M_DEVBUF); @@ -1037,7 +1037,7 @@ cmi_detach(device_t dev) if (sc->mpu_reg) bus_release_resource(dev, SYS_RES_IOPORT, sc->mpu_regid, sc->mpu_reg); - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); free(sc, M_DEVBUF); return 0; @@ -1048,11 +1048,11 @@ cmi_suspend(device_t dev) { struct sc_info *sc = pcm_getdevinfo(dev); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->pch.dma_was_active = cmi_ch0_stop(sc, &sc->pch); sc->rch.dma_was_active = cmi_ch1_stop(sc, &sc->rch); cmi_power(sc, 3); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -1061,17 +1061,17 @@ cmi_resume(device_t dev) { struct sc_info *sc = pcm_getdevinfo(dev); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); cmi_power(sc, 0); if (cmi_init(sc) != 0) { device_printf(dev, "unable to reinitialize the card\n"); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return ENXIO; } if (mixer_reinit(dev) == -1) { device_printf(dev, "unable to reinitialize the mixer\n"); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return ENXIO; } @@ -1086,7 +1086,7 @@ cmi_resume(device_t dev) cmichan_setformat(NULL, &sc->rch, sc->rch.fmt); cmi_ch1_start(sc, &sc->rch); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } diff --git a/sys/dev/sound/pci/cs4281.c b/sys/dev/sound/pci/cs4281.c index 7a25f7f4c08d..5b0b229a021b 100644 --- a/sys/dev/sound/pci/cs4281.c +++ b/sys/dev/sound/pci/cs4281.c @@ -326,9 +326,9 @@ cs4281chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channe ch->channel = c; ch->fmt = SND_FORMAT(AFMT_U8, 1, 0); - ch->spd = DSP_DEFAULT_SPEED; + ch->spd = 8000; ch->bps = 1; - ch->blksz = sndbuf_getsize(ch->buffer); + ch->blksz = ch->buffer->bufsize; ch->dma_chan = (dir == PCMDIR_PLAY) ? CS4281_DMA_PLAY : CS4281_DMA_REC; ch->dma_setup = 0; @@ -412,7 +412,7 @@ cs4281chan_getptr(kobj_t obj, void *data) u_int32_t dba, dca, ptr; int sz; - sz = sndbuf_getsize(ch->buffer); + sz = ch->buffer->bufsize; dba = cs4281_rd(sc, CS4281PCI_DBA(ch->dma_chan)); dca = cs4281_rd(sc, CS4281PCI_DCA(ch->dma_chan)); ptr = (dca - dba + sz) % sz; @@ -493,9 +493,9 @@ adcdac_prog(struct sc_chinfo *ch) if (!ch->dma_setup) { go = adcdac_go(ch, 0); cs4281_wr(sc, CS4281PCI_DBA(ch->dma_chan), - sndbuf_getbufaddr(ch->buffer)); + ch->buffer->buf_addr); cs4281_wr(sc, CS4281PCI_DBC(ch->dma_chan), - sndbuf_getsize(ch->buffer) / ch->bps - 1); + ch->buffer->bufsize / ch->bps - 1); ch->dma_setup = 1; adcdac_go(ch, go); } diff --git a/sys/dev/sound/pci/csapcm.c b/sys/dev/sound/pci/csapcm.c index a966a2e66402..688aee6400d8 100644 --- a/sys/dev/sound/pci/csapcm.c +++ b/sys/dev/sound/pci/csapcm.c @@ -483,7 +483,7 @@ csa_setupchan(struct csa_chinfo *ch) if (ch->dir == PCMDIR_PLAY) { /* direction */ - csa_writemem(resp, BA1_PBA, sndbuf_getbufaddr(ch->buffer)); + csa_writemem(resp, BA1_PBA, ch->buffer->buf_addr); /* format */ csa->pfie = csa_readmem(resp, BA1_PFIE) & ~0x0000f03f; @@ -512,7 +512,7 @@ csa_setupchan(struct csa_chinfo *ch) csa_setplaysamplerate(resp, ch->spd); } else if (ch->dir == PCMDIR_REC) { /* direction */ - csa_writemem(resp, BA1_CBA, sndbuf_getbufaddr(ch->buffer)); + csa_writemem(resp, BA1_CBA, ch->buffer->buf_addr); /* format */ csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001); @@ -602,11 +602,11 @@ csachan_getptr(kobj_t obj, void *data) resp = &csa->res; if (ch->dir == PCMDIR_PLAY) { - ptr = csa_readmem(resp, BA1_PBA) - sndbuf_getbufaddr(ch->buffer); + ptr = csa_readmem(resp, BA1_PBA) - ch->buffer->buf_addr; if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0) ptr >>= 1; } else { - ptr = csa_readmem(resp, BA1_CBA) - sndbuf_getbufaddr(ch->buffer); + ptr = csa_readmem(resp, BA1_CBA) - ch->buffer->buf_addr; if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0) ptr >>= 1; } diff --git a/sys/dev/sound/pci/emu10k1.c b/sys/dev/sound/pci/emu10k1.c index e4b2c22f4f07..da2ddc99f5a1 100644 --- a/sys/dev/sound/pci/emu10k1.c +++ b/sys/dev/sound/pci/emu10k1.c @@ -218,7 +218,7 @@ struct sc_info { struct resource *reg, *irq; void *ih; - struct mtx *lock; + struct mtx lock; unsigned int bufsz; int timer, timerinterval; @@ -413,7 +413,7 @@ emu_settimer(struct sc_info *sc) for (i = 0; i < sc->nchans; i++) { pch = &sc->pch[i]; if (pch->buffer) { - tmp = (pch->spd * sndbuf_getalign(pch->buffer)) + tmp = (pch->spd * pch->buffer->align) / pch->blksz; if (tmp > rate) rate = tmp; @@ -423,7 +423,7 @@ emu_settimer(struct sc_info *sc) for (i = 0; i < 3; i++) { rch = &sc->rch[i]; if (rch->buffer) { - tmp = (rch->spd * sndbuf_getalign(rch->buffer)) + tmp = (rch->spd * rch->buffer->align) / rch->blksz; if (tmp > rate) rate = tmp; @@ -820,10 +820,10 @@ emupchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, ch->blksz = sc->bufsz / 2; ch->fmt = SND_FORMAT(AFMT_U8, 1, 0); ch->spd = 8000; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); ch->master = emu_valloc(sc); ch->slave = emu_valloc(sc); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); r = (emu_vinit(sc, ch->master, ch->slave, sc->bufsz, ch->buffer)) ? NULL : ch; @@ -837,9 +837,9 @@ emupchan_free(kobj_t obj, void *data) struct sc_info *sc = ch->parent; int r; - snd_mtxlock(sc->lock); - r = emu_memfree(sc, sndbuf_getbuf(ch->buffer)); - snd_mtxunlock(sc->lock); + mtx_lock(&sc->lock); + r = emu_memfree(sc, ch->buffer->buf); + mtx_unlock(&sc->lock); return r; } @@ -869,9 +869,9 @@ emupchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) struct sc_info *sc = ch->parent; ch->blksz = blocksize; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); emu_settimer(sc); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return blocksize; } @@ -884,7 +884,7 @@ emupchan_trigger(kobj_t obj, void *data, int go) if (!PCMTRIG_COMMON(go)) return 0; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (go == PCMTRIG_START) { emu_vsetup(ch); emu_vwrite(sc, ch->master); @@ -901,7 +901,7 @@ emupchan_trigger(kobj_t obj, void *data, int go) } ch->run = (go == PCMTRIG_START) ? 1 : 0; emu_vtrigger(sc, ch->master, ch->run); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -912,9 +912,9 @@ emupchan_getptr(kobj_t obj, void *data) struct sc_info *sc = ch->parent; int r; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); r = emu_vpos(sc, ch->master); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return r; } @@ -984,10 +984,10 @@ emurchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) != 0) return NULL; else { - snd_mtxlock(sc->lock); - emu_wrptr(sc, 0, ch->basereg, sndbuf_getbufaddr(ch->buffer)); + mtx_lock(&sc->lock); + emu_wrptr(sc, 0, ch->basereg, ch->buffer->buf_addr); emu_wrptr(sc, 0, ch->sizereg, 0); /* off */ - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return ch; } } @@ -1027,9 +1027,9 @@ emurchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) struct sc_info *sc = ch->parent; ch->blksz = blocksize; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); emu_settimer(sc); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return blocksize; } @@ -1069,7 +1069,7 @@ emurchan_trigger(kobj_t obj, void *data, int go) sz = EMU_RECBS_BUFSIZE_4096; } - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); switch(go) { case PCMTRIG_START: ch->run = 1; @@ -1111,7 +1111,7 @@ emurchan_trigger(kobj_t obj, void *data, int go) default: break; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -1123,9 +1123,9 @@ emurchan_getptr(kobj_t obj, void *data) struct sc_info *sc = ch->parent; int r; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); r = emu_rdptr(sc, 0, ch->idxreg) & 0x0000ffff; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return r; } @@ -1171,9 +1171,9 @@ emu_muninit(struct mpu401 *arg, void *cookie) { struct sc_info *sc = cookie; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->mpu_intr = NULL; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -1216,7 +1216,7 @@ emu_intr(void *data) struct sc_info *sc = data; u_int32_t stat, ack, i, x; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); while (1) { stat = emu_rd(sc, EMU_IPR, 4); if (stat == 0) @@ -1262,7 +1262,7 @@ emu_intr(void *data) emu_wr(sc, EMU_IPR, stat, 4); if (ack) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); if (ack & EMU_IPR_INTERVALTIMER) { x = 0; @@ -1289,10 +1289,10 @@ emu_intr(void *data) chn_intr(sc->rch[2].channel); } - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); } /* -------------------------------------------------------------------- */ @@ -2071,7 +2071,8 @@ emu_pci_attach(device_t dev) char status[SND_STATUSLEN]; sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_emu10k1 softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "snd_emu10k1 softc", + MTX_DEF); sc->dev = dev; sc->type = pci_get_devid(dev); sc->rev = pci_get_revid(dev); @@ -2147,7 +2148,7 @@ bad: if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih); if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); if (sc->parent_dmat) bus_dma_tag_destroy(sc->parent_dmat); - if (sc->lock) snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); free(sc, M_DEVBUF); return ENXIO; } @@ -2170,7 +2171,7 @@ emu_pci_detach(device_t dev) bus_teardown_intr(dev, sc->irq, sc->ih); bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); bus_dma_tag_destroy(sc->parent_dmat); - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); free(sc, M_DEVBUF); return 0; diff --git a/sys/dev/sound/pci/emu10kx-pcm.c b/sys/dev/sound/pci/emu10kx-pcm.c index c280b64892f6..25b0006e4122 100644 --- a/sys/dev/sound/pci/emu10kx-pcm.c +++ b/sys/dev/sound/pci/emu10kx-pcm.c @@ -90,7 +90,7 @@ struct emu_pcm_rchinfo { #endif struct emu_pcm_info { - struct mtx *lock; + struct mtx lock; device_t dev; /* device information */ struct emu_sc_info *card; struct emu_pcm_pchinfo pch[MAX_CHANNELS]; /* hardware channels */ @@ -771,10 +771,10 @@ emupchan_setblocksize(kobj_t obj __unused, void *c_devinfo, uint32_t blocksize) if (blocksize > ch->pcm->bufsz) blocksize = ch->pcm->bufsz; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); ch->blksz = blocksize; - emu_timer_set(sc->card, ch->timer, ch->blksz / sndbuf_getalign(ch->buffer)); - snd_mtxunlock(sc->lock); + emu_timer_set(sc->card, ch->timer, ch->blksz / ch->buffer->align); + mtx_unlock(&sc->lock); return (ch->blksz); } @@ -787,7 +787,7 @@ emupchan_trigger(kobj_t obj __unused, void *c_devinfo, int go) if (!PCMTRIG_COMMON(go)) return (0); - snd_mtxlock(sc->lock); /* XXX can we trigger on parallel threads ? */ + mtx_lock(&sc->lock); /* XXX can we trigger on parallel threads ? */ if (go == PCMTRIG_START) { emu_vsetup(ch->master, ch->fmt, ch->spd); if (AFMT_CHANNEL(ch->fmt) > 1) @@ -795,13 +795,14 @@ emupchan_trigger(kobj_t obj __unused, void *c_devinfo, int go) else emu_vroute(sc->card, &(sc->rt_mono), ch->master); emu_vwrite(sc->card, ch->master); - emu_timer_set(sc->card, ch->timer, ch->blksz / sndbuf_getalign(ch->buffer)); + emu_timer_set(sc->card, ch->timer, ch->blksz / + ch->buffer->align); emu_timer_enable(sc->card, ch->timer, 1); } /* PCM interrupt handler will handle PCMTRIG_STOP event */ ch->run = (go == PCMTRIG_START) ? 1 : 0; emu_vtrigger(sc->card, ch->master, ch->run); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -878,7 +879,7 @@ emurchan_init(kobj_t obj __unused, void *devinfo, struct snd_dbuf *b, struct pcm return (NULL); else { ch->timer = emu_timer_create(sc->card); - emu_wrptr(sc->card, 0, ch->basereg, sndbuf_getbufaddr(ch->buffer)); + emu_wrptr(sc->card, 0, ch->basereg, ch->buffer->buf_addr); emu_wrptr(sc->card, 0, ch->sizereg, 0); /* off */ return (ch); } @@ -930,7 +931,8 @@ emurchan_setblocksize(kobj_t obj __unused, void *c_devinfo, uint32_t blocksize) * (and use) timer interrupts. Otherwise channel will be marked dead. */ if (ch->blksz < (ch->pcm->bufsz / 2)) { - emu_timer_set(sc->card, ch->timer, ch->blksz / sndbuf_getalign(ch->buffer)); + emu_timer_set(sc->card, ch->timer, ch->blksz / + ch->buffer->align); emu_timer_enable(sc->card, ch->timer, 1); } else { emu_timer_enable(sc->card, ch->timer, 0); @@ -968,7 +970,7 @@ emurchan_trigger(kobj_t obj __unused, void *c_devinfo, int go) sz = EMU_RECBS_BUFSIZE_4096; } - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); switch (go) { case PCMTRIG_START: ch->run = 1; @@ -997,7 +999,7 @@ emurchan_trigger(kobj_t obj __unused, void *c_devinfo, int go) default: break; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -1059,7 +1061,7 @@ emufxrchan_init(kobj_t obj __unused, void *devinfo, struct snd_dbuf *b, struct p if (sndbuf_alloc(ch->buffer, emu_gettag(sc->card), 0, sc->bufsz) != 0) return (NULL); else { - emu_wrptr(sc->card, 0, ch->basereg, sndbuf_getbufaddr(ch->buffer)); + emu_wrptr(sc->card, 0, ch->basereg, ch->buffer->buf_addr); emu_wrptr(sc->card, 0, ch->sizereg, 0); /* off */ return (ch); } @@ -1128,7 +1130,7 @@ emufxrchan_trigger(kobj_t obj __unused, void *c_devinfo, int go) sz = EMU_RECBS_BUFSIZE_4096; } - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); switch (go) { case PCMTRIG_START: ch->run = 1; @@ -1167,7 +1169,7 @@ emufxrchan_trigger(kobj_t obj __unused, void *c_devinfo, int go) default: break; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -1232,24 +1234,24 @@ emu_pcm_intr(void *pcm, uint32_t stat) ack = 0; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (stat & EMU_IPR_INTERVALTIMER) { ack |= EMU_IPR_INTERVALTIMER; for (i = 0; i < MAX_CHANNELS; i++) if (sc->pch[i].channel) { if (sc->pch[i].run == 1) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(sc->pch[i].channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } else emu_timer_enable(sc->card, sc->pch[i].timer, 0); } /* ADC may install timer to get low-latency interrupts */ if ((sc->rch_adc.channel) && (sc->rch_adc.run)) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(sc->rch_adc.channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } /* * EFX does not use timer, because it will fill @@ -1260,21 +1262,21 @@ emu_pcm_intr(void *pcm, uint32_t stat) if (stat & (EMU_IPR_ADCBUFFULL | EMU_IPR_ADCBUFHALFFULL)) { ack |= stat & (EMU_IPR_ADCBUFFULL | EMU_IPR_ADCBUFHALFFULL); if (sc->rch_adc.channel) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(sc->rch_adc.channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } } if (stat & (EMU_IPR_EFXBUFFULL | EMU_IPR_EFXBUFHALFFULL)) { ack |= stat & (EMU_IPR_EFXBUFFULL | EMU_IPR_EFXBUFHALFFULL); if (sc->rch_efx.channel) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(sc->rch_efx.channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (ack); } @@ -1347,7 +1349,8 @@ emu_pcm_attach(device_t dev) return (ENXIO); } - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_emu10kx pcm softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "snd_emu10kx pcm softc", + MTX_DEF); sc->dev = dev; BUS_READ_IVAR(device_get_parent(dev), dev, EMU_VAR_ISEMU10K1, &ivar); @@ -1481,8 +1484,7 @@ emu_pcm_attach(device_t dev) bad: if (sc->codec) ac97_destroy(sc->codec); - if (sc->lock) - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); free(sc, M_DEVBUF); return (ENXIO); } @@ -1501,8 +1503,7 @@ emu_pcm_detach(device_t dev) emu_pcm_uninit(sc); - if (sc->lock) - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); free(sc, M_DEVBUF); return (0); diff --git a/sys/dev/sound/pci/envy24.c b/sys/dev/sound/pci/envy24.c index 51842bfdb480..3adb22254b72 100644 --- a/sys/dev/sound/pci/envy24.c +++ b/sys/dev/sound/pci/envy24.c @@ -116,7 +116,7 @@ struct cfg_info { /* device private data */ struct sc_info { device_t dev; - struct mtx *lock; + struct mtx lock; /* Control/Status registor */ struct resource *cs; @@ -1567,10 +1567,10 @@ envy24chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channe #if(0) device_printf(sc->dev, "envy24chan_init(obj, devinfo, b, c, %d)\n", dir); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if ((sc->chnum > ENVY24_CHAN_PLAY_SPDIF && dir != PCMDIR_REC) || (sc->chnum < ENVY24_CHAN_REC_ADC1 && dir != PCMDIR_PLAY)) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return NULL; } num = sc->chnum; @@ -1589,14 +1589,14 @@ envy24chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channe ch->dir = dir; /* set channel map */ ch->num = envy24_chanmap[num]; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); sndbuf_setup(ch->buffer, ch->data, ch->size); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); /* these 2 values are dummy */ ch->unit = 4; ch->blk = 10240; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return ch; } @@ -1610,12 +1610,12 @@ envy24chan_free(kobj_t obj, void *data) #if(0) device_printf(sc->dev, "envy24chan_free()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->data != NULL) { free(ch->data, M_ENVY24); ch->data = NULL; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -1632,21 +1632,21 @@ envy24chan_setformat(kobj_t obj, void *data, u_int32_t format) #if(0) device_printf(sc->dev, "envy24chan_setformat(obj, data, 0x%08x)\n", format); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); /* check and get format related information */ if (ch->dir == PCMDIR_PLAY) emltab = envy24_pemltab; else emltab = envy24_remltab; if (emltab == NULL) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return -1; } for (i = 0; emltab[i].format != 0; i++) if (emltab[i].format == format) break; if (emltab[i].format == 0) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return -1; } @@ -1670,7 +1670,7 @@ envy24chan_setformat(kobj_t obj, void *data, u_int32_t format) bcnt = ch->size / bsize; sndbuf_resize(ch->buffer, bcnt, bsize); #endif - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); #if(0) device_printf(sc->dev, "envy24chan_setformat(): return 0x%08x\n", 0); @@ -1723,7 +1723,7 @@ envy24chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) device_printf(sc->dev, "envy24chan_setblocksize(obj, data, %d)\n", blocksize); #endif prev = 0x7fffffff; - /* snd_mtxlock(sc->lock); */ + /* mtx_lock(&sc->lock); */ for (size = ch->size / 2; size > 0; size /= 2) { if (abs(size - blocksize) < abs(prev - blocksize)) prev = size; @@ -1745,7 +1745,7 @@ envy24chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) bsize *= ch->unit; bcnt = ch->size / bsize; sndbuf_resize(ch->buffer, bcnt, bsize); - /* snd_mtxunlock(sc->lock); */ + /* mtx_unlock(&sc->lock); */ #if(0) device_printf(sc->dev, "envy24chan_setblocksize(): return %d\n", prev); @@ -1767,7 +1767,7 @@ envy24chan_trigger(kobj_t obj, void *data, int go) device_printf(sc->dev, "envy24chan_trigger(obj, data, %d)\n", go); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->dir == PCMDIR_PLAY) slot = 0; else @@ -1862,7 +1862,7 @@ envy24chan_trigger(kobj_t obj, void *data, int go) break; } fail: - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (error); } @@ -1876,10 +1876,10 @@ envy24chan_getptr(kobj_t obj, void *data) #if(0) device_printf(sc->dev, "envy24chan_getptr()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); ptr = envy24_gethwptr(sc, ch->dir); rtn = ptr * ch->unit; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); #if(0) device_printf(sc->dev, "envy24chan_getptr(): return %d\n", @@ -1898,7 +1898,7 @@ envy24chan_getcaps(kobj_t obj, void *data) #if(0) device_printf(sc->dev, "envy24chan_getcaps()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->dir == PCMDIR_PLAY) { if (sc->run[0] == 0) rtn = &envy24_playcaps; @@ -1911,7 +1911,7 @@ envy24chan_getcaps(kobj_t obj, void *data) else rtn = &sc->caps[1]; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return rtn; } @@ -1945,12 +1945,12 @@ envy24mixer_init(struct snd_mixer *m) return -1; /* set volume control rate */ - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); envy24_wrmt(sc, ENVY24_MT_VOLRATE, 0x30, 1); /* 0x30 is default value */ mix_setdevs(m, ENVY24_MIX_MASK); mix_setrecdevs(m, ENVY24_MIX_REC_MASK); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -2003,7 +2003,7 @@ envy24mixer_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right dev, left, right); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (dev == 0) { for (i = 0; i < sc->dacn; i++) { sc->cfg->codec->setvolume(sc->dac[i], PCMDIR_PLAY, left, right); @@ -2020,7 +2020,7 @@ envy24mixer_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right if (hwch > ENVY24_CHAN_PLAY_SPDIF || sc->chan[ch].run) envy24_setvolume(sc, hwch); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return right << 8 | left; } @@ -2063,7 +2063,7 @@ envy24_intr(void *p) #if(0) device_printf(sc->dev, "envy24_intr()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (envy24_checkintr(sc, PCMDIR_PLAY)) { #if(0) device_printf(sc->dev, "envy24_intr(): play\n"); @@ -2085,9 +2085,9 @@ envy24_intr(void *p) device_printf(sc->dev, "envy24_intr(): chan[%d].blk = %d\n", i, ch->blk); #endif if (ch->run && ch->blk <= feed) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(ch->channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } } sc->intr[0] = ptr; @@ -2104,15 +2104,15 @@ envy24_intr(void *p) for (i = ENVY24_CHAN_REC_ADC1; i <= ENVY24_CHAN_REC_SPDIF; i++) { ch = &sc->chan[i]; if (ch->run && ch->blk <= feed) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(ch->channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } } sc->intr[1] = ptr; envy24_updintr(sc, PCMDIR_REC); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return; } @@ -2551,7 +2551,8 @@ envy24_pci_attach(device_t dev) } bzero(sc, sizeof(*sc)); - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_envy24 softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "snd_envy24 softc", + MTX_DEF); sc->dev = dev; /* initialize PCI interface */ @@ -2627,8 +2628,7 @@ bad: bus_release_resource(dev, SYS_RES_IOPORT, sc->dsid, sc->ds); if (sc->mt) bus_release_resource(dev, SYS_RES_IOPORT, sc->mtid, sc->mt); - if (sc->lock) - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); free(sc, M_ENVY24); return err; } @@ -2665,7 +2665,7 @@ envy24_pci_detach(device_t dev) bus_release_resource(dev, SYS_RES_IOPORT, sc->ddmaid, sc->ddma); bus_release_resource(dev, SYS_RES_IOPORT, sc->dsid, sc->ds); bus_release_resource(dev, SYS_RES_IOPORT, sc->mtid, sc->mt); - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); free(sc, M_ENVY24); return 0; } diff --git a/sys/dev/sound/pci/envy24ht.c b/sys/dev/sound/pci/envy24ht.c index b8202a9fa7cd..2396a340cd84 100644 --- a/sys/dev/sound/pci/envy24ht.c +++ b/sys/dev/sound/pci/envy24ht.c @@ -125,7 +125,7 @@ struct cfg_info { /* device private data */ struct sc_info { device_t dev; - struct mtx *lock; + struct mtx lock; /* Control/Status registor */ struct resource *cs; @@ -1476,11 +1476,11 @@ envy24htchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_chan #if(0) device_printf(sc->dev, "envy24htchan_init(obj, devinfo, b, c, %d)\n", dir); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); #if 0 if ((sc->chnum > ENVY24HT_CHAN_PLAY_SPDIF && dir != PCMDIR_REC) || (sc->chnum < ENVY24HT_CHAN_REC_ADC1 && dir != PCMDIR_PLAY)) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return NULL; } #endif @@ -1500,14 +1500,14 @@ envy24htchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_chan ch->dir = dir; /* set channel map */ ch->num = envy24ht_chanmap[num]; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); sndbuf_setup(ch->buffer, ch->data, ch->size); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); /* these 2 values are dummy */ ch->unit = 4; ch->blk = 10240; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return ch; } @@ -1521,12 +1521,12 @@ envy24htchan_free(kobj_t obj, void *data) #if(0) device_printf(sc->dev, "envy24htchan_free()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->data != NULL) { free(ch->data, M_ENVY24HT); ch->data = NULL; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -1543,21 +1543,21 @@ envy24htchan_setformat(kobj_t obj, void *data, u_int32_t format) #if(0) device_printf(sc->dev, "envy24htchan_setformat(obj, data, 0x%08x)\n", format); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); /* check and get format related information */ if (ch->dir == PCMDIR_PLAY) emltab = envy24ht_pemltab; else emltab = envy24ht_remltab; if (emltab == NULL) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return -1; } for (i = 0; emltab[i].format != 0; i++) if (emltab[i].format == format) break; if (emltab[i].format == 0) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return -1; } @@ -1581,7 +1581,7 @@ envy24htchan_setformat(kobj_t obj, void *data, u_int32_t format) bcnt = ch->size / bsize; sndbuf_resize(ch->buffer, bcnt, bsize); #endif - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); #if(0) device_printf(sc->dev, "envy24htchan_setformat(): return 0x%08x\n", 0); @@ -1634,7 +1634,7 @@ envy24htchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) device_printf(sc->dev, "envy24htchan_setblocksize(obj, data, %d)\n", blocksize); #endif prev = 0x7fffffff; - /* snd_mtxlock(sc->lock); */ + /* mtx_lock(&sc->lock); */ for (size = ch->size / 2; size > 0; size /= 2) { if (abs(size - blocksize) < abs(prev - blocksize)) prev = size; @@ -1656,7 +1656,7 @@ envy24htchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) bsize *= ch->unit; bcnt = ch->size / bsize; sndbuf_resize(ch->buffer, bcnt, bsize); - /* snd_mtxunlock(sc->lock); */ + /* mtx_unlock(&sc->lock); */ #if(0) device_printf(sc->dev, "envy24htchan_setblocksize(): return %d\n", prev); @@ -1678,7 +1678,7 @@ envy24htchan_trigger(kobj_t obj, void *data, int go) device_printf(sc->dev, "envy24htchan_trigger(obj, data, %d)\n", go); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->dir == PCMDIR_PLAY) slot = 0; else @@ -1771,7 +1771,7 @@ envy24htchan_trigger(kobj_t obj, void *data, int go) break; } fail: - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (error); } @@ -1785,10 +1785,10 @@ envy24htchan_getptr(kobj_t obj, void *data) #if(0) device_printf(sc->dev, "envy24htchan_getptr()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); ptr = envy24ht_gethwptr(sc, ch->dir); rtn = ptr * ch->unit; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); #if(0) device_printf(sc->dev, "envy24htchan_getptr(): return %d\n", @@ -1807,7 +1807,7 @@ envy24htchan_getcaps(kobj_t obj, void *data) #if(0) device_printf(sc->dev, "envy24htchan_getcaps()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->dir == PCMDIR_PLAY) { if (sc->run[0] == 0) rtn = &envy24ht_playcaps; @@ -1820,7 +1820,7 @@ envy24htchan_getcaps(kobj_t obj, void *data) else rtn = &sc->caps[1]; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return rtn; } @@ -1854,7 +1854,7 @@ envy24htmixer_init(struct snd_mixer *m) return -1; /* set volume control rate */ - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); #if 0 envy24ht_wrmt(sc, ENVY24HT_MT_VOLRATE, 0x30, 1); /* 0x30 is default value */ #endif @@ -1864,7 +1864,7 @@ envy24htmixer_init(struct snd_mixer *m) mix_setdevs(m, ENVY24HT_MIX_MASK); mix_setrecdevs(m, ENVY24HT_MIX_REC_MASK); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return 0; } @@ -1917,7 +1917,7 @@ envy24htmixer_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned rig dev, left, right); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (dev == 0) { for (i = 0; i < sc->dacn; i++) { sc->cfg->codec->setvolume(sc->dac[i], PCMDIR_PLAY, left, right); @@ -1934,7 +1934,7 @@ envy24htmixer_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned rig if (hwch > ENVY24HT_CHAN_PLAY_SPDIF || sc->chan[ch].run) envy24ht_setvolume(sc, hwch); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return right << 8 | left; } @@ -1977,7 +1977,7 @@ envy24ht_intr(void *p) #if(0) device_printf(sc->dev, "envy24ht_intr()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (envy24ht_checkintr(sc, PCMDIR_PLAY)) { #if(0) device_printf(sc->dev, "envy24ht_intr(): play\n"); @@ -1999,9 +1999,9 @@ envy24ht_intr(void *p) device_printf(sc->dev, "envy24ht_intr(): chan[%d].blk = %d\n", i, ch->blk); #endif if (ch->run && ch->blk <= feed) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(ch->channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } } sc->intr[0] = ptr; @@ -2018,15 +2018,15 @@ envy24ht_intr(void *p) for (i = ENVY24HT_CHAN_REC_ADC1; i <= ENVY24HT_CHAN_REC_SPDIF; i++) { ch = &sc->chan[i]; if (ch->run && ch->blk <= feed) { - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(ch->channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } } sc->intr[1] = ptr; envy24ht_updintr(sc, PCMDIR_REC); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return; } @@ -2455,8 +2455,8 @@ envy24ht_pci_attach(device_t dev) } bzero(sc, sizeof(*sc)); - sc->lock = snd_mtxcreate(device_get_nameunit(dev), - "snd_envy24ht softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "snd_eny24ht softc", + MTX_DEF); sc->dev = dev; /* initialize PCI interface */ @@ -2524,8 +2524,7 @@ bad: bus_release_resource(dev, SYS_RES_IOPORT, sc->csid, sc->cs); if (sc->mt) bus_release_resource(dev, SYS_RES_IOPORT, sc->mtid, sc->mt); - if (sc->lock) - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); free(sc, M_ENVY24HT); return err; } @@ -2560,7 +2559,7 @@ envy24ht_pci_detach(device_t dev) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); bus_release_resource(dev, SYS_RES_IOPORT, sc->csid, sc->cs); bus_release_resource(dev, SYS_RES_IOPORT, sc->mtid, sc->mt); - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); free(sc, M_ENVY24HT); return 0; } diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c index 3c1bea09b5d1..cc51005309b0 100644 --- a/sys/dev/sound/pci/es137x.c +++ b/sys/dev/sound/pci/es137x.c @@ -224,14 +224,14 @@ struct es_info { uint32_t sctrl; uint32_t escfg; struct es_chinfo ch[ES_NCHANS]; - struct mtx *lock; + struct mtx lock; struct callout poll_timer; int poll_ticks, polling; }; -#define ES_LOCK(sc) snd_mtxlock((sc)->lock) -#define ES_UNLOCK(sc) snd_mtxunlock((sc)->lock) -#define ES_LOCK_ASSERT(sc) snd_mtxassert((sc)->lock) +#define ES_LOCK(sc) mtx_lock(&(sc)->lock) +#define ES_UNLOCK(sc) mtx_unlock(&(sc)->lock) +#define ES_LOCK_ASSERT(sc) mtx_assert(&(sc)->lock, MA_OWNED) /* prototypes */ static void es_intr(void *); @@ -508,21 +508,21 @@ eschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, es_wr(es, ES1370_REG_MEMPAGE, ES1370_REG_DAC1_FRAMEADR >> 8, 1); es_wr(es, ES1370_REG_DAC1_FRAMEADR & 0xff, - sndbuf_getbufaddr(ch->buffer), 4); + ch->buffer->buf_addr, 4); es_wr(es, ES1370_REG_DAC1_FRAMECNT & 0xff, (ch->bufsz >> 2) - 1, 4); } else { es_wr(es, ES1370_REG_MEMPAGE, ES1370_REG_DAC2_FRAMEADR >> 8, 1); es_wr(es, ES1370_REG_DAC2_FRAMEADR & 0xff, - sndbuf_getbufaddr(ch->buffer), 4); + ch->buffer->buf_addr, 4); es_wr(es, ES1370_REG_DAC2_FRAMECNT & 0xff, (ch->bufsz >> 2) - 1, 4); } } else { es_wr(es, ES1370_REG_MEMPAGE, ES1370_REG_ADC_FRAMEADR >> 8, 1); es_wr(es, ES1370_REG_ADC_FRAMEADR & 0xff, - sndbuf_getbufaddr(ch->buffer), 4); + ch->buffer->buf_addr, 4); es_wr(es, ES1370_REG_ADC_FRAMECNT & 0xff, (ch->bufsz >> 2) - 1, 4); } @@ -637,8 +637,8 @@ eschan_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt) blksz &= ES_BLK_ALIGN; - if (blksz > (sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN)) - blksz = sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN; + if (blksz > (ch->buffer->maxsize / ES_DMA_SEGS_MIN)) + blksz = ch->buffer->maxsize / ES_DMA_SEGS_MIN; if (blksz < ES_BLK_MIN) blksz = ES_BLK_MIN; if (blkcnt > ES_DMA_SEGS_MAX) @@ -646,7 +646,7 @@ eschan_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt) if (blkcnt < ES_DMA_SEGS_MIN) blkcnt = ES_DMA_SEGS_MIN; - while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) { + while ((blksz * blkcnt) > ch->buffer->maxsize) { if ((blkcnt >> 1) >= ES_DMA_SEGS_MIN) blkcnt >>= 1; else if ((blksz >> 1) >= ES_BLK_MIN) @@ -655,15 +655,15 @@ eschan_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt) break; } - if ((sndbuf_getblksz(ch->buffer) != blksz || - sndbuf_getblkcnt(ch->buffer) != blkcnt) && + if ((ch->buffer->blksz != blksz || + ch->buffer->blkcnt != blkcnt) && sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) device_printf(es->dev, "%s: failed blksz=%u blkcnt=%u\n", __func__, blksz, blkcnt); - ch->bufsz = sndbuf_getsize(ch->buffer); - ch->blksz = sndbuf_getblksz(ch->buffer); - ch->blkcnt = sndbuf_getblkcnt(ch->buffer); + ch->bufsz = ch->buffer->bufsize; + ch->blksz = ch->buffer->blksz; + ch->blkcnt = ch->buffer->blkcnt; return (0); } @@ -762,7 +762,7 @@ eschan_trigger(kobj_t obj, void *data, int go) return 0; ES_LOCK(es); - cnt = (ch->blksz / sndbuf_getalign(ch->buffer)) - 1; + cnt = (ch->blksz / ch->buffer->align) - 1; if (ch->fmt & AFMT_16BIT) b |= 0x02; if (AFMT_CHANNEL(ch->fmt) > 1) @@ -987,7 +987,7 @@ es1370_init(struct es_info *es) es->escfg = ES_SET_FIXED_RATE(es->escfg, fixed_rate); else { es->escfg = ES_SET_FIXED_RATE(es->escfg, 0); - fixed_rate = DSP_DEFAULT_SPEED; + fixed_rate = 8000; } if (single_pcm) es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 1); @@ -1712,7 +1712,8 @@ es_pci_attach(device_t dev) uint32_t devid; es = malloc(sizeof *es, M_DEVBUF, M_WAITOK | M_ZERO); - es->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_es137x softc"); + mtx_init(&es->lock, device_get_nameunit(dev), "snd_es137x softc", + MTX_DEF); es->dev = dev; es->escfg = 0; mapped = 0; @@ -1888,8 +1889,7 @@ bad: ac97_destroy(codec); if (es->reg) bus_release_resource(dev, es->regtype, es->regid, es->reg); - if (es->lock) - snd_mtxfree(es->lock); + mtx_destroy(&es->lock); if (es) free(es, M_DEVBUF); return (ENXIO); @@ -1919,7 +1919,7 @@ es_pci_detach(device_t dev) bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq); bus_release_resource(dev, es->regtype, es->regid, es->reg); bus_dma_tag_destroy(es->parent_dmat); - snd_mtxfree(es->lock); + mtx_destroy(&es->lock); free(es, M_DEVBUF); return (0); diff --git a/sys/dev/sound/pci/fm801.c b/sys/dev/sound/pci/fm801.c index 3537c7807ded..39d12f8505d1 100644 --- a/sys/dev/sound/pci/fm801.c +++ b/sys/dev/sound/pci/fm801.c @@ -440,7 +440,7 @@ fm801ch_trigger(kobj_t obj, void *data, int go) { struct fm801_chinfo *ch = data; struct fm801_info *fm801 = ch->parent; - u_int32_t baseaddr = sndbuf_getbufaddr(ch->buffer); + u_int32_t baseaddr = ch->buffer->buf_addr; u_int32_t k1; DPRINT("fm801ch_trigger go %d , ", go); diff --git a/sys/dev/sound/pci/hda/hdaa.c b/sys/dev/sound/pci/hda/hdaa.c index 5dbb5c4f4453..7dec437de944 100644 --- a/sys/dev/sound/pci/hda/hdaa.c +++ b/sys/dev/sound/pci/hda/hdaa.c @@ -47,9 +47,9 @@ #include "mixer_if.h" -#define hdaa_lock(devinfo) snd_mtxlock((devinfo)->lock) -#define hdaa_unlock(devinfo) snd_mtxunlock((devinfo)->lock) -#define hdaa_lockassert(devinfo) snd_mtxassert((devinfo)->lock) +#define hdaa_lock(devinfo) mtx_lock((devinfo)->lock) +#define hdaa_unlock(devinfo) mtx_unlock((devinfo)->lock) +#define hdaa_lockassert(devinfo) mtx_assert((devinfo)->lock, MA_OWNED) static const struct { const char *key; @@ -2081,10 +2081,10 @@ hdaa_channel_setfragments(kobj_t obj, void *data, { struct hdaa_chan *ch = data; - blksz -= blksz % lcm(HDA_DMA_ALIGNMENT, sndbuf_getalign(ch->b)); + blksz -= blksz % lcm(HDA_DMA_ALIGNMENT, ch->b->align); - if (blksz > (sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN)) - blksz = sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN; + if (blksz > (ch->b->maxsize / HDA_BDL_MIN)) + blksz = ch->b->maxsize / HDA_BDL_MIN; if (blksz < HDA_BLK_MIN) blksz = HDA_BLK_MIN; if (blkcnt > HDA_BDL_MAX) @@ -2092,7 +2092,7 @@ hdaa_channel_setfragments(kobj_t obj, void *data, if (blkcnt < HDA_BDL_MIN) blkcnt = HDA_BDL_MIN; - while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->b)) { + while ((blksz * blkcnt) > ch->b->maxsize) { if ((blkcnt >> 1) >= HDA_BDL_MIN) blkcnt >>= 1; else if ((blksz >> 1) >= HDA_BLK_MIN) @@ -2101,14 +2101,14 @@ hdaa_channel_setfragments(kobj_t obj, void *data, break; } - if ((sndbuf_getblksz(ch->b) != blksz || - sndbuf_getblkcnt(ch->b) != blkcnt) && + if ((ch->b->blksz != blksz || + ch->b->blkcnt != blkcnt) && sndbuf_resize(ch->b, blkcnt, blksz) != 0) device_printf(ch->devinfo->dev, "%s: failed blksz=%u blkcnt=%u\n", __func__, blksz, blkcnt); - ch->blksz = sndbuf_getblksz(ch->b); - ch->blkcnt = sndbuf_getblkcnt(ch->b); + ch->blksz = ch->b->blksz; + ch->blkcnt = ch->b->blkcnt; return (0); } @@ -2169,7 +2169,7 @@ hdaa_channel_start(struct hdaa_chan *ch) ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid); HDAC_STREAM_START(device_get_parent(devinfo->dev), devinfo->dev, ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid, - sndbuf_getbufaddr(ch->b), ch->blksz, ch->blkcnt); + ch->b->buf_addr, ch->blksz, ch->blkcnt); ch->flags |= HDAA_CHN_RUNNING; return (0); } diff --git a/sys/dev/sound/pci/hda/hdaa_patches.c b/sys/dev/sound/pci/hda/hdaa_patches.c index 91bb244578c7..d4267aae80f8 100644 --- a/sys/dev/sound/pci/hda/hdaa_patches.c +++ b/sys/dev/sound/pci/hda/hdaa_patches.c @@ -341,7 +341,8 @@ hdac_pin_patch(struct hdaa_widget *w) } else if (id == HDA_CODEC_ALC257 && (subid == LENOVO_L5AMD_SUBVENDOR || subid == LENOVO_L5INTEL_SUBVENDOR || - subid == LENOVO_IDEAPAD3_SUBVENDOR)) { + subid == LENOVO_IDEAPAD3_SUBVENDOR || + subid == LENOVO_V15_SUBVENDOR)) { switch (nid) { case 20: patch_str = "as=1 seq=0"; diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index 8a325c538b9b..d1de81e7ba29 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -51,9 +51,9 @@ #define HDA_DRV_TEST_REV "20120126_0002" -#define hdac_lock(sc) snd_mtxlock((sc)->lock) -#define hdac_unlock(sc) snd_mtxunlock((sc)->lock) -#define hdac_lockassert(sc) snd_mtxassert((sc)->lock) +#define hdac_lock(sc) mtx_lock(&(sc)->lock) +#define hdac_unlock(sc) mtx_unlock(&(sc)->lock) +#define hdac_lockassert(sc) mtx_assert(&(sc)->lock, MA_OWNED) #define HDAC_QUIRK_64BIT (1 << 0) #define HDAC_QUIRK_DMAPOS (1 << 1) @@ -1171,7 +1171,8 @@ hdac_attach(device_t dev) } } - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "HDA driver mutex"); + mtx_init(&sc->lock, device_get_nameunit(dev), "HDA driver mutex", + MTX_DEF); sc->dev = dev; TASK_INIT(&sc->unsolq_task, 0, hdac_unsolq_task, sc); callout_init(&sc->poll_callout, 1); @@ -1374,7 +1375,7 @@ hdac_attach_fail: hdac_dma_free(sc, &sc->rirb_dma); hdac_dma_free(sc, &sc->corb_dma); hdac_mem_free(sc); - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); return (ENXIO); } @@ -1798,7 +1799,7 @@ hdac_detach(device_t dev) sc->chan_dmat = NULL; } hdac_mem_free(sc); - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); return (0); } @@ -1888,7 +1889,7 @@ hdac_get_mtx(device_t dev, device_t child) { struct hdac_softc *sc = device_get_softc(dev); - return (sc->lock); + return (&sc->lock); } static uint32_t diff --git a/sys/dev/sound/pci/hda/hdac.h b/sys/dev/sound/pci/hda/hdac.h index 8fb54108a833..bc0ae651a3b6 100644 --- a/sys/dev/sound/pci/hda/hdac.h +++ b/sys/dev/sound/pci/hda/hdac.h @@ -390,6 +390,7 @@ #define LENOVO_3000_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x384e) #define LENOVO_IDEAPAD330_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3808) #define LENOVO_IDEAPAD3_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3881) +#define LENOVO_V15_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3886) #define LENOVO_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0xffff) /* Samsung */ diff --git a/sys/dev/sound/pci/hda/hdac_private.h b/sys/dev/sound/pci/hda/hdac_private.h index c434bface240..0c6fe41fd5de 100644 --- a/sys/dev/sound/pci/hda/hdac_private.h +++ b/sys/dev/sound/pci/hda/hdac_private.h @@ -162,7 +162,7 @@ struct hdac_stream { struct hdac_softc { device_t dev; - struct mtx *lock; + struct mtx lock; struct intr_config_hook intrhook; diff --git a/sys/dev/sound/pci/hda/hdacc.c b/sys/dev/sound/pci/hda/hdacc.c index 4198982c9c2a..b001daa549b1 100644 --- a/sys/dev/sound/pci/hda/hdacc.c +++ b/sys/dev/sound/pci/hda/hdacc.c @@ -60,9 +60,9 @@ struct hdacc_softc { struct hdacc_fg *fgs; }; -#define hdacc_lock(codec) snd_mtxlock((codec)->lock) -#define hdacc_unlock(codec) snd_mtxunlock((codec)->lock) -#define hdacc_lockassert(codec) snd_mtxassert((codec)->lock) +#define hdacc_lock(codec) mtx_lock((codec)->lock) +#define hdacc_unlock(codec) mtx_unlock((codec)->lock) +#define hdacc_lockassert(codec) mtx_assert((codec)->lock, MA_OWNED) MALLOC_DEFINE(M_HDACC, "hdacc", "HDA CODEC"); diff --git a/sys/dev/sound/pci/hdsp-pcm.c b/sys/dev/sound/pci/hdsp-pcm.c index 5ac571e64fde..b64cec281388 100644 --- a/sys/dev/sound/pci/hdsp-pcm.c +++ b/sys/dev/sound/pci/hdsp-pcm.c @@ -321,10 +321,10 @@ hdspmixer_init(struct snd_mixer *m) if (hdsp_channel_rec_ports(scp->hc)) mask |= SOUND_MASK_RECLEV; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL); mix_setdevs(m, mask); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -676,7 +676,7 @@ hdspchan_free(kobj_t obj, void *data) device_printf(scp->dev, "hdspchan_free()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->data != NULL) { free(ch->data, M_HDSP); ch->data = NULL; @@ -685,7 +685,7 @@ hdspchan_free(kobj_t obj, void *data) free(ch->caps, M_HDSP); ch->caps = NULL; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -702,7 +702,7 @@ hdspchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, scp = devinfo; sc = scp->sc; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); num = scp->chnum; ch = &scp->chan[num]; @@ -745,7 +745,7 @@ hdspchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, ch->dir = dir; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); if (sndbuf_setup(ch->buffer, ch->data, ch->size) != 0) { device_printf(scp->dev, "Can't setup sndbuf.\n"); @@ -767,7 +767,7 @@ hdspchan_trigger(kobj_t obj, void *data, int go) scp = ch->parent; sc = scp->sc; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); switch (go) { case PCMTRIG_START: #if 0 @@ -795,7 +795,7 @@ hdspchan_trigger(kobj_t obj, void *data, int go) break; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -812,9 +812,9 @@ hdspchan_getptr(kobj_t obj, void *data) scp = ch->parent; sc = scp->sc; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); ret = hdsp_read_2(sc, HDSP_STATUS_REG); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); pos = ret & HDSP_BUF_POSITION_MASK; pos %= (2 * sc->period * sizeof(uint32_t)); /* Double buffer. */ @@ -951,12 +951,12 @@ hdspchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) } } - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->ctrl_register &= ~HDSP_LAT_MASK; sc->ctrl_register |= hdsp_encode_latency(hl->n); hdsp_write_4(sc, HDSP_CONTROL_REG, sc->ctrl_register); sc->period = hl->period; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); #if 0 device_printf(scp->dev, "New period=%d\n", sc->period); @@ -971,7 +971,7 @@ hdspchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) hdsp_write_4(sc, HDSP_FREQ_REG, hdsp_freq_reg_value(sc->speed)); end: - return (sndbuf_getblksz(ch->buffer)); + return (ch->buffer->blksz); } static uint32_t hdsp_bkp_fmt[] = { @@ -1034,9 +1034,9 @@ hdsp_pcm_intr(struct sc_pcminfo *scp) for (i = 0; i < scp->chnum; i++) { ch = &scp->chan[i]; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(ch->channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } return (0); diff --git a/sys/dev/sound/pci/hdsp.c b/sys/dev/sound/pci/hdsp.c index 4ba23d22ebce..aefbb71807b6 100644 --- a/sys/dev/sound/pci/hdsp.c +++ b/sys/dev/sound/pci/hdsp.c @@ -109,7 +109,7 @@ hdsp_intr(void *p) sc = (struct sc_info *)p; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); status = hdsp_read_1(sc, HDSP_STATUS_REG); if (status & HDSP_AUDIO_IRQ_PENDING) { @@ -126,7 +126,7 @@ hdsp_intr(void *p) free(devlist, M_TEMP); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); } static void @@ -286,11 +286,11 @@ hdsp_sysctl_input_level(SYSCTL_HANDLER_ARGS) /* Set input level in control register. */ control &= HDSP_INPUT_LEVEL_MASK; if (control != (sc->ctrl_register & HDSP_INPUT_LEVEL_MASK)) { - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->ctrl_register &= ~HDSP_INPUT_LEVEL_MASK; sc->ctrl_register |= control; hdsp_write_4(sc, HDSP_CONTROL_REG, sc->ctrl_register); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); } return (0); } @@ -350,11 +350,11 @@ hdsp_sysctl_output_level(SYSCTL_HANDLER_ARGS) /* Set output level in control register. */ control &= HDSP_OUTPUT_LEVEL_MASK; if (control != (sc->ctrl_register & HDSP_OUTPUT_LEVEL_MASK)) { - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->ctrl_register &= ~HDSP_OUTPUT_LEVEL_MASK; sc->ctrl_register |= control; hdsp_write_4(sc, HDSP_CONTROL_REG, sc->ctrl_register); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); } return (0); } @@ -414,11 +414,11 @@ hdsp_sysctl_phones_level(SYSCTL_HANDLER_ARGS) /* Set phones level in control register. */ control &= HDSP_PHONES_LEVEL_MASK; if (control != (sc->ctrl_register & HDSP_PHONES_LEVEL_MASK)) { - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->ctrl_register &= ~HDSP_PHONES_LEVEL_MASK; sc->ctrl_register |= control; hdsp_write_4(sc, HDSP_CONTROL_REG, sc->ctrl_register); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); } return (0); } @@ -549,11 +549,11 @@ hdsp_sysctl_clock_preference(SYSCTL_HANDLER_ARGS) if (clock->name != NULL) { control = hdsp_control_clock_preference(clock->type); control &= HDSP_CONTROL_CLOCK_MASK; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->ctrl_register &= ~HDSP_CONTROL_CLOCK_MASK; sc->ctrl_register |= control; hdsp_write_4(sc, HDSP_CONTROL_REG, sc->ctrl_register); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); } return (0); } @@ -600,10 +600,10 @@ hdsp_sysctl_clock_source(SYSCTL_HANDLER_ARGS) return (ENXIO); /* Read current (autosync) clock source from status2 register. */ - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); status2 = hdsp_read_4(sc, HDSP_STATUS2_REG); status2 &= HDSP_STATUS2_CLOCK_MASK; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); /* Translate status2 register value to clock source. */ for (clock = clock_table; clock->name != NULL; ++clock) { @@ -720,10 +720,10 @@ hdsp_sysctl_sync_status(SYSCTL_HANDLER_ARGS) return (ENXIO); /* Read current lock and sync bits from status registers. */ - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); status = hdsp_read_4(sc, HDSP_STATUS_REG); status2 = hdsp_read_4(sc, HDSP_STATUS2_REG); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); /* List clock sources with lock and sync state. */ for (clock = clock_table; clock->name != NULL; ++clock) { @@ -857,8 +857,8 @@ hdsp_attach(device_t dev) #endif sc = device_get_softc(dev); - sc->lock = snd_mtxcreate(device_get_nameunit(dev), - "snd_hdsp softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "snd_hdsp softc", + MTX_DEF); sc->dev = dev; pci_enable_busmaster(dev); @@ -999,8 +999,7 @@ hdsp_detach(device_t dev) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); if (sc->cs) bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->cs); - if (sc->lock) - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); return (0); } diff --git a/sys/dev/sound/pci/hdsp.h b/sys/dev/sound/pci/hdsp.h index 8ac438cd79f9..18737709ec3f 100644 --- a/sys/dev/sound/pci/hdsp.h +++ b/sys/dev/sound/pci/hdsp.h @@ -223,7 +223,7 @@ struct sc_pcminfo { /* HDSP device private data */ struct sc_info { device_t dev; - struct mtx *lock; + struct mtx lock; uint32_t ctrl_register; uint32_t type; diff --git a/sys/dev/sound/pci/hdspe-pcm.c b/sys/dev/sound/pci/hdspe-pcm.c index 09bbbe22dacf..d78820732639 100644 --- a/sys/dev/sound/pci/hdspe-pcm.c +++ b/sys/dev/sound/pci/hdspe-pcm.c @@ -305,10 +305,10 @@ hdspemixer_init(struct snd_mixer *m) if (hdspe_channel_rec_ports(scp->hc)) mask |= SOUND_MASK_RECLEV; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL); mix_setdevs(m, mask); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -667,7 +667,7 @@ hdspechan_free(kobj_t obj, void *data) device_printf(scp->dev, "hdspechan_free()\n"); #endif - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); if (ch->data != NULL) { free(ch->data, M_HDSPE); ch->data = NULL; @@ -676,7 +676,7 @@ hdspechan_free(kobj_t obj, void *data) free(ch->caps, M_HDSPE); ch->caps = NULL; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -693,7 +693,7 @@ hdspechan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, scp = devinfo; sc = scp->sc; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); num = scp->chnum; ch = &scp->chan[num]; @@ -729,7 +729,7 @@ hdspechan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, ch->dir = dir; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); if (sndbuf_setup(ch->buffer, ch->data, ch->size) != 0) { device_printf(scp->dev, "Can't setup sndbuf.\n"); @@ -751,7 +751,7 @@ hdspechan_trigger(kobj_t obj, void *data, int go) scp = ch->parent; sc = scp->sc; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); switch (go) { case PCMTRIG_START: #if 0 @@ -779,7 +779,7 @@ hdspechan_trigger(kobj_t obj, void *data, int go) break; } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); return (0); } @@ -796,9 +796,9 @@ hdspechan_getptr(kobj_t obj, void *data) scp = ch->parent; sc = scp->sc; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); ret = hdspe_read_2(sc, HDSPE_STATUS_REG); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); pos = ret & HDSPE_BUF_POSITION_MASK; pos *= AFMT_CHANNEL(ch->format); /* Hardbuf with multiple channels. */ @@ -946,12 +946,12 @@ hdspechan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) } } - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->ctrl_register &= ~HDSPE_LAT_MASK; sc->ctrl_register |= hdspe_encode_latency(hl->n); hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register); sc->period = hl->period; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); #if 0 device_printf(scp->dev, "New period=%d\n", sc->period); @@ -962,7 +962,7 @@ hdspechan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) (sc->period * 4)); end: - return (sndbuf_getblksz(ch->buffer)); + return (ch->buffer->blksz); } static uint32_t hdspe_bkp_fmt[] = { @@ -1025,9 +1025,9 @@ hdspe_pcm_intr(struct sc_pcminfo *scp) for (i = 0; i < scp->chnum; i++) { ch = &scp->chan[i]; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); chn_intr(ch->channel); - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); } return (0); diff --git a/sys/dev/sound/pci/hdspe.c b/sys/dev/sound/pci/hdspe.c index c292b2ddef56..f468111cb16e 100644 --- a/sys/dev/sound/pci/hdspe.c +++ b/sys/dev/sound/pci/hdspe.c @@ -119,7 +119,7 @@ hdspe_intr(void *p) sc = (struct sc_info *)p; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); status = hdspe_read_1(sc, HDSPE_STATUS_REG); if (status & HDSPE_AUDIO_IRQ_PENDING) { @@ -136,7 +136,7 @@ hdspe_intr(void *p) free(devlist, M_TEMP); } - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); } static void @@ -301,11 +301,11 @@ hdspe_sysctl_input_level(SYSCTL_HANDLER_ARGS) /* Set input level in settings register. */ settings &= HDSPE_INPUT_LEVEL_MASK; if (settings != (sc->settings_register & HDSPE_INPUT_LEVEL_MASK)) { - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->settings_register &= ~HDSPE_INPUT_LEVEL_MASK; sc->settings_register |= settings; hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); } return (0); } @@ -365,11 +365,11 @@ hdspe_sysctl_output_level(SYSCTL_HANDLER_ARGS) /* Set output level in settings register. */ settings &= HDSPE_OUTPUT_LEVEL_MASK; if (settings != (sc->settings_register & HDSPE_OUTPUT_LEVEL_MASK)) { - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->settings_register &= ~HDSPE_OUTPUT_LEVEL_MASK; sc->settings_register |= settings; hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); } return (0); } @@ -429,11 +429,11 @@ hdspe_sysctl_phones_level(SYSCTL_HANDLER_ARGS) /* Set phones level in settings register. */ settings &= HDSPE_PHONES_LEVEL_MASK; if (settings != (sc->settings_register & HDSPE_PHONES_LEVEL_MASK)) { - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->settings_register &= ~HDSPE_PHONES_LEVEL_MASK; sc->settings_register |= settings; hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); } return (0); } @@ -540,11 +540,11 @@ hdspe_sysctl_clock_preference(SYSCTL_HANDLER_ARGS) /* Set preferred clock source in settings register. */ if (clock->name != NULL) { setting = clock->setting & HDSPE_SETTING_CLOCK_MASK; - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); sc->settings_register &= ~HDSPE_SETTING_CLOCK_MASK; sc->settings_register |= setting; hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); } return (0); } @@ -568,10 +568,10 @@ hdspe_sysctl_clock_source(SYSCTL_HANDLER_ARGS) return (ENXIO); /* Read current (autosync) clock source from status register. */ - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); status = hdspe_read_4(sc, HDSPE_STATUS1_REG); status &= HDSPE_STATUS1_CLOCK_MASK; - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); /* Translate status register value to clock source. */ for (clock = clock_table; clock->name != NULL; ++clock) { @@ -640,9 +640,9 @@ hdspe_sysctl_sync_status(SYSCTL_HANDLER_ARGS) return (ENXIO); /* Read current lock and sync bits from status register. */ - snd_mtxlock(sc->lock); + mtx_lock(&sc->lock); status = hdspe_read_4(sc, HDSPE_STATUS1_REG); - snd_mtxunlock(sc->lock); + mtx_unlock(&sc->lock); /* List clock sources with lock and sync state. */ for (clock = clock_table; clock->name != NULL; ++clock) { @@ -749,8 +749,8 @@ hdspe_attach(device_t dev) #endif sc = device_get_softc(dev); - sc->lock = snd_mtxcreate(device_get_nameunit(dev), - "snd_hdspe softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "snd_hdspe softc", + MTX_DEF); sc->dev = dev; pci_enable_busmaster(dev); @@ -891,8 +891,7 @@ hdspe_detach(device_t dev) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); if (sc->cs) bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->cs); - if (sc->lock) - snd_mtxfree(sc->lock); + mtx_destroy(&sc->lock); return (0); } diff --git a/sys/dev/sound/pci/hdspe.h b/sys/dev/sound/pci/hdspe.h index bced78758068..85acbe9f7374 100644 --- a/sys/dev/sound/pci/hdspe.h +++ b/sys/dev/sound/pci/hdspe.h @@ -214,7 +214,7 @@ struct sc_pcminfo { /* HDSPe device private data */ struct sc_info { device_t dev; - struct mtx *lock; + struct mtx lock; uint32_t ctrl_register; uint32_t settings_register; diff --git a/sys/dev/sound/pci/ich.c b/sys/dev/sound/pci/ich.c index 500d6d95daac..7e7fe95dac8c 100644 --- a/sys/dev/sound/pci/ich.c +++ b/sys/dev/sound/pci/ich.c @@ -77,9 +77,9 @@ #define AMD_768 0x7445 #define AMD_8111 0x746d -#define ICH_LOCK(sc) snd_mtxlock((sc)->ich_lock) -#define ICH_UNLOCK(sc) snd_mtxunlock((sc)->ich_lock) -#define ICH_LOCK_ASSERT(sc) snd_mtxassert((sc)->ich_lock) +#define ICH_LOCK(sc) mtx_lock(&(sc)->ich_lock) +#define ICH_UNLOCK(sc) mtx_unlock(&(sc)->ich_lock) +#define ICH_LOCK_ASSERT(sc) mtx_assert(&(sc)->ich_lock, MA_OWNED) #if 0 #define ICH_DEBUG(stmt) do { \ @@ -196,7 +196,7 @@ struct sc_info { uint16_t vendor; uint16_t devid; uint32_t flags; - struct mtx *ich_lock; + struct mtx ich_lock; }; /* -------------------------------------------------------------------- */ @@ -301,15 +301,15 @@ ich_filldtbl(struct sc_chinfo *ch) uint32_t base; int i; - base = sndbuf_getbufaddr(ch->buffer); - if ((ch->blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer)) - ch->blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt; - if ((sndbuf_getblksz(ch->buffer) != ch->blksz || - sndbuf_getblkcnt(ch->buffer) != ch->blkcnt) && + base = ch->buffer->buf_addr; + if ((ch->blksz * ch->blkcnt) > ch->buffer->maxsize) + ch->blksz = ch->buffer->maxsize / ch->blkcnt; + if ((ch->buffer->blksz != ch->blksz || + ch->buffer->blkcnt != ch->blkcnt) && sndbuf_resize(ch->buffer, ch->blkcnt, ch->blksz) != 0) device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n", __func__, ch->blksz, ch->blkcnt); - ch->blksz = sndbuf_getblksz(ch->buffer); + ch->blksz = ch->buffer->blksz; for (i = 0; i < ICH_DTBL_LENGTH; i++) { ch->dtbl[i].buffer = base + (ch->blksz * (i % ch->blkcnt)); @@ -491,7 +491,7 @@ ichchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) ); if (sc->flags & ICH_HIGH_LATENCY) - blocksize = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt; + blocksize = ch->buffer->maxsize / ch->blkcnt; if (blocksize < ICH_MIN_BLKSZ) blocksize = ICH_MIN_BLKSZ; @@ -734,7 +734,7 @@ ich_calibrate(void *arg) ch->blkcnt = 2; sc->flags |= ICH_CALIBRATE_DONE; ICH_UNLOCK(sc); - ichchan_setblocksize(0, ch, sndbuf_getmaxsize(ch->buffer) >> 1); + ichchan_setblocksize(0, ch, ch->buffer->maxsize >> 1); ICH_LOCK(sc); sc->flags &= ~ICH_CALIBRATE_DONE; @@ -888,7 +888,8 @@ ich_pci_attach(device_t dev) int i; sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); - sc->ich_lock = snd_mtxcreate(device_get_nameunit(dev), "snd_ich softc"); + mtx_init(&sc->ich_lock, device_get_nameunit(dev), "snd_ich softc", + MTX_DEF); sc->dev = dev; vendor = sc->vendor = pci_get_vendor(dev); @@ -1111,8 +1112,7 @@ bad: bus_dma_tag_destroy(sc->chan_dmat); if (sc->dmat) bus_dma_tag_destroy(sc->dmat); - if (sc->ich_lock) - snd_mtxfree(sc->ich_lock); + mtx_destroy(&sc->ich_lock); free(sc, M_DEVBUF); return (ENXIO); } @@ -1136,7 +1136,7 @@ ich_pci_detach(device_t dev) bus_dmamem_free(sc->dmat, sc->dtbl, sc->dtmap); bus_dma_tag_destroy(sc->chan_dmat); bus_dma_tag_destroy(sc->dmat); - snd_mtxfree(sc->ich_lock); + mtx_destroy(&sc->ich_lock); free(sc, M_DEVBUF); return (0); } diff --git a/sys/dev/sound/pci/maestro3.c b/sys/dev/sound/pci/maestro3.c index 2d102fcd6dbe..a8a52601d1a2 100644 --- a/sys/dev/sound/pci/maestro3.c +++ b/sys/dev/sound/pci/maestro3.c @@ -156,12 +156,12 @@ struct sc_info { unsigned int bufsz; u_int16_t *savemem; - struct mtx *sc_lock; + struct mtx sc_lock; }; -#define M3_LOCK(_sc) snd_mtxlock((_sc)->sc_lock) -#define M3_UNLOCK(_sc) snd_mtxunlock((_sc)->sc_lock) -#define M3_LOCK_ASSERT(_sc) snd_mtxassert((_sc)->sc_lock) +#define M3_LOCK(_sc) mtx_lock(&(_sc)->sc_lock) +#define M3_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_lock) +#define M3_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_lock, MA_OWNED) /* -------------------------------------------------------------------- */ @@ -437,17 +437,17 @@ m3_pchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel ch->parent = sc; ch->channel = c; ch->fmt = SND_FORMAT(AFMT_U8, 1, 0); - ch->spd = DSP_DEFAULT_SPEED; + ch->spd = 8000; M3_UNLOCK(sc); /* XXX */ if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) != 0) { device_printf(sc->dev, "m3_pchan_init chn_allocbuf failed\n"); return (NULL); } M3_LOCK(sc); - ch->bufsize = sndbuf_getsize(ch->buffer); + ch->bufsize = ch->buffer->bufsize; /* host dma buffer pointers */ - bus_addr = sndbuf_getbufaddr(ch->buffer); + bus_addr = ch->buffer->buf_addr; if (bus_addr & 3) { device_printf(sc->dev, "m3_pchan_init unaligned bus_addr\n"); bus_addr = (bus_addr + 4) & ~3; @@ -595,7 +595,7 @@ m3_pchan_setblocksize(kobj_t kobj, void *chdata, u_int32_t blocksize) M3_DEBUG(CHANGE, ("m3_pchan_setblocksize(dac=%d, blocksize=%d)\n", ch->dac_idx, blocksize)); - return (sndbuf_getblksz(ch->buffer)); + return (ch->buffer->blksz); } static int @@ -709,7 +709,7 @@ m3_pchan_getptr_internal(struct sc_pchinfo *ch) struct sc_info *sc = ch->parent; u_int32_t hi, lo, bus_base, bus_crnt; - bus_base = sndbuf_getbufaddr(ch->buffer); + bus_base = ch->buffer->buf_addr; hi = m3_rd_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_CURRENTH); lo = m3_rd_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_CURRENTL); bus_crnt = lo | (hi << 16); @@ -816,17 +816,17 @@ m3_rchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel ch->parent = sc; ch->channel = c; ch->fmt = SND_FORMAT(AFMT_U8, 1, 0); - ch->spd = DSP_DEFAULT_SPEED; + ch->spd = 8000; M3_UNLOCK(sc); /* XXX */ if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) != 0) { device_printf(sc->dev, "m3_rchan_init chn_allocbuf failed\n"); return (NULL); } M3_LOCK(sc); - ch->bufsize = sndbuf_getsize(ch->buffer); + ch->bufsize = ch->buffer->bufsize; /* host dma buffer pointers */ - bus_addr = sndbuf_getbufaddr(ch->buffer); + bus_addr = ch->buffer->buf_addr; if (bus_addr & 3) { device_printf(sc->dev, "m3_rchan_init unaligned bus_addr\n"); bus_addr = (bus_addr + 4) & ~3; @@ -968,7 +968,7 @@ m3_rchan_setblocksize(kobj_t kobj, void *chdata, u_int32_t blocksize) M3_DEBUG(CHANGE, ("m3_rchan_setblocksize(adc=%d, blocksize=%d)\n", ch->adc_idx, blocksize)); - return (sndbuf_getblksz(ch->buffer)); + return (ch->buffer->blksz); } static int @@ -1061,7 +1061,7 @@ m3_rchan_getptr_internal(struct sc_rchinfo *ch) struct sc_info *sc = ch->parent; u_int32_t hi, lo, bus_base, bus_crnt; - bus_base = sndbuf_getbufaddr(ch->buffer); + bus_base = ch->buffer->buf_addr; hi = m3_rd_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_CURRENTH); lo = m3_rd_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_CURRENTL); bus_crnt = lo | (hi << 16); @@ -1162,7 +1162,7 @@ m3_handle_channel_intr: pch->ptr = m3_pchan_getptr_internal(pch); delta = pch->bufsize + pch->ptr - pch->prevptr; delta %= pch->bufsize; - if (delta < sndbuf_getblksz(pch->buffer)) + if (delta < pch->buffer->blksz) continue; pch->prevptr = pch->ptr; M3_UNLOCK(sc); @@ -1176,7 +1176,7 @@ m3_handle_channel_intr: rch->ptr = m3_rchan_getptr_internal(rch); delta = rch->bufsize + rch->ptr - rch->prevptr; delta %= rch->bufsize; - if (delta < sndbuf_getblksz(rch->buffer)) + if (delta < rch->buffer->blksz) continue; rch->prevptr = rch->ptr; M3_UNLOCK(sc); @@ -1325,8 +1325,8 @@ m3_pci_attach(device_t dev) sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); sc->dev = dev; sc->type = pci_get_devid(dev); - sc->sc_lock = snd_mtxcreate(device_get_nameunit(dev), - "snd_maestro3 softc"); + mtx_init(&sc->sc_lock, device_get_nameunit(dev), "snd_maestro3 softc", + MTX_DEF); for (card = m3_card_types ; card->pci_id ; card++) { if (sc->type == card->pci_id) { sc->which = card->which; @@ -1465,8 +1465,7 @@ m3_pci_attach(device_t dev) bus_release_resource(dev, sc->regtype, sc->regid, sc->reg); if (sc->parent_dmat) bus_dma_tag_destroy(sc->parent_dmat); - if (sc->sc_lock) - snd_mtxfree(sc->sc_lock); + mtx_destroy(&sc->sc_lock); free(sc, M_DEVBUF); return ENXIO; } @@ -1494,7 +1493,7 @@ m3_pci_detach(device_t dev) bus_dma_tag_destroy(sc->parent_dmat); free(sc->savemem, M_DEVBUF); - snd_mtxfree(sc->sc_lock); + mtx_destroy(&sc->sc_lock); free(sc, M_DEVBUF); return 0; } diff --git a/sys/dev/sound/pci/neomagic.c b/sys/dev/sound/pci/neomagic.c index d7824c990a52..1fee943d9364 100644 --- a/sys/dev/sound/pci/neomagic.c +++ b/sys/dev/sound/pci/neomagic.c @@ -362,7 +362,7 @@ nmchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c sndbuf_setup(ch->buffer, (u_int8_t *)rman_get_virtual(sc->buf) + chnbuf, NM_BUFFSIZE); if (bootverbose) device_printf(sc->dev, "%s buf %p\n", (dir == PCMDIR_PLAY)? - "play" : "rec", sndbuf_getbuf(ch->buffer)); + "play" : "rec", ch->buffer->buf); ch->parent = sc; ch->channel = c; ch->dir = dir; diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c index 90dd2e26ad41..2b61b594a8f3 100644 --- a/sys/dev/sound/pci/solo.c +++ b/sys/dev/sound/pci/solo.c @@ -97,12 +97,12 @@ struct ess_info { unsigned int bufsz; struct ess_chinfo pch, rch; - struct mtx *lock; + struct mtx lock; }; -#define ess_lock(_ess) snd_mtxlock((_ess)->lock) -#define ess_unlock(_ess) snd_mtxunlock((_ess)->lock) -#define ess_lock_assert(_ess) snd_mtxassert((_ess)->lock) +#define ess_lock(_ess) mtx_lock(&(_ess)->lock) +#define ess_unlock(_ess) mtx_unlock(&(_ess)->lock) +#define ess_lock_assert(_ess) mtx_assert(&(_ess)->lock, MA_OWNED) static int ess_rd(struct ess_info *sc, int reg); static void ess_wr(struct ess_info *sc, int reg, u_int8_t val); @@ -584,7 +584,8 @@ esschan_trigger(kobj_t obj, void *data, int go) ess_lock(sc); switch (go) { case PCMTRIG_START: - ess_dmasetup(sc, ch->hwch, sndbuf_getbufaddr(ch->buffer), sndbuf_getsize(ch->buffer), ch->dir); + ess_dmasetup(sc, ch->hwch, ch->buffer->buf_addr, + ch->buffer->bufsize, ch->dir); ess_dmatrigger(sc, ch->hwch, 1); ess_start(ch); break; @@ -854,10 +855,7 @@ ess_release_resources(struct ess_info *sc, device_t dev) sc->parent_dmat = 0; } - if (sc->lock) { - snd_mtxfree(sc->lock); - sc->lock = NULL; - } + mtx_destroy(&sc->lock); free(sc, M_DEVBUF); } @@ -886,10 +884,11 @@ ess_alloc_resources(struct ess_info *sc, device_t dev) sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE | RF_SHAREABLE); - sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_solo softc"); + mtx_init(&sc->lock, device_get_nameunit(dev), "snd_solo softc", + MTX_DEF); return (sc->irq && sc->io && sc->sb && sc->vc && - sc->mpu && sc->gp && sc->lock)? 0 : ENXIO; + sc->mpu && sc->gp)? 0 : ENXIO; } static int diff --git a/sys/dev/sound/pci/spicds.c b/sys/dev/sound/pci/spicds.c index da0e8d9da6d5..350034d8bafb 100644 --- a/sys/dev/sound/pci/spicds.c +++ b/sys/dev/sound/pci/spicds.c @@ -49,7 +49,7 @@ struct spicds_info { unsigned int dvc; /* De-emphasis and Volume Control */ unsigned int left, right; char name[SPICDS_NAMELEN]; - struct mtx *lock; + struct mtx lock; }; static void @@ -149,7 +149,7 @@ spicds_create(device_t dev, void *devinfo, int num, spicds_ctrl ctrl) return NULL; snprintf(codec->name, SPICDS_NAMELEN, "%s:spicds%d", device_get_nameunit(dev), num); - codec->lock = snd_mtxcreate(codec->name, codec->name); + mtx_init(&codec->lock, codec->name, codec->name, MTX_DEF); codec->dev = dev; codec->ctrl = ctrl; codec->devinfo = devinfo; @@ -165,40 +165,40 @@ spicds_create(device_t dev, void *devinfo, int num, spicds_ctrl ctrl) void spicds_destroy(struct spicds_info *codec) { - snd_mtxfree(codec->lock); + mtx_destroy(&codec->lock); free(codec, M_SPICDS); } void spicds_settype(struct spicds_info *codec, unsigned int type) { - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); codec->type = type; - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); } void spicds_setcif(struct spicds_info *codec, unsigned int cif) { - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); codec->cif = cif; - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); } void spicds_setformat(struct spicds_info *codec, unsigned int format) { - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); codec->format = format; - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); } void spicds_setdvc(struct spicds_info *codec, unsigned int dvc) { - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); codec->dvc = dvc; - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); } void @@ -207,7 +207,7 @@ spicds_init(struct spicds_info *codec) #if(0) device_printf(codec->dev, "spicds_init(codec)\n"); #endif - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); if (codec->type == SPICDS_TYPE_AK4524 ||\ codec->type == SPICDS_TYPE_AK4528) { /* power off */ @@ -244,13 +244,13 @@ spicds_init(struct spicds_info *codec) spicds_wrcd(codec, 0x00, 0x8f); /* I2S, 24bit, power-up */ if (codec->type == SPICDS_TYPE_AK4396) spicds_wrcd(codec, 0x00, 0x07); /* I2S, 24bit, power-up */ - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); } void spicds_reinit(struct spicds_info *codec) { - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); if (codec->type != SPICDS_TYPE_WM8770) { /* reset */ spicds_wrcd(codec, AK4524_RESET, 0); @@ -265,7 +265,7 @@ spicds_reinit(struct spicds_info *codec) /* AK4358 reinit */ /* AK4381 reinit */ } - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); } void @@ -274,7 +274,7 @@ spicds_set(struct spicds_info *codec, int dir, unsigned int left, unsigned int r #if(0) device_printf(codec->dev, "spicds_set(codec, %d, %d, %d)\n", dir, left, right); #endif - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); if (left >= 100) if ((codec->type == SPICDS_TYPE_AK4381) || \ (codec->type == SPICDS_TYPE_AK4396)) @@ -362,7 +362,7 @@ spicds_set(struct spicds_info *codec, int dir, unsigned int left, unsigned int r spicds_wrcd(codec, AK4396_ROATT, right); } - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); } MODULE_DEPEND(snd_spicds, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); diff --git a/sys/dev/sound/pci/t4dwave.c b/sys/dev/sound/pci/t4dwave.c index 07b9e1004573..1b659118b840 100644 --- a/sys/dev/sound/pci/t4dwave.c +++ b/sys/dev/sound/pci/t4dwave.c @@ -99,7 +99,7 @@ struct tr_info { int regtype, regid, irqid; void *ih; - struct mtx *lock; + struct mtx lock; u_int32_t hwchns; u_int32_t playchns; @@ -209,7 +209,7 @@ tr_rdcd(kobj_t obj, void *devinfo, int regno) i = j = 0; regno &= 0x7f; - snd_mtxlock(tr->lock); + mtx_lock(&tr->lock); if (tr->type == ALI_PCI_ID) { u_int32_t chk1, chk2; j = trw; @@ -229,7 +229,7 @@ tr_rdcd(kobj_t obj, void *devinfo, int regno) for (i=TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--) j=tr_rd(tr, treg, 4); } - snd_mtxunlock(tr->lock); + mtx_unlock(&tr->lock); if (i == 0) printf("codec timeout during read of register %x\n", regno); return (j >> TR_CDC_DATA) & 0xffff; } @@ -266,7 +266,7 @@ tr_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data) printf("tr_wrcd: reg %x was %x", regno, tr_rdcd(devinfo, regno)); #endif j=trw; - snd_mtxlock(tr->lock); + mtx_lock(&tr->lock); if (tr->type == ALI_PCI_ID) { j = trw; for (i = TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--) @@ -290,7 +290,7 @@ tr_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data) #if 0 printf(" - wrote %x, now %x\n", data, tr_rdcd(devinfo, regno)); #endif - snd_mtxunlock(tr->lock); + mtx_unlock(&tr->lock); if (i==0) printf("codec timeout writing %x, data %x\n", regno, data); return (i > 0)? 0 : -1; } @@ -336,7 +336,7 @@ tr_enaint(struct tr_chinfo *ch, int enable) u_int32_t i, reg; int bank, chan; - snd_mtxlock(tr->lock); + mtx_lock(&tr->lock); bank = (ch->index & 0x20) ? 1 : 0; chan = ch->index & 0x1f; reg = bank? TR_REG_INTENB : TR_REG_INTENA; @@ -347,7 +347,7 @@ tr_enaint(struct tr_chinfo *ch, int enable) tr_clrint(ch); tr_wr(tr, reg, i, 4); - snd_mtxunlock(tr->lock); + mtx_unlock(&tr->lock); } /* playback channels */ @@ -429,11 +429,11 @@ tr_wrch(struct tr_chinfo *ch) cr[3]|=(ch->alpha<<20) | (ch->fms<<16) | (ch->fmc<<14); break; } - snd_mtxlock(tr->lock); + mtx_lock(&tr->lock); tr_selch(ch); for (i=0; i<TR_CHN_REGS; i++) tr_wr(tr, TR_REG_CHNBASE+(i<<2), cr[i], 4); - snd_mtxunlock(tr->lock); + mtx_unlock(&tr->lock); } static void @@ -442,11 +442,11 @@ tr_rdch(struct tr_chinfo *ch) struct tr_info *tr = ch->parent; u_int32_t cr[5], i; - snd_mtxlock(tr->lock); + mtx_lock(&tr->lock); tr_selch(ch); for (i=0; i<5; i++) cr[i]=tr_rd(tr, TR_REG_CHNBASE+(i<<2), 4); - snd_mtxunlock(tr->lock); + mtx_unlock(&tr->lock); if (tr->type == ALI_PCI_ID) ch->lba=(cr[1] & ALI_MAXADDR); @@ -555,9 +555,9 @@ trpchan_trigger(kobj_t obj, void *data, int go) ch->fms = 0; ch->ec = 0; ch->alpha = 0; - ch->lba = sndbuf_getbufaddr(ch->buffer); + ch->lba = ch->buffer->buf_addr; ch->cso = 0; - ch->eso = (sndbuf_getsize(ch->buffer) / sndbuf_getalign(ch->buffer)) - 1; + ch->eso = (ch->buffer->bufsize / ch->buffer->align) - 1; ch->rvol = ch->cvol = 0x7f; ch->gvsel = 0; ch->pan = 0; @@ -581,7 +581,7 @@ trpchan_getptr(kobj_t obj, void *data) struct tr_chinfo *ch = data; tr_rdch(ch); - return ch->cso * sndbuf_getalign(ch->buffer); + return ch->cso * ch->buffer->align; } static struct pcmchan_caps * @@ -680,7 +680,7 @@ trrchan_trigger(kobj_t obj, void *data, int go) i = tr_rd(tr, TR_REG_DMAR11, 1) & 0x03; tr_wr(tr, TR_REG_DMAR11, i | 0x54, 1); /* set up base address */ - tr_wr(tr, TR_REG_DMAR0, sndbuf_getbufaddr(ch->buffer), 4); + tr_wr(tr, TR_REG_DMAR0, ch->buffer->buf_addr, 4); /* set up buffer size */ i = tr_rd(tr, TR_REG_DMAR4, 4) & ~0x00ffffff; tr_wr(tr, TR_REG_DMAR4, i | (sndbuf_runsz(ch->buffer) - 1), 4); @@ -703,7 +703,7 @@ trrchan_getptr(kobj_t obj, void *data) struct tr_info *tr = ch->parent; /* return current byte offset of channel */ - return tr_rd(tr, TR_REG_DMAR0, 4) - sndbuf_getbufaddr(ch->buffer); + return tr_rd(tr, TR_REG_DMAR0, 4) - ch->buffer->buf_addr; } static struct pcmchan_caps * @@ -830,7 +830,8 @@ tr_pci_attach(device_t dev) tr = malloc(sizeof(*tr), M_DEVBUF, M_WAITOK | M_ZERO); tr->type = pci_get_devid(dev); tr->rev = pci_get_revid(dev); - tr->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_t4dwave softc"); + mtx_init(&tr->lock, device_get_nameunit(dev), "snd_t4dwave softc", + MTX_DEF); if (resource_int_value(device_get_name(dev), device_get_unit(dev), "dac", &i) == 0) { @@ -936,7 +937,7 @@ bad: if (tr->ih) bus_teardown_intr(dev, tr->irq, tr->ih); if (tr->irq) bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq); if (tr->parent_dmat) bus_dma_tag_destroy(tr->parent_dmat); - if (tr->lock) snd_mtxfree(tr->lock); + mtx_destroy(&tr->lock); free(tr, M_DEVBUF); return ENXIO; } @@ -956,7 +957,7 @@ tr_pci_detach(device_t dev) bus_teardown_intr(dev, tr->irq, tr->ih); bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq); bus_dma_tag_destroy(tr->parent_dmat); - snd_mtxfree(tr->lock); + mtx_destroy(&tr->lock); free(tr, M_DEVBUF); return 0; diff --git a/sys/dev/sound/pci/via8233.c b/sys/dev/sound/pci/via8233.c index 243353805b94..6c59397756e0 100644 --- a/sys/dev/sound/pci/via8233.c +++ b/sys/dev/sound/pci/via8233.c @@ -121,7 +121,7 @@ struct via_info { uint16_t codec_caps; uint16_t n_dxs_registered; int play_num, rec_num; - struct mtx *lock; + struct mtx lock; struct callout poll_timer; int poll_ticks, polling; }; @@ -164,9 +164,9 @@ sysctl_via8233_spdif_enable(SYSCTL_HANDLER_ARGS) dev = oidp->oid_arg1; via = pcm_getdevinfo(dev); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); r = pci_read_config(dev, VIA_PCI_SPDIF, 1); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); new_en = (r & VIA_SPDIF_EN) ? 1 : 0; err = sysctl_handle_int(oidp, &new_en, 0, req); @@ -179,9 +179,9 @@ sysctl_via8233_spdif_enable(SYSCTL_HANDLER_ARGS) r |= VIA_SPDIF_EN; else r &= ~VIA_SPDIF_EN; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); pci_write_config(dev, VIA_PCI_SPDIF, r, 1); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return (0); } @@ -195,9 +195,9 @@ sysctl_via8233_dxs_src(SYSCTL_HANDLER_ARGS) dev = oidp->oid_arg1; via = pcm_getdevinfo(dev); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); val = via->dxs_src; - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); err = sysctl_handle_int(oidp, &val, 0, req); if (err || req->newptr == NULL) @@ -205,9 +205,9 @@ sysctl_via8233_dxs_src(SYSCTL_HANDLER_ARGS) if (val < 0 || val > 1) return (EINVAL); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); via->dxs_src = val; - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return (0); } @@ -223,9 +223,9 @@ sysctl_via_polling(SYSCTL_HANDLER_ARGS) via = pcm_getdevinfo(dev); if (via == NULL) return (EINVAL); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); val = via->polling; - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); err = sysctl_handle_int(oidp, &val, 0, req); if (err || req->newptr == NULL) @@ -233,7 +233,7 @@ sysctl_via_polling(SYSCTL_HANDLER_ARGS) if (val < 0 || val > 1) return (EINVAL); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); if (val != via->polling) { if (via_chan_active(via) != 0) err = EBUSY; @@ -242,7 +242,7 @@ sysctl_via_polling(SYSCTL_HANDLER_ARGS) else via->polling = 1; } - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return (err); } @@ -385,7 +385,7 @@ via_buildsgdt(struct via_chinfo *ch) uint32_t phys_addr, flag; int i; - phys_addr = sndbuf_getbufaddr(ch->buffer); + phys_addr = ch->buffer->buf_addr; for (i = 0; i < ch->blkcnt; i++) { flag = (i == ch->blkcnt - 1) ? VIA_DMAOP_EOL : VIA_DMAOP_FLAG; @@ -411,9 +411,9 @@ via8233wr_setformat(kobj_t obj, void *data, uint32_t format) f |= WR_FORMAT_STEREO; if (format & AFMT_S16_LE) f |= WR_FORMAT_16BIT; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); via_wr(via, VIA_WR0_FORMAT, f, 4); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return (0); } @@ -426,7 +426,7 @@ via8233dxs_setformat(kobj_t obj, void *data, uint32_t format) uint32_t r, v; r = ch->rbase + VIA8233_RP_DXS_RATEFMT; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); v = via_rd(via, r, 4); v &= ~(VIA8233_DXS_RATEFMT_STEREO | VIA8233_DXS_RATEFMT_16BIT); @@ -435,7 +435,7 @@ via8233dxs_setformat(kobj_t obj, void *data, uint32_t format) if (format & AFMT_16BIT) v |= VIA8233_DXS_RATEFMT_16BIT; via_wr(via, r, v, 4); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return (0); } @@ -457,10 +457,10 @@ via8233msgd_setformat(kobj_t obj, void *data, uint32_t format) s |= SLOT3(1) | SLOT4(1); } - snd_mtxlock(via->lock); + mtx_lock(&via->lock); via_wr(via, VIA_MC_SLOT_SELECT, s, 4); via_wr(via, VIA_MC_SGD_FORMAT, v, 1); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return (0); } @@ -488,14 +488,14 @@ via8233dxs_setspeed(kobj_t obj, void *data, uint32_t speed) uint32_t r, v; r = ch->rbase + VIA8233_RP_DXS_RATEFMT; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); v = via_rd(via, r, 4) & ~VIA8233_DXS_RATEFMT_48K; /* Careful to avoid overflow (divide by 48 per vt8233c docs) */ v |= VIA8233_DXS_RATEFMT_48K * (speed / 48) / (48000 / 48); via_wr(via, r, v, 4); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return (speed); } @@ -568,8 +568,8 @@ via8233chan_setfragments(kobj_t obj, void *data, blksz &= VIA_BLK_ALIGN; - if (blksz > (sndbuf_getmaxsize(ch->buffer) / VIA_SEGS_MIN)) - blksz = sndbuf_getmaxsize(ch->buffer) / VIA_SEGS_MIN; + if (blksz > (ch->buffer->maxsize / VIA_SEGS_MIN)) + blksz = ch->buffer->maxsize / VIA_SEGS_MIN; if (blksz < VIA_BLK_MIN) blksz = VIA_BLK_MIN; if (blkcnt > VIA_SEGS_MAX) @@ -577,7 +577,7 @@ via8233chan_setfragments(kobj_t obj, void *data, if (blkcnt < VIA_SEGS_MIN) blkcnt = VIA_SEGS_MIN; - while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) { + while ((blksz * blkcnt) > ch->buffer->maxsize) { if ((blkcnt >> 1) >= VIA_SEGS_MIN) blkcnt >>= 1; else if ((blksz >> 1) >= VIA_BLK_MIN) @@ -586,14 +586,14 @@ via8233chan_setfragments(kobj_t obj, void *data, break; } - if ((sndbuf_getblksz(ch->buffer) != blksz || - sndbuf_getblkcnt(ch->buffer) != blkcnt) && + if ((ch->buffer->blksz != blksz || + ch->buffer->blkcnt != blkcnt) && sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) device_printf(via->dev, "%s: failed blksz=%u blkcnt=%u\n", __func__, blksz, blkcnt); - ch->blksz = sndbuf_getblksz(ch->buffer); - ch->blkcnt = sndbuf_getblkcnt(ch->buffer); + ch->blksz = ch->buffer->blksz; + ch->blkcnt = ch->buffer->blkcnt; return (0); } @@ -616,13 +616,13 @@ via8233chan_getptr(kobj_t obj, void *data) struct via_info *via = ch->parent; uint32_t v, index, count, ptr; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); if (via->polling != 0) { ptr = ch->ptr; - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); } else { v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); index = v >> 24; /* Last completed buffer */ count = v & 0x00ffffff; /* Bytes remaining */ ptr = (index + 1) * ch->blksz - count; @@ -660,7 +660,7 @@ via8233wr_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct via_chinfo *ch; int num; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); num = via->rec_num++; ch = &via->rch[num]; ch->parent = via; @@ -670,15 +670,15 @@ via8233wr_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, ch->blkcnt = via->blkcnt; ch->rbase = VIA_WR_BASE(num); via_wr(via, ch->rbase + VIA_WR_RP_SGD_FORMAT, WR_FIFO_ENABLE, 1); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0) return (NULL); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); via8233chan_sgdinit(via, ch, num); via8233chan_reset(via, ch); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return (ch); } @@ -691,7 +691,7 @@ via8233dxs_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct via_chinfo *ch; int num; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); num = via->play_num++; ch = &via->pch[num]; ch->parent = via; @@ -707,15 +707,15 @@ via8233dxs_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, */ ch->rbase = VIA_DXS_BASE(NDXSCHANS - 1 - via->n_dxs_registered); via->n_dxs_registered++; - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0) return (NULL); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); via8233chan_sgdinit(via, ch, NWRCHANS + num); via8233chan_reset(via, ch); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return (ch); } @@ -728,7 +728,7 @@ via8233msgd_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct via_chinfo *ch; int num; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); num = via->play_num++; ch = &via->pch[num]; ch->parent = via; @@ -737,15 +737,15 @@ via8233msgd_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, ch->dir = dir; ch->rbase = VIA_MC_SGD_STATUS; ch->blkcnt = via->blkcnt; - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0) return (NULL); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); via8233chan_sgdinit(via, ch, NWRCHANS + num); via8233chan_reset(via, ch); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return (ch); } @@ -807,9 +807,9 @@ via_poll_callback(void *arg) if (via == NULL) return; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); if (via->polling == 0 || via_chan_active(via) == 0) { - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return; } @@ -825,7 +825,7 @@ via_poll_callback(void *arg) callout_reset(&via->poll_timer, 1/*via->poll_ticks*/, via_poll_callback, via); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { if (ptrigger & (1 << i)) @@ -850,8 +850,7 @@ via_poll_ticks(struct via_info *via) if (ch->channel == NULL || ch->active == 0) continue; pollticks = ((uint64_t)hz * ch->blksz) / - ((uint64_t)sndbuf_getalign(ch->buffer) * - sndbuf_getspd(ch->buffer)); + ((uint64_t)ch->buffer->align * ch->buffer->spd); pollticks >>= 2; if (pollticks > hz) pollticks = hz; @@ -866,8 +865,7 @@ via_poll_ticks(struct via_info *via) if (ch->channel == NULL || ch->active == 0) continue; pollticks = ((uint64_t)hz * ch->blksz) / - ((uint64_t)sndbuf_getalign(ch->buffer) * - sndbuf_getspd(ch->buffer)); + ((uint64_t)ch->buffer->align * ch->buffer->spd); pollticks >>= 2; if (pollticks > hz) pollticks = hz; @@ -890,7 +888,7 @@ via8233chan_trigger(kobj_t obj, void* data, int go) if (!PCMTRIG_COMMON(go)) return (0); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); switch(go) { case PCMTRIG_START: via_buildsgdt(ch); @@ -900,8 +898,8 @@ via8233chan_trigger(kobj_t obj, void* data, int go) ch->ptr = 0; ch->prevptr = 0; pollticks = ((uint64_t)hz * ch->blksz) / - ((uint64_t)sndbuf_getalign(ch->buffer) * - sndbuf_getspd(ch->buffer)); + ((uint64_t)ch->buffer->align * + ch->buffer->spd); pollticks >>= 2; if (pollticks > hz) pollticks = hz; @@ -959,7 +957,7 @@ via8233chan_trigger(kobj_t obj, void* data, int go) default: break; } - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return (0); } @@ -1011,9 +1009,9 @@ via_intr(void *p) uint32_t ptrigger = 0, rtrigger = 0; int i, reg, stat; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); if (via->polling != 0) { - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return; } /* Poll playback channels */ @@ -1048,7 +1046,7 @@ via_intr(void *p) rtrigger |= 1 << i; } } - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { if (ptrigger & (1 << i)) @@ -1170,8 +1168,8 @@ via_attach(device_t dev) uint32_t revid; via = malloc(sizeof *via, M_DEVBUF, M_WAITOK | M_ZERO); - via->lock = snd_mtxcreate(device_get_nameunit(dev), - "snd_via8233 softc"); + mtx_init(&via->lock, device_get_nameunit(dev), "snd_via8233 softc", + MTX_DEF); via->dev = dev; callout_init(&via->poll_timer, 1); @@ -1386,8 +1384,7 @@ bad: bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat); - if (via->lock) - snd_mtxfree(via->lock); + mtx_destroy(&via->lock); if (via) free(via, M_DEVBUF); return (ENXIO); @@ -1406,10 +1403,10 @@ via_detach(device_t dev) via = pcm_getdevinfo(dev); if (via != NULL && (via->play_num != 0 || via->rec_num != 0)) { - snd_mtxlock(via->lock); + mtx_lock(&via->lock); via->polling = 0; callout_stop(&via->poll_timer); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); callout_drain(&via->poll_timer); } @@ -1420,7 +1417,7 @@ via_detach(device_t dev) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); bus_dma_tag_destroy(via->sgd_dmat); - snd_mtxfree(via->lock); + mtx_destroy(&via->lock); free(via, M_DEVBUF); return (0); } diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c index 40f3521a57a2..fe34583b1a25 100644 --- a/sys/dev/sound/pci/via82c686.c +++ b/sys/dev/sound/pci/via82c686.c @@ -90,7 +90,7 @@ struct via_info { struct via_chinfo pch, rch; struct via_dma_op *sgd_table; u_int16_t codec_caps; - struct mtx *lock; + struct mtx lock; }; static u_int32_t via_fmt[] = { @@ -226,8 +226,8 @@ via_buildsgdt(struct via_chinfo *ch) * is feeding. */ seg_size = ch->blksz; - segs = sndbuf_getsize(ch->buffer) / seg_size; - phys_addr = sndbuf_getbufaddr(ch->buffer); + segs = ch->buffer->bufsize / seg_size; + phys_addr = ch->buffer->buf_addr; for (i = 0; i < segs; i++) { flag = (i == segs - 1)? VIA_DMAOP_EOL : VIA_DMAOP_FLAG; @@ -245,7 +245,7 @@ viachan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel * struct via_info *via = devinfo; struct via_chinfo *ch; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); if (dir == PCMDIR_PLAY) { ch = &via->pch; ch->base = VIA_PLAY_DMAOPS_BASE; @@ -268,7 +268,7 @@ viachan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel * ch->channel = c; ch->buffer = b; ch->dir = dir; - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0) return NULL; @@ -290,12 +290,12 @@ viachan_setformat(kobj_t obj, void *data, u_int32_t format) mode_set |= VIA_RPMODE_16BIT; DEB(printf("set format: dir = %d, format=%x\n", ch->dir, format)); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); mode = via_rd(via, ch->mode, 1); mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO); mode |= mode_set; via_wr(via, ch->mode, mode, 1); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); return 0; } @@ -346,14 +346,14 @@ viachan_trigger(kobj_t obj, void *data, int go) DEB(printf("ado located at va=%p pa=%x\n", ch->sgd_table, sgd_addr)); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); if (go == PCMTRIG_START) { via_buildsgdt(ch); via_wr(via, ch->base, sgd_addr, 4); via_wr(via, ch->ctrl, VIA_RPCTRL_START, 1); } else via_wr(via, ch->ctrl, VIA_RPCTRL_TERMINATE, 1); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); DEB(printf("viachan_trigger: go=%d\n", go)); return 0; @@ -367,13 +367,13 @@ viachan_getptr(kobj_t obj, void *data) bus_addr_t sgd_addr = ch->sgd_addr; u_int32_t ptr, base, base1, len, seg; - snd_mtxlock(via->lock); + mtx_lock(&via->lock); base1 = via_rd(via, ch->base, 4); len = via_rd(via, ch->count, 4); base = via_rd(via, ch->base, 4); if (base != base1) /* Avoid race hazard */ len = via_rd(via, ch->count, 4); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base)); @@ -385,7 +385,7 @@ viachan_getptr(kobj_t obj, void *data) seg = SEGS_PER_CHAN; /* Now work out offset: seg less count */ - ptr = (seg * sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN) - len; + ptr = (seg * ch->buffer->bufsize / SEGS_PER_CHAN) - len; if (ch->dir == PCMDIR_REC) { /* DMA appears to operate on memory 'lines' of 32 bytes */ /* so don't return any part line - it isn't in RAM yet */ @@ -426,22 +426,22 @@ via_intr(void *p) /* DEB(printf("viachan_intr\n")); */ /* Read channel */ - snd_mtxlock(via->lock); + mtx_lock(&via->lock); if (via_rd(via, VIA_PLAY_STAT, 1) & VIA_RPSTAT_INTR) { via_wr(via, VIA_PLAY_STAT, VIA_RPSTAT_INTR, 1); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); chn_intr(via->pch.channel); - snd_mtxlock(via->lock); + mtx_lock(&via->lock); } /* Write channel */ if (via_rd(via, VIA_RECORD_STAT, 1) & VIA_RPSTAT_INTR) { via_wr(via, VIA_RECORD_STAT, VIA_RPSTAT_INTR, 1); - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); chn_intr(via->rch.channel); return; } - snd_mtxunlock(via->lock); + mtx_unlock(&via->lock); } /* @@ -472,8 +472,8 @@ via_attach(device_t dev) u_int32_t data, cnt; via = malloc(sizeof(*via), M_DEVBUF, M_WAITOK | M_ZERO); - via->lock = snd_mtxcreate(device_get_nameunit(dev), - "snd_via82c686 softc"); + mtx_init(&via->lock, device_get_nameunit(dev), "snd_via82c686 softc", + MTX_DEF); pci_enable_busmaster(dev); @@ -600,7 +600,7 @@ bad: if (via->sgd_addr) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); if (via->sgd_table) bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat); - if (via->lock) snd_mtxfree(via->lock); + mtx_destroy(&via->lock); if (via) free(via, M_DEVBUF); return ENXIO; } @@ -623,7 +623,7 @@ via_detach(device_t dev) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); bus_dma_tag_destroy(via->sgd_dmat); - snd_mtxfree(via->lock); + mtx_destroy(&via->lock); free(via, M_DEVBUF); return 0; } diff --git a/sys/dev/sound/pci/vibes.c b/sys/dev/sound/pci/vibes.c index 7e908f188614..1b7353464503 100644 --- a/sys/dev/sound/pci/vibes.c +++ b/sys/dev/sound/pci/vibes.c @@ -204,7 +204,7 @@ svchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c } ch->buffer = b; ch->fmt = SND_FORMAT(AFMT_U8, 1, 0); - ch->spd = DSP_DEFAULT_SPEED; + ch->spd = 8000; ch->dma_active = ch->dma_was_active = 0; return ch; @@ -328,9 +328,9 @@ svrchan_trigger(kobj_t obj, void *data, int go) sv_indirect_set(sc, SV_REG_FORMAT, v); /* Program DMA */ - count = sndbuf_getsize(ch->buffer) / 2; /* DMAC uses words */ + count = ch->buffer->bufsize / 2; /* DMAC uses words */ sv_dma_set_config(sc->dmac_st, sc->dmac_sh, - sndbuf_getbufaddr(ch->buffer), + ch->buffer->buf_addr, count - 1, SV_DMA_MODE_AUTO | SV_DMA_MODE_RD); count = count / SV_INTR_PER_BUFFER - 1; @@ -360,7 +360,7 @@ svrchan_getptr(kobj_t obj, void *data) struct sc_info *sc = ch->parent; u_int32_t sz, remain; - sz = sndbuf_getsize(ch->buffer); + sz = ch->buffer->bufsize; /* DMAC uses words */ remain = (sv_dma_get_count(sc->dmac_st, sc->dmac_sh) + 1) * 2; return sz - remain; @@ -404,9 +404,9 @@ svpchan_trigger(kobj_t obj, void *data, int go) sv_indirect_set(sc, SV_REG_FORMAT, v); /* Program DMA */ - count = sndbuf_getsize(ch->buffer); + count = ch->buffer->bufsize; sv_dma_set_config(sc->dmaa_st, sc->dmaa_sh, - sndbuf_getbufaddr(ch->buffer), + ch->buffer->buf_addr, count - 1, SV_DMA_MODE_AUTO | SV_DMA_MODE_WR); count = count / SV_INTR_PER_BUFFER - 1; @@ -437,7 +437,7 @@ svpchan_getptr(kobj_t obj, void *data) struct sc_info *sc = ch->parent; u_int32_t sz, remain; - sz = sndbuf_getsize(ch->buffer); + sz = ch->buffer->bufsize; /* DMAA uses bytes */ remain = sv_dma_get_count(sc->dmaa_st, sc->dmaa_sh) + 1; return (sz - remain); diff --git a/sys/dev/sound/pcm/ac97.c b/sys/dev/sound/pcm/ac97.c index f5ca06cd3942..14ff2f6a62ab 100644 --- a/sys/dev/sound/pcm/ac97.c +++ b/sys/dev/sound/pcm/ac97.c @@ -65,7 +65,7 @@ struct ac97_info { u_int32_t flags; struct ac97mixtable_entry mix[AC97_MIXER_SIZE]; char name[16]; - struct mtx *lock; + struct mtx lock; }; struct ac97_vendorid { @@ -364,7 +364,7 @@ ac97_setrate(struct ac97_info *codec, int which, int rate) return -1; } - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); if (rate != 0) { v = rate; if (codec->extstat & AC97_EXTCAP_DRA) @@ -374,7 +374,7 @@ ac97_setrate(struct ac97_info *codec, int which, int rate) v = ac97_rdcd(codec, which); if (codec->extstat & AC97_EXTCAP_DRA) v <<= 1; - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); return v; } @@ -387,10 +387,10 @@ ac97_setextmode(struct ac97_info *codec, u_int16_t mode) mode); return -1; } - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); ac97_wrcd(codec, AC97_REGEXT_STAT, mode); codec->extstat = ac97_rdcd(codec, AC97_REGEXT_STAT) & AC97_EXTCAPS; - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); return (mode == codec->extstat)? 0 : -1; } @@ -426,9 +426,9 @@ ac97_setrecsrc(struct ac97_info *codec, int channel) if (e->recidx > 0) { int val = e->recidx - 1; val |= val << 8; - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); ac97_wrcd(codec, AC97_REG_RECSEL, val); - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); return 0; } else return -1; @@ -497,13 +497,13 @@ ac97_setmixer(struct ac97_info *codec, unsigned channel, unsigned left, unsigned /* * If the mask bit is set, do not alter the other bits. */ - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); if (e->mask) { int cur = ac97_rdcd(codec, reg); val |= cur & ~(mask); } ac97_wrcd(codec, reg, val); - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); return left | (right << 8); } else { return -1; @@ -603,11 +603,11 @@ ac97_initmixer(struct ac97_info *codec) u_int32_t id; int reg; - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); codec->count = AC97_INIT(codec->methods, codec->devinfo); if (codec->count == 0) { device_printf(codec->dev, "ac97 codec init failed\n"); - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); return ENODEV; } @@ -633,7 +633,7 @@ ac97_initmixer(struct ac97_info *codec) id = (ac97_rdcd(codec, AC97_REG_ID1) << 16) | ac97_rdcd(codec, AC97_REG_ID2); if (id == 0 || id == 0xffffffff) { device_printf(codec->dev, "ac97 codec invalid or not present (id == %x)\n", id); - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); return ENODEV; } @@ -780,18 +780,18 @@ ac97_initmixer(struct ac97_info *codec) } if (bootverbose) device_printf(codec->dev, "ac97 codec dac ready count: %d\n", i); - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); return 0; } static unsigned ac97_reinitmixer(struct ac97_info *codec) { - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); codec->count = AC97_INIT(codec->methods, codec->devinfo); if (codec->count == 0) { device_printf(codec->dev, "ac97 codec init failed\n"); - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); return ENODEV; } @@ -811,7 +811,7 @@ ac97_reinitmixer(struct ac97_info *codec) if ((ac97_rdcd(codec, AC97_REG_POWER) & 2) == 0) device_printf(codec->dev, "ac97 codec reports dac not ready\n"); - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); return 0; } @@ -824,7 +824,7 @@ ac97_create(device_t dev, void *devinfo, kobj_class_t cls) codec = malloc(sizeof(*codec), M_AC97, M_WAITOK | M_ZERO); snprintf(codec->name, sizeof(codec->name), "%s:ac97", device_get_nameunit(dev)); - codec->lock = snd_mtxcreate(codec->name, "ac97 codec"); + mtx_init(&codec->lock, codec->name, "ac97 codec", MTX_DEF); codec->methods = kobj_create(cls, M_AC97, M_WAITOK | M_ZERO); codec->dev = dev; codec->devinfo = devinfo; @@ -844,10 +844,10 @@ ac97_create(device_t dev, void *devinfo, kobj_class_t cls) void ac97_destroy(struct ac97_info *codec) { - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); if (codec->methods != NULL) kobj_delete(codec->methods, M_AC97); - snd_mtxfree(codec->lock); + mtx_destroy(&codec->lock); free(codec, M_AC97); } @@ -960,21 +960,21 @@ sysctl_hw_snd_ac97_eapd(SYSCTL_HANDLER_ARGS) u_int16_t val; codec = oidp->oid_arg1; - if (codec == NULL || codec->id == 0 || codec->lock == NULL) + if (codec == NULL || codec->id == 0) return EINVAL; - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); val = ac97_rdcd(codec, AC97_REG_POWER); inv = (codec->flags & AC97_F_EAPD_INV) ? 0 : 1; ea = (val >> 15) ^ inv; - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); err = sysctl_handle_int(oidp, &ea, 0, req); if (err == 0 && req->newptr != NULL) { if (ea != 0 && ea != 1) return EINVAL; if (ea != ((val >> 15) ^ inv)) { - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); ac97_wrcd(codec, AC97_REG_POWER, val ^ 0x8000); - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); } } return err; @@ -987,12 +987,12 @@ ac97_init_sysctl(struct ac97_info *codec) if (codec == NULL || codec->dev == NULL) return; - snd_mtxlock(codec->lock); + mtx_lock(&codec->lock); orig = ac97_rdcd(codec, AC97_REG_POWER); ac97_wrcd(codec, AC97_REG_POWER, orig ^ 0x8000); val = ac97_rdcd(codec, AC97_REG_POWER); ac97_wrcd(codec, AC97_REG_POWER, orig); - snd_mtxunlock(codec->lock); + mtx_unlock(&codec->lock); if ((val & 0x8000) == (orig & 0x8000)) return; SYSCTL_ADD_PROC(device_get_sysctl_ctx(codec->dev), diff --git a/sys/dev/sound/pcm/buffer.c b/sys/dev/sound/pcm/buffer.c index de535ec2dcba..eb2cbe667bf3 100644 --- a/sys/dev/sound/pcm/buffer.c +++ b/sys/dev/sound/pcm/buffer.c @@ -5,6 +5,10 @@ * Portions Copyright (c) Ryan Beasley <ryan.beasley@gmail.com> - GSoC 2006 * Copyright (c) 1999 Cameron Grant <cg@FreeBSD.org> * All rights reserved. + * Copyright (c) 2025 The FreeBSD Foundation + * + * Portions of this software were developed by Christos Margiolis + * <christos@FreeBSD.org> under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,13 +45,12 @@ #include "snd_fxdiv_gen.h" struct snd_dbuf * -sndbuf_create(device_t dev, char *drv, char *desc, struct pcm_channel *channel) +sndbuf_create(struct pcm_channel *channel, const char *desc) { struct snd_dbuf *b; b = malloc(sizeof(*b), M_DEVBUF, M_WAITOK | M_ZERO); - snprintf(b->name, SNDBUF_NAMELEN, "%s:%s", drv, desc); - b->dev = dev; + snprintf(b->name, SNDBUF_NAMELEN, "%s:%s", channel->name, desc); b->channel = channel; return b; @@ -60,19 +63,13 @@ sndbuf_destroy(struct snd_dbuf *b) free(b, M_DEVBUF); } -bus_addr_t -sndbuf_getbufaddr(struct snd_dbuf *buf) -{ - return (buf->buf_addr); -} - static void sndbuf_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) { struct snd_dbuf *b = (struct snd_dbuf *)arg; if (snd_verbose > 3) { - device_printf(b->dev, "sndbuf_setmap %lx, %lx; ", + printf("sndbuf_setmap %lx, %lx; ", (u_long)segs[0].ds_addr, (u_long)segs[0].ds_len); printf("%p -> %lx\n", b->buf, (u_long)segs[0].ds_addr); } @@ -147,7 +144,7 @@ sndbuf_free(struct snd_dbuf *b) } else free(b->buf, M_DEVBUF); } - seldrain(sndbuf_getsel(b)); + seldrain(&b->sel); b->tmpbuf = NULL; b->shadbuf = NULL; @@ -277,16 +274,10 @@ sndbuf_clear(struct snd_dbuf *b, unsigned int length) length = b->bufsize; data = sndbuf_zerodata(b->fmt); - i = sndbuf_getfreeptr(b); - p = sndbuf_getbuf(b); - while (length > 0) { - p[i] = data; - length--; - i++; - if (i >= b->bufsize) - i = 0; - } + p = b->buf; + for (; length > 0; length--, i++) + p[i % b->bufsize] = data; } /** @@ -298,7 +289,7 @@ void sndbuf_fillsilence(struct snd_dbuf *b) { if (b->bufsize > 0) - memset(sndbuf_getbuf(b), sndbuf_zerodata(b->fmt), b->bufsize); + memset(b->buf, sndbuf_zerodata(b->fmt), b->bufsize); b->rp = 0; b->rl = b->bufsize; } @@ -307,7 +298,7 @@ void sndbuf_fillsilence_rl(struct snd_dbuf *b, u_int rl) { if (b->bufsize > 0) - memset(sndbuf_getbuf(b), sndbuf_zerodata(b->fmt), b->bufsize); + memset(b->buf, sndbuf_zerodata(b->fmt), b->bufsize); b->rp = 0; b->rl = min(b->bufsize, rl); } @@ -344,12 +335,6 @@ sndbuf_reset(struct snd_dbuf *b) sndbuf_clearshadow(b); } -u_int32_t -sndbuf_getfmt(struct snd_dbuf *b) -{ - return b->fmt; -} - int sndbuf_setfmt(struct snd_dbuf *b, u_int32_t fmt) { @@ -359,60 +344,12 @@ sndbuf_setfmt(struct snd_dbuf *b, u_int32_t fmt) return 0; } -unsigned int -sndbuf_getspd(struct snd_dbuf *b) -{ - return b->spd; -} - void sndbuf_setspd(struct snd_dbuf *b, unsigned int spd) { b->spd = spd; } -unsigned int -sndbuf_getalign(struct snd_dbuf *b) -{ - return (b->align); -} - -unsigned int -sndbuf_getblkcnt(struct snd_dbuf *b) -{ - return b->blkcnt; -} - -void -sndbuf_setblkcnt(struct snd_dbuf *b, unsigned int blkcnt) -{ - b->blkcnt = blkcnt; -} - -unsigned int -sndbuf_getblksz(struct snd_dbuf *b) -{ - return b->blksz; -} - -void -sndbuf_setblksz(struct snd_dbuf *b, unsigned int blksz) -{ - b->blksz = blksz; -} - -unsigned int -sndbuf_getbps(struct snd_dbuf *b) -{ - return b->bps; -} - -void * -sndbuf_getbuf(struct snd_dbuf *b) -{ - return b->buf; -} - void * sndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs) { @@ -422,24 +359,6 @@ sndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs) } unsigned int -sndbuf_getsize(struct snd_dbuf *b) -{ - return b->bufsize; -} - -unsigned int -sndbuf_getmaxsize(struct snd_dbuf *b) -{ - return b->maxsize; -} - -unsigned int -sndbuf_getallocsize(struct snd_dbuf *b) -{ - return b->allocsize; -} - -unsigned int sndbuf_runsz(struct snd_dbuf *b) { return b->dl; @@ -451,19 +370,6 @@ sndbuf_setrun(struct snd_dbuf *b, int go) b->dl = go? b->blksz : 0; } -struct selinfo * -sndbuf_getsel(struct snd_dbuf *b) -{ - return &b->sel; -} - -/************************************************************/ -unsigned int -sndbuf_getxrun(struct snd_dbuf *b) -{ - return b->xrun; -} - void sndbuf_setxrun(struct snd_dbuf *b, unsigned int xrun) { @@ -471,18 +377,6 @@ sndbuf_setxrun(struct snd_dbuf *b, unsigned int xrun) } unsigned int -sndbuf_gethwptr(struct snd_dbuf *b) -{ - return b->hp; -} - -void -sndbuf_sethwptr(struct snd_dbuf *b, unsigned int ptr) -{ - b->hp = ptr; -} - -unsigned int sndbuf_getready(struct snd_dbuf *b) { KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl)); @@ -521,38 +415,13 @@ sndbuf_getblocks(struct snd_dbuf *b) return b->total / b->blksz; } -u_int64_t -sndbuf_getprevblocks(struct snd_dbuf *b) -{ - return b->prev_total / b->blksz; -} - -u_int64_t -sndbuf_gettotal(struct snd_dbuf *b) -{ - return b->total; -} - -u_int64_t -sndbuf_getprevtotal(struct snd_dbuf *b) -{ - return b->prev_total; -} - -void -sndbuf_updateprevtotal(struct snd_dbuf *b) -{ - b->prev_total = b->total; -} - unsigned int sndbuf_xbytes(unsigned int v, struct snd_dbuf *from, struct snd_dbuf *to) { if (from == NULL || to == NULL || v == 0) return 0; - return snd_xbytes(v, sndbuf_getalign(from) * sndbuf_getspd(from), - sndbuf_getalign(to) * sndbuf_getspd(to)); + return snd_xbytes(v, from->align * from->spd, to->align * to->spd); } u_int8_t @@ -592,7 +461,7 @@ sndbuf_acquire(struct snd_dbuf *b, u_int8_t *from, unsigned int count) b->total += count; if (from != NULL) { while (count > 0) { - l = min(count, sndbuf_getsize(b) - sndbuf_getfreeptr(b)); + l = min(count, b->bufsize - sndbuf_getfreeptr(b)); bcopy(from, sndbuf_getbufofs(b, sndbuf_getfreeptr(b)), l); from += l; b->rl += l; @@ -628,7 +497,7 @@ sndbuf_dispose(struct snd_dbuf *b, u_int8_t *to, unsigned int count) KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl)); if (to != NULL) { while (count > 0) { - l = min(count, sndbuf_getsize(b) - sndbuf_getreadyptr(b)); + l = min(count, b->bufsize - sndbuf_getreadyptr(b)); bcopy(sndbuf_getbufofs(b, sndbuf_getreadyptr(b)), to, l); to += l; b->rl -= l; @@ -673,7 +542,7 @@ sndbuf_feed(struct snd_dbuf *from, struct snd_dbuf *to, struct pcm_channel *chan if (sndbuf_getfree(to) < count) return (EINVAL); - maxfeed = SND_FXROUND(SND_FXDIV_MAX, sndbuf_getalign(to)); + maxfeed = SND_FXROUND(SND_FXDIV_MAX, to->align); do { cnt = FEEDER_FEED(feeder, channel, to->tmpbuf, @@ -695,40 +564,6 @@ sndbuf_feed(struct snd_dbuf *from, struct snd_dbuf *to, struct pcm_channel *chan return (0); } -/************************************************************/ - -void -sndbuf_dump(struct snd_dbuf *b, char *s, u_int32_t what) -{ - printf("%s: [", s); - if (what & 0x01) - printf(" bufsize: %d, maxsize: %d", b->bufsize, b->maxsize); - if (what & 0x02) - printf(" dl: %d, rp: %d, rl: %d, hp: %d", b->dl, b->rp, b->rl, b->hp); - if (what & 0x04) - printf(" total: %ju, prev_total: %ju, xrun: %d", (uintmax_t)b->total, (uintmax_t)b->prev_total, b->xrun); - if (what & 0x08) - printf(" fmt: 0x%x, spd: %d", b->fmt, b->spd); - if (what & 0x10) - printf(" blksz: %d, blkcnt: %d, flags: 0x%x", b->blksz, b->blkcnt, b->flags); - printf(" ]\n"); -} - -/************************************************************/ -u_int32_t -sndbuf_getflags(struct snd_dbuf *b) -{ - return b->flags; -} - -void -sndbuf_setflags(struct snd_dbuf *b, u_int32_t flags, int on) -{ - b->flags &= ~flags; - if (on) - b->flags |= flags; -} - /** * @brief Clear the shadow buffer by filling with samples equal to zero. * diff --git a/sys/dev/sound/pcm/buffer.h b/sys/dev/sound/pcm/buffer.h index ddf4083ec19f..371ba2dd94ce 100644 --- a/sys/dev/sound/pcm/buffer.h +++ b/sys/dev/sound/pcm/buffer.h @@ -3,6 +3,10 @@ * * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> * All rights reserved. + * Copyright (c) 2025 The FreeBSD Foundation + * + * Portions of this software were developed by Christos Margiolis + * <christos@FreeBSD.org> under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +30,11 @@ * SUCH DAMAGE. */ -#define SNDBUF_F_MANAGED 0x00000008 +#define SNDBUF_F_MANAGED 0x00000001 #define SNDBUF_NAMELEN 48 struct snd_dbuf { - device_t dev; u_int8_t *buf, *tmpbuf; u_int8_t *shadbuf; /**< shadow buffer used w/ S_D_SILENCE/SKIP */ volatile int sl; /**< shadbuf ready length in # of bytes */ @@ -41,7 +44,7 @@ struct snd_dbuf { volatile int rl; /* length of ready area */ volatile int hp; volatile u_int64_t total, prev_total; - int dmachan, dir; /* dma channel */ + int dmachan; /* dma channel */ u_int32_t fmt, spd, bps, align; unsigned int blksz, blkcnt; int xrun; @@ -55,11 +58,9 @@ struct snd_dbuf { char name[SNDBUF_NAMELEN]; }; -struct snd_dbuf *sndbuf_create(device_t dev, char *drv, char *desc, struct pcm_channel *channel); +struct snd_dbuf *sndbuf_create(struct pcm_channel *channel, const char *desc); void sndbuf_destroy(struct snd_dbuf *b); -void sndbuf_dump(struct snd_dbuf *b, char *s, u_int32_t what); - int sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, int dmaflags, unsigned int size); int sndbuf_setup(struct snd_dbuf *b, void *buf, unsigned int size); void sndbuf_free(struct snd_dbuf *b); @@ -72,51 +73,26 @@ void sndbuf_fillsilence_rl(struct snd_dbuf *b, u_int rl); void sndbuf_softreset(struct snd_dbuf *b); void sndbuf_clearshadow(struct snd_dbuf *b); -u_int32_t sndbuf_getfmt(struct snd_dbuf *b); int sndbuf_setfmt(struct snd_dbuf *b, u_int32_t fmt); -unsigned int sndbuf_getspd(struct snd_dbuf *b); void sndbuf_setspd(struct snd_dbuf *b, unsigned int spd); -unsigned int sndbuf_getbps(struct snd_dbuf *b); -bus_addr_t sndbuf_getbufaddr(struct snd_dbuf *buf); - -void *sndbuf_getbuf(struct snd_dbuf *b); void *sndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs); -unsigned int sndbuf_getsize(struct snd_dbuf *b); -unsigned int sndbuf_getmaxsize(struct snd_dbuf *b); -unsigned int sndbuf_getallocsize(struct snd_dbuf *b); -unsigned int sndbuf_getalign(struct snd_dbuf *b); -unsigned int sndbuf_getblkcnt(struct snd_dbuf *b); -void sndbuf_setblkcnt(struct snd_dbuf *b, unsigned int blkcnt); -unsigned int sndbuf_getblksz(struct snd_dbuf *b); -void sndbuf_setblksz(struct snd_dbuf *b, unsigned int blksz); unsigned int sndbuf_runsz(struct snd_dbuf *b); void sndbuf_setrun(struct snd_dbuf *b, int go); -struct selinfo *sndbuf_getsel(struct snd_dbuf *b); -unsigned int sndbuf_getxrun(struct snd_dbuf *b); void sndbuf_setxrun(struct snd_dbuf *b, unsigned int xrun); -unsigned int sndbuf_gethwptr(struct snd_dbuf *b); -void sndbuf_sethwptr(struct snd_dbuf *b, unsigned int ptr); unsigned int sndbuf_getfree(struct snd_dbuf *b); unsigned int sndbuf_getfreeptr(struct snd_dbuf *b); unsigned int sndbuf_getready(struct snd_dbuf *b); unsigned int sndbuf_getreadyptr(struct snd_dbuf *b); u_int64_t sndbuf_getblocks(struct snd_dbuf *b); -u_int64_t sndbuf_getprevblocks(struct snd_dbuf *b); -u_int64_t sndbuf_gettotal(struct snd_dbuf *b); -u_int64_t sndbuf_getprevtotal(struct snd_dbuf *b); unsigned int sndbuf_xbytes(unsigned int v, struct snd_dbuf *from, struct snd_dbuf *to); u_int8_t sndbuf_zerodata(u_int32_t fmt); -void sndbuf_updateprevtotal(struct snd_dbuf *b); int sndbuf_acquire(struct snd_dbuf *b, u_int8_t *from, unsigned int count); int sndbuf_dispose(struct snd_dbuf *b, u_int8_t *to, unsigned int count); int sndbuf_feed(struct snd_dbuf *from, struct snd_dbuf *to, struct pcm_channel *channel, struct pcm_feeder *feeder, unsigned int count); -u_int32_t sndbuf_getflags(struct snd_dbuf *b); -void sndbuf_setflags(struct snd_dbuf *b, u_int32_t flags, int on); - #ifdef OSSV4_EXPERIMENT void sndbuf_getpeaks(struct snd_dbuf *b, int *lp, int *rp); #endif diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index 4d13f20a5262..011dc1427c2e 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -228,19 +228,21 @@ chn_lockinit(struct pcm_channel *c, int dir) { switch (dir) { case PCMDIR_PLAY: - c->lock = snd_mtxcreate(c->name, "pcm play channel"); + mtx_init(&c->lock, c->name, "pcm play channel", MTX_DEF); cv_init(&c->intr_cv, "pcmwr"); break; case PCMDIR_PLAY_VIRTUAL: - c->lock = snd_mtxcreate(c->name, "pcm virtual play channel"); + mtx_init(&c->lock, c->name, "pcm virtual play channel", + MTX_DEF); cv_init(&c->intr_cv, "pcmwrv"); break; case PCMDIR_REC: - c->lock = snd_mtxcreate(c->name, "pcm record channel"); + mtx_init(&c->lock, c->name, "pcm record channel", MTX_DEF); cv_init(&c->intr_cv, "pcmrd"); break; case PCMDIR_REC_VIRTUAL: - c->lock = snd_mtxcreate(c->name, "pcm virtual record channel"); + mtx_init(&c->lock, c->name, "pcm virtual record channel", + MTX_DEF); cv_init(&c->intr_cv, "pcmrdv"); break; default: @@ -262,7 +264,7 @@ chn_lockdestroy(struct pcm_channel *c) cv_destroy(&c->cv); cv_destroy(&c->intr_cv); - snd_mtxfree(c->lock); + mtx_destroy(&c->lock); } /** @@ -271,7 +273,7 @@ chn_lockdestroy(struct pcm_channel *c) * @retval 1 = ready for I/O * @retval 0 = not ready for I/O */ -static int +int chn_polltrigger(struct pcm_channel *c) { struct snd_dbuf *bs = c->bufsoft; @@ -280,10 +282,10 @@ chn_polltrigger(struct pcm_channel *c) CHN_LOCKASSERT(c); if (c->flags & CHN_F_MMAP) { - if (sndbuf_getprevtotal(bs) < c->lw) + if (bs->prev_total < c->lw) delta = c->lw; else - delta = sndbuf_gettotal(bs) - sndbuf_getprevtotal(bs); + delta = bs->total - bs->prev_total; } else { if (c->direction == PCMDIR_PLAY) delta = sndbuf_getfree(bs); @@ -299,7 +301,7 @@ chn_pollreset(struct pcm_channel *c) { CHN_LOCKASSERT(c); - sndbuf_updateprevtotal(c->bufsoft); + c->bufsoft->prev_total = c->bufsoft->total; } static void @@ -313,8 +315,9 @@ chn_wakeup(struct pcm_channel *c) bs = c->bufsoft; if (CHN_EMPTY(c, children.busy)) { - if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c)) - selwakeuppri(sndbuf_getsel(bs), PRIBIO); + KNOTE_LOCKED(&bs->sel.si_note, 0); + if (SEL_WAITING(&bs->sel) && chn_polltrigger(c)) + selwakeuppri(&bs->sel, PRIBIO); CHN_BROADCAST(&c->intr_cv); } else { CHN_FOREACH(ch, c, children.busy) { @@ -336,7 +339,7 @@ chn_sleep(struct pcm_channel *c, int timeout) return (EINVAL); c->sleeping++; - ret = cv_timedwait_sig(&c->intr_cv, c->lock, timeout); + ret = cv_timedwait_sig(&c->intr_cv, &c->lock, timeout); c->sleeping--; return ((c->flags & CHN_F_DEAD) ? EINVAL : ret); @@ -353,22 +356,22 @@ chn_dmaupdate(struct pcm_channel *c) struct snd_dbuf *b = c->bufhard; unsigned int delta, old, hwptr, amt; - KASSERT(sndbuf_getsize(b) > 0, ("bufsize == 0")); + KASSERT(b->bufsize > 0, ("bufsize == 0")); CHN_LOCKASSERT(c); - old = sndbuf_gethwptr(b); + old = b->hp; hwptr = chn_getptr(c); - delta = (sndbuf_getsize(b) + hwptr - old) % sndbuf_getsize(b); - sndbuf_sethwptr(b, hwptr); + delta = (b->bufsize + hwptr - old) % b->bufsize; + b->hp = hwptr; if (c->direction == PCMDIR_PLAY) { amt = min(delta, sndbuf_getready(b)); - amt -= amt % sndbuf_getalign(b); + amt -= amt % b->align; if (amt > 0) sndbuf_dispose(b, NULL, amt); } else { amt = min(delta, sndbuf_getfree(b)); - amt -= amt % sndbuf_getalign(b); + amt -= amt % b->align; if (amt > 0) sndbuf_acquire(b, NULL, amt); } @@ -396,8 +399,7 @@ chn_wrfeed(struct pcm_channel *c) sndbuf_acquire(bs, NULL, sndbuf_getfree(bs)); wasfree = sndbuf_getfree(b); - want = min(sndbuf_getsize(b), - imax(0, sndbuf_xbytes(sndbuf_getsize(bs), bs, b) - + want = min(b->bufsize, imax(0, sndbuf_xbytes(bs->bufsize, bs, b) - sndbuf_getready(b))); amt = min(wasfree, want); if (amt > 0) @@ -438,7 +440,7 @@ chn_write(struct pcm_channel *c, struct uio *buf) { struct snd_dbuf *bs = c->bufsoft; void *off; - int ret, timeout, sz, t, p; + int ret, timeout, sz, p; CHN_LOCKASSERT(c); @@ -446,24 +448,17 @@ chn_write(struct pcm_channel *c, struct uio *buf) timeout = chn_timeout * hz; while (ret == 0 && buf->uio_resid > 0) { + p = sndbuf_getfreeptr(bs); sz = min(buf->uio_resid, sndbuf_getfree(bs)); + sz = min(sz, bs->bufsize - p); if (sz > 0) { - /* - * The following assumes that the free space in - * the buffer can never be less around the - * unlock-uiomove-lock sequence. - */ - while (ret == 0 && sz > 0) { - p = sndbuf_getfreeptr(bs); - t = min(sz, sndbuf_getsize(bs) - p); - off = sndbuf_getbufofs(bs, p); - CHN_UNLOCK(c); - ret = uiomove(off, t, buf); - CHN_LOCK(c); - sz -= t; - sndbuf_acquire(bs, NULL, t); - } - ret = 0; + off = sndbuf_getbufofs(bs, p); + sndbuf_acquire(bs, NULL, sz); + CHN_UNLOCK(c); + ret = uiomove(off, sz, buf); + CHN_LOCK(c); + if (ret != 0) + break; if (CHN_STOPPED(c) && !(c->flags & CHN_F_NOTRIGGER)) { ret = chn_start(c, 0); if (ret != 0) @@ -483,13 +478,7 @@ chn_write(struct pcm_channel *c, struct uio *buf) ret = EAGAIN; } else { ret = chn_sleep(c, timeout); - if (ret == EAGAIN) { - ret = EINVAL; - c->flags |= CHN_F_DEAD; - device_printf(c->dev, "%s(): %s: " - "play interrupt timeout, channel dead\n", - __func__, c->name); - } else if (ret == ERESTART || ret == EINTR) + if (ret == ERESTART || ret == EINTR) c->flags |= CHN_F_ABORTING; } } @@ -552,7 +541,7 @@ chn_read(struct pcm_channel *c, struct uio *buf) { struct snd_dbuf *bs = c->bufsoft; void *off; - int ret, timeout, sz, t, p; + int ret, timeout, sz, p; CHN_LOCKASSERT(c); @@ -568,35 +557,22 @@ chn_read(struct pcm_channel *c, struct uio *buf) timeout = chn_timeout * hz; while (ret == 0 && buf->uio_resid > 0) { + p = sndbuf_getreadyptr(bs); sz = min(buf->uio_resid, sndbuf_getready(bs)); + sz = min(sz, bs->bufsize - p); if (sz > 0) { - /* - * The following assumes that the free space in - * the buffer can never be less around the - * unlock-uiomove-lock sequence. - */ - while (ret == 0 && sz > 0) { - p = sndbuf_getreadyptr(bs); - t = min(sz, sndbuf_getsize(bs) - p); - off = sndbuf_getbufofs(bs, p); - CHN_UNLOCK(c); - ret = uiomove(off, t, buf); - CHN_LOCK(c); - sz -= t; - sndbuf_dispose(bs, NULL, t); - } - ret = 0; + off = sndbuf_getbufofs(bs, p); + sndbuf_dispose(bs, NULL, sz); + CHN_UNLOCK(c); + ret = uiomove(off, sz, buf); + CHN_LOCK(c); + if (ret != 0) + break; } else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) ret = EAGAIN; else { ret = chn_sleep(c, timeout); - if (ret == EAGAIN) { - ret = EINVAL; - c->flags |= CHN_F_DEAD; - device_printf(c->dev, "%s(): %s: " - "record interrupt timeout, channel dead\n", - __func__, c->name); - } else if (ret == ERESTART || ret == EINTR) + if (ret == ERESTART || ret == EINTR) c->flags |= CHN_F_ABORTING; } } @@ -605,30 +581,14 @@ chn_read(struct pcm_channel *c, struct uio *buf) } void -chn_intr_locked(struct pcm_channel *c) +chn_intr(struct pcm_channel *c) { - - CHN_LOCKASSERT(c); - + CHN_LOCK(c); c->interrupts++; - if (c->direction == PCMDIR_PLAY) chn_wrintr(c); else chn_rdintr(c); -} - -void -chn_intr(struct pcm_channel *c) -{ - - if (CHN_LOCKOWNED(c)) { - chn_intr_locked(c); - return; - } - - CHN_LOCK(c); - chn_intr_locked(c); CHN_UNLOCK(c); } @@ -663,7 +623,7 @@ chn_start(struct pcm_channel *c, int force) pb = CHN_BUF_PARENT(c, b); i = sndbuf_xbytes(sndbuf_getready(bs), bs, pb); - j = sndbuf_getalign(pb); + j = pb->align; } } if (snd_verbose > 3 && CHN_EMPTY(c, children)) @@ -686,7 +646,7 @@ chn_start(struct pcm_channel *c, int force) if (c->parentchannel == NULL) { if (c->direction == PCMDIR_PLAY) sndbuf_fillsilence_rl(b, - sndbuf_xbytes(sndbuf_getsize(bs), bs, b)); + sndbuf_xbytes(bs->bufsize, bs, b)); if (snd_verbose > 3) device_printf(c->dev, "%s(): %s starting! (%s/%s) " @@ -699,8 +659,8 @@ chn_start(struct pcm_channel *c, int force) "running", sndbuf_getready(b), force, i, j, c->timeout, - (sndbuf_getsize(b) * 1000) / - (sndbuf_getalign(b) * sndbuf_getspd(b))); + (b->bufsize * 1000) / + (b->align * b->spd)); } err = chn_trigger(c, PCMTRIG_START); } @@ -759,7 +719,7 @@ chn_sync(struct pcm_channel *c, int threshold) syncdelay = chn_syncdelay; if (syncdelay < 0 && (threshold > 0 || sndbuf_getready(bs) > 0)) - minflush += sndbuf_xbytes(sndbuf_getsize(b), b, bs); + minflush += sndbuf_xbytes(b->bufsize, b, bs); /* * Append (0-1000) millisecond trailing buffer (if needed) @@ -767,10 +727,10 @@ chn_sync(struct pcm_channel *c, int threshold) * to avoid audible truncation. */ if (syncdelay > 0) - minflush += (sndbuf_getalign(bs) * sndbuf_getspd(bs) * + minflush += (bs->align * bs->spd * ((syncdelay > 1000) ? 1000 : syncdelay)) / 1000; - minflush -= minflush % sndbuf_getalign(bs); + minflush -= minflush % bs->align; if (minflush > 0) { threshold = min(minflush, sndbuf_getfree(bs)); @@ -781,14 +741,14 @@ chn_sync(struct pcm_channel *c, int threshold) resid = sndbuf_getready(bs); residp = resid; - blksz = sndbuf_getblksz(b); + blksz = b->blksz; if (blksz < 1) { device_printf(c->dev, "%s(): WARNING: blksz < 1 ! maxsize=%d [%d/%d/%d]\n", - __func__, sndbuf_getmaxsize(b), sndbuf_getsize(b), - sndbuf_getblksz(b), sndbuf_getblkcnt(b)); - if (sndbuf_getblkcnt(b) > 0) - blksz = sndbuf_getsize(b) / sndbuf_getblkcnt(b); + __func__, b->maxsize, b->bufsize, + b->blksz, b->blkcnt); + if (b->blkcnt > 0) + blksz = b->bufsize / b->blkcnt; if (blksz < 1) blksz = 1; } @@ -874,7 +834,7 @@ chn_poll(struct pcm_channel *c, int ev, struct thread *td) chn_pollreset(c); ret = ev; } else - selrecord(td, sndbuf_getsel(bs)); + selrecord(td, &bs->sel); return (ret); } @@ -1257,7 +1217,7 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, chn_vpc_reset(c, SND_VOL_C_PCM, 1); CHN_UNLOCK(c); - fc = feeder_getclass(NULL); + fc = feeder_getclass(FEEDER_ROOT); if (fc == NULL) { device_printf(d->dev, "%s(): failed to get feeder class\n", __func__); @@ -1268,8 +1228,8 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, goto fail; } - b = sndbuf_create(c->dev, c->name, "primary", c); - bs = sndbuf_create(c->dev, c->name, "secondary", c); + b = sndbuf_create(c, "primary"); + bs = sndbuf_create(c, "secondary"); if (b == NULL || bs == NULL) { device_printf(d->dev, "%s(): failed to create %s buffer\n", __func__, b == NULL ? "hardware" : "software"); @@ -1277,6 +1237,7 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, } c->bufhard = b; c->bufsoft = bs; + knlist_init_mtx(&bs->sel.si_note, &c->lock); c->devinfo = CHANNEL_INIT(c->methods, devinfo, b, c, direction); if (c->devinfo == NULL) { @@ -1284,7 +1245,7 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, goto fail; } - if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0)) { + if (b->bufsize == 0 && ((c->flags & CHN_F_VIRTUAL) == 0)) { device_printf(d->dev, "%s(): hardware buffer's size is 0\n", __func__); goto fail; @@ -1302,7 +1263,7 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, * seems to only come into existence in sndbuf_resize(). */ if (c->direction == PCMDIR_PLAY) { - bs->sl = sndbuf_getmaxsize(bs); + bs->sl = bs->maxsize; bs->shadbuf = malloc(bs->sl, M_DEVBUF, M_WAITOK); } @@ -1319,8 +1280,8 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, if ((c->flags & CHN_F_VIRTUAL) == 0) { CHN_INSERT_SORT_ASCEND(d, c, channels.pcm.primary); /* Initialize the *vchanrate/vchanformat parameters. */ - *vchanrate = sndbuf_getspd(c->bufsoft); - *vchanformat = sndbuf_getfmt(c->bufsoft); + *vchanrate = c->bufsoft->spd; + *vchanformat = c->bufsoft->fmt; } return (c); @@ -1371,10 +1332,13 @@ chn_kill(struct pcm_channel *c) } free_unr(chn_getunr(d, c->type), c->unit); feeder_remove(c); - if (c->devinfo && CHANNEL_FREE(c->methods, c->devinfo)) - sndbuf_free(b); - if (bs) + if (c->devinfo) + CHANNEL_FREE(c->methods, c->devinfo); + if (bs) { + knlist_clear(&bs->sel.si_note, 0); + knlist_destroy(&bs->sel.si_note); sndbuf_destroy(bs); + } if (b) sndbuf_destroy(b); CHN_LOCK(c); @@ -1895,20 +1859,20 @@ chn_resizebuf(struct pcm_channel *c, int latency, b = c->bufhard; if (!(blksz == 0 || blkcnt == -1) && - (blksz < 16 || blksz < sndbuf_getalign(bs) || blkcnt < 2 || + (blksz < 16 || blksz < bs->align || blkcnt < 2 || (blksz * blkcnt) > CHN_2NDBUFMAXSIZE)) return EINVAL; - chn_calclatency(c->direction, latency, sndbuf_getalign(bs), - sndbuf_getalign(bs) * sndbuf_getspd(bs), CHN_2NDBUFMAXSIZE, + chn_calclatency(c->direction, latency, bs->align, + bs->align * bs->spd, CHN_2NDBUFMAXSIZE, &sblksz, &sblkcnt); if (blksz == 0 || blkcnt == -1) { if (blkcnt == -1) c->flags &= ~CHN_F_HAS_SIZE; if (c->flags & CHN_F_HAS_SIZE) { - blksz = sndbuf_getblksz(bs); - blkcnt = sndbuf_getblkcnt(bs); + blksz = bs->blksz; + blkcnt = bs->blkcnt; } } else c->flags |= CHN_F_HAS_SIZE; @@ -1921,7 +1885,7 @@ chn_resizebuf(struct pcm_channel *c, int latency, * defeat the purpose of having custom control. The least * we can do is round it to the nearest ^2 and align it. */ - sblksz = round_blksz(blksz, sndbuf_getalign(bs)); + sblksz = round_blksz(blksz, bs->align); sblkcnt = round_pow2(blkcnt); } @@ -1934,49 +1898,46 @@ chn_resizebuf(struct pcm_channel *c, int latency, CHN_LOCK(c); if (c->direction == PCMDIR_PLAY) { limit = (pb != NULL) ? - sndbuf_xbytes(sndbuf_getsize(pb), pb, bs) : 0; + sndbuf_xbytes(pb->bufsize, pb, bs) : 0; } else { limit = (pb != NULL) ? - sndbuf_xbytes(sndbuf_getblksz(pb), pb, bs) * 2 : 0; + sndbuf_xbytes(pb->blksz, pb, bs) * 2 : 0; } } else { hblkcnt = 2; if (c->flags & CHN_F_HAS_SIZE) { hblksz = round_blksz(sndbuf_xbytes(sblksz, bs, b), - sndbuf_getalign(b)); - hblkcnt = round_pow2(sndbuf_getblkcnt(bs)); + b->align); + hblkcnt = round_pow2(bs->blkcnt); } else chn_calclatency(c->direction, latency, - sndbuf_getalign(b), - sndbuf_getalign(b) * sndbuf_getspd(b), + b->align, b->align * b->spd, CHN_2NDBUFMAXSIZE, &hblksz, &hblkcnt); - if ((hblksz << 1) > sndbuf_getmaxsize(b)) - hblksz = round_blksz(sndbuf_getmaxsize(b) >> 1, - sndbuf_getalign(b)); + if ((hblksz << 1) > b->maxsize) + hblksz = round_blksz(b->maxsize >> 1, b->align); - while ((hblksz * hblkcnt) > sndbuf_getmaxsize(b)) { + while ((hblksz * hblkcnt) > b->maxsize) { if (hblkcnt < 4) hblksz >>= 1; else hblkcnt >>= 1; } - hblksz -= hblksz % sndbuf_getalign(b); + hblksz -= hblksz % b->align; CHN_UNLOCK(c); if (chn_usefrags == 0 || CHANNEL_SETFRAGMENTS(c->methods, c->devinfo, hblksz, hblkcnt) != 0) - sndbuf_setblksz(b, CHANNEL_SETBLOCKSIZE(c->methods, - c->devinfo, hblksz)); + b->blksz = CHANNEL_SETBLOCKSIZE(c->methods, + c->devinfo, hblksz); CHN_LOCK(c); if (!CHN_EMPTY(c, children)) { nsblksz = round_blksz( - sndbuf_xbytes(sndbuf_getblksz(b), b, bs), - sndbuf_getalign(bs)); - nsblkcnt = sndbuf_getblkcnt(b); + sndbuf_xbytes(b->blksz, b, bs), bs->align); + nsblkcnt = b->blkcnt; if (c->direction == PCMDIR_PLAY) { do { nsblkcnt--; @@ -1988,7 +1949,7 @@ chn_resizebuf(struct pcm_channel *c, int latency, sblkcnt = nsblkcnt; limit = 0; } else - limit = sndbuf_xbytes(sndbuf_getblksz(b), b, bs) * 2; + limit = sndbuf_xbytes(b->blksz, b, bs) * 2; } if (limit > CHN_2NDBUFMAXSIZE) @@ -2004,10 +1965,10 @@ chn_resizebuf(struct pcm_channel *c, int latency, sblkcnt >>= 1; } - sblksz -= sblksz % sndbuf_getalign(bs); + sblksz -= sblksz % bs->align; - if (sndbuf_getblkcnt(bs) != sblkcnt || sndbuf_getblksz(bs) != sblksz || - sndbuf_getsize(bs) != (sblkcnt * sblksz)) { + if (bs->blkcnt != sblkcnt || bs->blksz != sblksz || + bs->bufsize != (sblkcnt * sblksz)) { ret = sndbuf_remalloc(bs, sblkcnt, sblksz); if (ret != 0) { device_printf(c->dev, "%s(): Failed: %d %d\n", @@ -2019,8 +1980,8 @@ chn_resizebuf(struct pcm_channel *c, int latency, /* * Interrupt timeout */ - c->timeout = ((u_int64_t)hz * sndbuf_getsize(bs)) / - ((u_int64_t)sndbuf_getspd(bs) * sndbuf_getalign(bs)); + c->timeout = ((u_int64_t)hz * bs->bufsize) / + ((u_int64_t)bs->spd * bs->align); if (c->parentchannel != NULL) c->timeout = min(c->timeout, c->parentchannel->timeout); if (c->timeout < 1) @@ -2030,7 +1991,7 @@ chn_resizebuf(struct pcm_channel *c, int latency, * OSSv4 docs: "By default OSS will set the low water level equal * to the fragment size which is optimal in most cases." */ - c->lw = sndbuf_getblksz(bs); + c->lw = bs->blksz; chn_resetbuf(c); if (snd_verbose > 3) @@ -2039,10 +2000,10 @@ chn_resizebuf(struct pcm_channel *c, int latency, __func__, CHN_DIRSTR(c), (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware", c->timeout, - sndbuf_getsize(b), sndbuf_getblksz(b), - sndbuf_getblkcnt(b), - sndbuf_getsize(bs), sndbuf_getblksz(bs), - sndbuf_getblkcnt(bs), limit); + b->bufsize, b->blksz, + b->blkcnt, + bs->bufsize, bs->blksz, + bs->blkcnt, limit); return 0; } @@ -2085,7 +2046,7 @@ chn_setparam(struct pcm_channel *c, uint32_t format, uint32_t speed) sndbuf_setspd(c->bufhard, CHANNEL_SETSPEED(c->methods, c->devinfo, hwspeed)); - hwspeed = sndbuf_getspd(c->bufhard); + hwspeed = c->bufhard->spd; delta = (hwspeed > speed) ? (hwspeed - speed) : (speed - hwspeed); @@ -2095,8 +2056,7 @@ chn_setparam(struct pcm_channel *c, uint32_t format, uint32_t speed) ret = feeder_chain(c); if (ret == 0) - ret = CHANNEL_SETFORMAT(c->methods, c->devinfo, - sndbuf_getfmt(c->bufhard)); + ret = CHANNEL_SETFORMAT(c->methods, c->devinfo, c->bufhard->fmt); if (ret == 0) ret = chn_resizebuf(c, -2, 0, 0); @@ -2339,7 +2299,7 @@ chn_getptr(struct pcm_channel *c) CHN_LOCKASSERT(c); hwptr = (CHN_STARTED(c)) ? CHANNEL_GETPTR(c->methods, c->devinfo) : 0; - return (hwptr - (hwptr % sndbuf_getalign(c->bufhard))); + return (hwptr - (hwptr % c->bufhard->align)); } struct pcmchan_caps * diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h index 9ad21d219001..6415f5c88984 100644 --- a/sys/dev/sound/pcm/channel.h +++ b/sys/dev/sound/pcm/channel.h @@ -110,7 +110,7 @@ struct pcm_channel { int type; char name[CHN_NAMELEN]; char comm[MAXCOMLEN + 1]; - struct mtx *lock; + struct mtx lock; int trigger; /** * For interrupt manipulations. @@ -261,6 +261,7 @@ int chn_read(struct pcm_channel *c, struct uio *buf); u_int32_t chn_start(struct pcm_channel *c, int force); int chn_sync(struct pcm_channel *c, int threshold); int chn_flush(struct pcm_channel *c); +int chn_polltrigger(struct pcm_channel *c); int chn_poll(struct pcm_channel *c, int ev, struct thread *td); char *chn_mkname(char *buf, size_t len, struct pcm_channel *c); @@ -297,7 +298,6 @@ int chn_oss_setorder(struct pcm_channel *, unsigned long long *); int chn_oss_getmask(struct pcm_channel *, uint32_t *); void chn_resetbuf(struct pcm_channel *c); -void chn_intr_locked(struct pcm_channel *c); void chn_intr(struct pcm_channel *c); int chn_abort(struct pcm_channel *c); @@ -319,12 +319,12 @@ int chn_syncdestroy(struct pcm_channel *c); int chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak); #endif -#define CHN_LOCKOWNED(c) mtx_owned((c)->lock) -#define CHN_LOCK(c) mtx_lock((c)->lock) -#define CHN_UNLOCK(c) mtx_unlock((c)->lock) -#define CHN_TRYLOCK(c) mtx_trylock((c)->lock) -#define CHN_LOCKASSERT(c) mtx_assert((c)->lock, MA_OWNED) -#define CHN_UNLOCKASSERT(c) mtx_assert((c)->lock, MA_NOTOWNED) +#define CHN_LOCKOWNED(c) mtx_owned(&(c)->lock) +#define CHN_LOCK(c) mtx_lock(&(c)->lock) +#define CHN_UNLOCK(c) mtx_unlock(&(c)->lock) +#define CHN_TRYLOCK(c) mtx_trylock(&(c)->lock) +#define CHN_LOCKASSERT(c) mtx_assert(&(c)->lock, MA_OWNED) +#define CHN_UNLOCKASSERT(c) mtx_assert(&(c)->lock, MA_NOTOWNED) #define CHN_BROADCAST(x) cv_broadcastpri(x, PRIBIO) diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index 27d5b740b90b..62db4592f206 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -72,8 +72,6 @@ SYSCTL_INT(_hw_snd, OID_AUTO, basename_clone, CTLFLAG_RWTUN, #define DSP_F_READ(x) ((x) & FREAD) #define DSP_F_WRITE(x) ((x) & FWRITE) -#define OLDPCM_IOCTL - static d_open_t dsp_open; static d_read_t dsp_read; static d_write_t dsp_write; @@ -81,6 +79,7 @@ static d_ioctl_t dsp_ioctl; static d_poll_t dsp_poll; static d_mmap_t dsp_mmap; static d_mmap_single_t dsp_mmap_single; +static d_kqfilter_t dsp_kqfilter; struct cdevsw dsp_cdevsw = { .d_version = D_VERSION, @@ -89,6 +88,7 @@ struct cdevsw dsp_cdevsw = { .d_write = dsp_write, .d_ioctl = dsp_ioctl, .d_poll = dsp_poll, + .d_kqfilter = dsp_kqfilter, .d_mmap = dsp_mmap, .d_mmap_single = dsp_mmap_single, .d_name = "dsp", @@ -462,14 +462,9 @@ static __inline int dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf) { struct snddev_info *d; - struct pcm_channel **ch; + struct pcm_channel *ch; int (*chn_io)(struct pcm_channel *, struct uio *); - int prio, ret; - pid_t runpid; - - KASSERT(buf != NULL && - (buf->uio_rw == UIO_READ || buf->uio_rw == UIO_WRITE), - ("%s(): io train wreck!", __func__)); + int ret; d = priv->sc; if (!DSP_REGISTERED(d)) @@ -479,53 +474,39 @@ dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf) switch (buf->uio_rw) { case UIO_READ: - prio = FREAD; - ch = &priv->rdch; + ch = priv->rdch; chn_io = chn_read; break; case UIO_WRITE: - prio = FWRITE; - ch = &priv->wrch; + ch = priv->wrch; chn_io = chn_write; break; - default: - panic("invalid/corrupted uio direction: %d", buf->uio_rw); - break; } - - runpid = buf->uio_td->td_proc->p_pid; - - dsp_lock_chans(priv, prio); - - if (*ch == NULL || !((*ch)->flags & CHN_F_BUSY)) { - if (priv->rdch != NULL || priv->wrch != NULL) - dsp_unlock_chans(priv, prio); + if (ch == NULL) { PCM_GIANT_EXIT(d); - return (EBADF); + return (ENXIO); } + CHN_LOCK(ch); - if (((*ch)->flags & (CHN_F_MMAP | CHN_F_DEAD)) || - (((*ch)->flags & CHN_F_RUNNING) && (*ch)->pid != runpid)) { - dsp_unlock_chans(priv, prio); + if (!(ch->flags & CHN_F_BUSY) || + (ch->flags & (CHN_F_MMAP | CHN_F_DEAD))) { + CHN_UNLOCK(ch); PCM_GIANT_EXIT(d); - return (EINVAL); - } else if (!((*ch)->flags & CHN_F_RUNNING)) { - (*ch)->flags |= CHN_F_RUNNING; - (*ch)->pid = runpid; - } + return (ENXIO); + } else if (!(ch->flags & CHN_F_RUNNING)) + ch->flags |= CHN_F_RUNNING; /* * chn_read/write must give up channel lock in order to copy bytes * from/to userland, so up the "in progress" counter to make sure * someone else doesn't come along and muss up the buffer. */ - ++(*ch)->inprog; - ret = chn_io(*ch, buf); - --(*ch)->inprog; - - CHN_BROADCAST(&(*ch)->cv); + ch->inprog++; + ret = chn_io(ch, buf); + ch->inprog--; - dsp_unlock_chans(priv, prio); + CHN_BROADCAST(&ch->cv); + CHN_UNLOCK(ch); PCM_GIANT_LEAVE(d); @@ -806,10 +787,6 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, } switch(cmd) { -#ifdef OLDPCM_IOCTL - /* - * we start with the new ioctl interface. - */ case AIONWRITE: /* how many bytes can write ? */ if (wrch) { CHN_LOCK(wrch); @@ -835,13 +812,13 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, if (wrch) { CHN_LOCK(wrch); chn_setblocksize(wrch, 2, p->play_size); - p->play_size = sndbuf_getblksz(wrch->bufsoft); + p->play_size = wrch->bufsoft->blksz; CHN_UNLOCK(wrch); } if (rdch) { CHN_LOCK(rdch); chn_setblocksize(rdch, 2, p->rec_size); - p->rec_size = sndbuf_getblksz(rdch->bufsoft); + p->rec_size = rdch->bufsoft->blksz; CHN_UNLOCK(rdch); } PCM_RELEASE_QUICK(d); @@ -853,12 +830,12 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, if (wrch) { CHN_LOCK(wrch); - p->play_size = sndbuf_getblksz(wrch->bufsoft); + p->play_size = wrch->bufsoft->blksz; CHN_UNLOCK(wrch); } if (rdch) { CHN_LOCK(rdch); - p->rec_size = sndbuf_getblksz(rdch->bufsoft); + p->rec_size = rdch->bufsoft->blksz; CHN_UNLOCK(rdch); } } @@ -973,8 +950,8 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, pcaps? pcaps->minspeed : 0); p->rate_max = min(rcaps? rcaps->maxspeed : 1000000, pcaps? pcaps->maxspeed : 1000000); - p->bufsize = min(rdch? sndbuf_getsize(rdch->bufsoft) : 1000000, - wrch? sndbuf_getsize(wrch->bufsoft) : 1000000); + p->bufsize = min(rdch? rdch->bufsoft->bufsize : 1000000, + wrch? wrch->bufsoft->bufsize : 1000000); /* XXX bad on sb16 */ p->formats = (rdch? chn_getformats(rdch) : 0xffffffff) & (wrch? chn_getformats(wrch) : 0xffffffff); @@ -1026,10 +1003,6 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, printf("AIOSYNC chan 0x%03lx pos %lu unimplemented\n", ((snd_sync_parm *)arg)->chan, ((snd_sync_parm *)arg)->pos); break; -#endif - /* - * here follow the standard ioctls (filio.h etc.) - */ case FIONREAD: /* get # bytes to read */ if (rdch) { CHN_LOCK(rdch); @@ -1068,16 +1041,11 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, } break; - /* - * Finally, here is the linux-compatible ioctl interface - */ -#define THE_REAL_SNDCTL_DSP_GETBLKSIZE _IOWR('P', 4, int) - case THE_REAL_SNDCTL_DSP_GETBLKSIZE: case SNDCTL_DSP_GETBLKSIZE: chn = wrch ? wrch : rdch; if (chn) { CHN_LOCK(chn); - *arg_i = sndbuf_getblksz(chn->bufsoft); + *arg_i = chn->bufsoft->blksz; CHN_UNLOCK(chn); } else { *arg_i = 0; @@ -1315,8 +1283,8 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, if (rdch) { CHN_LOCK(rdch); ret = chn_setblocksize(rdch, maxfrags, fragsz); - r_maxfrags = sndbuf_getblkcnt(rdch->bufsoft); - r_fragsz = sndbuf_getblksz(rdch->bufsoft); + r_maxfrags = rdch->bufsoft->blkcnt; + r_fragsz = rdch->bufsoft->blksz; CHN_UNLOCK(rdch); } else { r_maxfrags = maxfrags; @@ -1325,8 +1293,8 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, if (wrch && ret == 0) { CHN_LOCK(wrch); ret = chn_setblocksize(wrch, maxfrags, fragsz); - maxfrags = sndbuf_getblkcnt(wrch->bufsoft); - fragsz = sndbuf_getblksz(wrch->bufsoft); + maxfrags = wrch->bufsoft->blkcnt; + fragsz = wrch->bufsoft->blksz; CHN_UNLOCK(wrch); } else { /* use whatever came from the read channel */ maxfrags = r_maxfrags; @@ -1352,9 +1320,9 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, CHN_LOCK(rdch); a->bytes = sndbuf_getready(bs); - a->fragments = a->bytes / sndbuf_getblksz(bs); - a->fragstotal = sndbuf_getblkcnt(bs); - a->fragsize = sndbuf_getblksz(bs); + a->fragments = a->bytes / bs->blksz; + a->fragstotal = bs->blkcnt; + a->fragsize = bs->blksz; CHN_UNLOCK(rdch); } else ret = EINVAL; @@ -1370,9 +1338,9 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, CHN_LOCK(wrch); a->bytes = sndbuf_getfree(bs); - a->fragments = a->bytes / sndbuf_getblksz(bs); - a->fragstotal = sndbuf_getblkcnt(bs); - a->fragsize = sndbuf_getblksz(bs); + a->fragments = a->bytes / bs->blksz; + a->fragstotal = bs->blkcnt; + a->fragsize = bs->blksz; CHN_UNLOCK(wrch); } else ret = EINVAL; @@ -1386,7 +1354,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct snd_dbuf *bs = rdch->bufsoft; CHN_LOCK(rdch); - a->bytes = sndbuf_gettotal(bs); + a->bytes = bs->total; a->blocks = sndbuf_getblocks(bs) - rdch->blocks; a->ptr = sndbuf_getfreeptr(bs); rdch->blocks = sndbuf_getblocks(bs); @@ -1403,7 +1371,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct snd_dbuf *bs = wrch->bufsoft; CHN_LOCK(wrch); - a->bytes = sndbuf_gettotal(bs); + a->bytes = bs->total; a->blocks = sndbuf_getblocks(bs) - wrch->blocks; a->ptr = sndbuf_getreadyptr(bs); wrch->blocks = sndbuf_getblocks(bs); @@ -1629,7 +1597,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct snd_dbuf *bs; CHN_LOCK(wrch); while (wrch->inprog != 0) - cv_wait(&wrch->cv, wrch->lock); + cv_wait(&wrch->cv, &wrch->lock); bs = wrch->bufsoft; if ((bs->shadbuf != NULL) && (sndbuf_getready(bs) > 0)) { bs->sl = sndbuf_getready(bs); @@ -1653,7 +1621,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct snd_dbuf *bs; CHN_LOCK(wrch); while (wrch->inprog != 0) - cv_wait(&wrch->cv, wrch->lock); + cv_wait(&wrch->cv, &wrch->lock); bs = wrch->bufsoft; if ((bs->shadbuf != NULL) && (bs->sl > 0)) { sndbuf_softreset(bs); @@ -1690,8 +1658,8 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, CHN_LOCK(chn); bs = chn->bufsoft; - oc->samples = sndbuf_gettotal(bs) / sndbuf_getalign(bs); - oc->fifo_samples = sndbuf_getready(bs) / sndbuf_getalign(bs); + oc->samples = bs->total / bs->align; + oc->fifo_samples = sndbuf_getready(bs) / bs->align; CHN_UNLOCK(chn); } break; @@ -1992,7 +1960,7 @@ dsp_mmap_single(struct cdev *i_dev, vm_ooffset_t *offset, c = ((nprot & PROT_WRITE) != 0) ? wrch : rdch; if (c == NULL || (c->flags & CHN_F_MMAP_INVALID) || - (*offset + size) > sndbuf_getallocsize(c->bufsoft) || + (*offset + size) > c->bufsoft->allocsize || (wrch != NULL && (wrch->flags & CHN_F_MMAP_INVALID)) || (rdch != NULL && (rdch->flags & CHN_F_MMAP_INVALID))) { dsp_unlock_chans(priv, FREAD | FWRITE); @@ -2962,6 +2930,86 @@ dsp_oss_getchannelmask(struct pcm_channel *wrch, struct pcm_channel *rdch, return (ret); } +static void +dsp_kqdetach(struct knote *kn) +{ + struct pcm_channel *ch = kn->kn_hook; + + if (ch == NULL) + return; + CHN_LOCK(ch); + knlist_remove(&ch->bufsoft->sel.si_note, kn, 1); + CHN_UNLOCK(ch); +} + +static int +dsp_kqevent(struct knote *kn, long hint) +{ + struct pcm_channel *ch = kn->kn_hook; + + CHN_LOCKASSERT(ch); + if (ch->flags & CHN_F_DEAD) { + kn->kn_flags |= EV_EOF; + return (1); + } + kn->kn_data = 0; + if (chn_polltrigger(ch)) { + if (kn->kn_filter == EVFILT_READ) + kn->kn_data = sndbuf_getready(ch->bufsoft); + else + kn->kn_data = sndbuf_getfree(ch->bufsoft); + } + + return (kn->kn_data > 0); +} + +static const struct filterops dsp_filtops = { + .f_isfd = 1, + .f_detach = dsp_kqdetach, + .f_event = dsp_kqevent, +}; + +static int +dsp_kqfilter(struct cdev *dev, struct knote *kn) +{ + struct dsp_cdevpriv *priv; + struct snddev_info *d; + struct pcm_channel *ch; + int err = 0; + + if ((err = devfs_get_cdevpriv((void **)&priv)) != 0) + return (err); + + d = priv->sc; + if (!DSP_REGISTERED(d)) + return (EBADF); + PCM_GIANT_ENTER(d); + switch (kn->kn_filter) { + case EVFILT_READ: + ch = priv->rdch; + break; + case EVFILT_WRITE: + ch = priv->wrch; + break; + default: + kn->kn_hook = NULL; + err = EINVAL; + ch = NULL; + break; + } + if (ch != NULL) { + kn->kn_fop = &dsp_filtops; + CHN_LOCK(ch); + knlist_add(&ch->bufsoft->sel.si_note, kn, 1); + CHN_UNLOCK(ch); + kn->kn_hook = ch; + } else + err = EINVAL; + PCM_GIANT_LEAVE(d); + + return (err); +} + #ifdef OSSV4_EXPERIMENT /** * @brief Retrieve an audio device's label diff --git a/sys/dev/sound/pcm/feeder.c b/sys/dev/sound/pcm/feeder.c index af3ada441e48..fa4e4e16a133 100644 --- a/sys/dev/sound/pcm/feeder.c +++ b/sys/dev/sound/pcm/feeder.c @@ -36,94 +36,25 @@ #endif #include <dev/sound/pcm/sound.h> -#include <dev/sound/pcm/vchan.h> #include "feeder_if.h" static MALLOC_DEFINE(M_FEEDER, "feeder", "pcm feeder"); -#define MAXFEEDERS 256 - -struct feedertab_entry { - SLIST_ENTRY(feedertab_entry) link; - struct feeder_class *feederclass; - struct pcm_feederdesc *desc; - - int idx; -}; -static SLIST_HEAD(, feedertab_entry) feedertab; -static int feedercnt = 0; - -/*****************************************************************************/ - -static void -feeder_register_root(void *p) -{ - struct feeder_class *fc = p; - struct feedertab_entry *fte; - - MPASS(feedercnt == 0); - KASSERT(fc->desc == NULL, ("first feeder not root: %s", fc->name)); - - SLIST_INIT(&feedertab); - fte = malloc(sizeof(*fte), M_FEEDER, M_WAITOK | M_ZERO); - fte->feederclass = fc; - fte->desc = NULL; - fte->idx = feedercnt; - SLIST_INSERT_HEAD(&feedertab, fte, link); - feedercnt++; -} +static SLIST_HEAD(, feeder_class) feedertab = SLIST_HEAD_INITIALIZER(feedertab); void feeder_register(void *p) { struct feeder_class *fc = p; - struct feedertab_entry *fte; - int i; - KASSERT(fc->desc != NULL, ("feeder '%s' has no descriptor", fc->name)); - - /* - * beyond this point failure is non-fatal but may result in some - * translations being unavailable - */ - i = 0; - while ((feedercnt < MAXFEEDERS) && (fc->desc[i].type > 0)) { - fte = malloc(sizeof(*fte), M_FEEDER, M_WAITOK | M_ZERO); - fte->feederclass = fc; - fte->desc = &fc->desc[i]; - fte->idx = feedercnt; - fte->desc->idx = feedercnt; - SLIST_INSERT_HEAD(&feedertab, fte, link); - i++; - } - feedercnt++; - if (feedercnt >= MAXFEEDERS) { - printf("MAXFEEDERS (%d >= %d) exceeded\n", - feedercnt, MAXFEEDERS); - } + SLIST_INSERT_HEAD(&feedertab, fc, link); } static void -feeder_unregisterall(void *p) +feeder_unregisterall(void *p __unused) { - struct feedertab_entry *fte, *next; - - next = SLIST_FIRST(&feedertab); - while (next != NULL) { - fte = next; - next = SLIST_NEXT(fte, link); - free(fte, M_FEEDER); - } -} - -static int -cmpdesc(struct pcm_feederdesc *n, struct pcm_feederdesc *m) -{ - return ((n->type == m->type) && - ((n->in == 0) || (n->in == m->in)) && - ((n->out == 0) || (n->out == m->out)) && - (n->flags == m->flags)); + SLIST_INIT(&feedertab); } static void @@ -143,21 +74,10 @@ feeder_create(struct feeder_class *fc, struct pcm_feederdesc *desc) if (f == NULL) return NULL; - f->data = fc->data; - f->source = NULL; - f->parent = NULL; f->class = fc; f->desc = &(f->desc_static); - - if (desc) { + if (desc != NULL) *(f->desc) = *desc; - } else { - f->desc->type = FEEDER_ROOT; - f->desc->in = 0; - f->desc->out = 0; - f->desc->flags = 0; - f->desc->idx = 0; - } err = FEEDER_INIT(f); if (err) { @@ -171,17 +91,15 @@ feeder_create(struct feeder_class *fc, struct pcm_feederdesc *desc) } struct feeder_class * -feeder_getclass(struct pcm_feederdesc *desc) +feeder_getclass(u_int32_t type) { - struct feedertab_entry *fte; + struct feeder_class *fc; - SLIST_FOREACH(fte, &feedertab, link) { - if ((desc == NULL) && (fte->desc == NULL)) - return fte->feederclass; - if ((fte->desc != NULL) && (desc != NULL) && cmpdesc(desc, fte->desc)) - return fte->feederclass; + SLIST_FOREACH(fc, &feedertab, link) { + if (fc->type == type) + return (fc); } - return NULL; + return (NULL); } int @@ -221,7 +139,7 @@ feeder_find(struct pcm_channel *c, u_int32_t type) f = c->feeder; while (f != NULL) { - if (f->desc->type == type) + if (f->class->type == type) return f; f = f->source; } @@ -386,22 +304,6 @@ snd_fmtbest(u_int32_t fmt, u_int32_t *fmts) return best2; } -void -feeder_printchain(struct pcm_feeder *head) -{ - struct pcm_feeder *f; - - printf("feeder chain (head @%p)\n", head); - f = head; - while (f != NULL) { - printf("%s/%d @ %p\n", f->class->name, f->desc->idx, f); - f = f->source; - } - printf("[end]\n\n"); -} - -/*****************************************************************************/ - static int feed_root(struct pcm_feeder *feeder, struct pcm_channel *ch, u_int8_t *buffer, u_int32_t count, void *source) { @@ -433,9 +335,7 @@ feed_root(struct pcm_feeder *feeder, struct pcm_channel *ch, u_int8_t *buffer, u offset, count, l, ch->feedcount); if (ch->feedcount == 1) { - memset(buffer, - sndbuf_zerodata(sndbuf_getfmt(src)), - offset); + memset(buffer, sndbuf_zerodata(src->fmt), offset); if (l > 0) sndbuf_dispose(src, buffer + offset, l); else @@ -443,9 +343,7 @@ feed_root(struct pcm_feeder *feeder, struct pcm_channel *ch, u_int8_t *buffer, u } else { if (l > 0) sndbuf_dispose(src, buffer, l); - memset(buffer + l, - sndbuf_zerodata(sndbuf_getfmt(src)), - offset); + memset(buffer + l, sndbuf_zerodata(src->fmt), offset); if (!(ch->flags & CHN_F_CLOSING)) ch->xruns++; } @@ -463,13 +361,12 @@ static struct feeder_class feeder_root_class = { .name = "feeder_root", .methods = feeder_root_methods, .size = sizeof(struct pcm_feeder), - .desc = NULL, - .data = NULL, + .type = FEEDER_ROOT, }; /* * Register the root feeder first so that pcm_addchan() and subsequent * functions can use it. */ -SYSINIT(feeder_root, SI_SUB_DRIVERS, SI_ORDER_FIRST, feeder_register_root, +SYSINIT(feeder_root, SI_SUB_DRIVERS, SI_ORDER_FIRST, feeder_register, &feeder_root_class); SYSUNINIT(feeder_root, SI_SUB_DRIVERS, SI_ORDER_FIRST, feeder_unregisterall, NULL); diff --git a/sys/dev/sound/pcm/feeder.h b/sys/dev/sound/pcm/feeder.h index 60b8280e59ef..f1c96d86fda0 100644 --- a/sys/dev/sound/pcm/feeder.h +++ b/sys/dev/sound/pcm/feeder.h @@ -27,17 +27,25 @@ * SUCH DAMAGE. */ +enum feeder_type { + FEEDER_ROOT, + FEEDER_FORMAT, + FEEDER_MIXER, + FEEDER_RATE, + FEEDER_EQ, + FEEDER_VOLUME, + FEEDER_MATRIX, + FEEDER_LAST, +}; + struct pcm_feederdesc { - u_int32_t type; u_int32_t in, out; - u_int32_t flags; - int idx; }; struct feeder_class { KOBJ_CLASS_FIELDS; - struct pcm_feederdesc *desc; - void *data; + enum feeder_type type; + SLIST_ENTRY(feeder_class) link; }; struct pcm_feeder { @@ -51,7 +59,7 @@ struct pcm_feeder { }; void feeder_register(void *p); -struct feeder_class *feeder_getclass(struct pcm_feederdesc *desc); +struct feeder_class *feeder_getclass(u_int32_t type); u_int32_t snd_fmtscore(u_int32_t fmt); u_int32_t snd_fmtbestbit(u_int32_t fmt, u_int32_t *fmts); @@ -62,31 +70,18 @@ int feeder_add(struct pcm_channel *c, struct feeder_class *fc, struct pcm_feederdesc *desc); void feeder_remove(struct pcm_channel *c); struct pcm_feeder *feeder_find(struct pcm_channel *c, u_int32_t type); -void feeder_printchain(struct pcm_feeder *head); int feeder_chain(struct pcm_channel *); -#define FEEDER_DECLARE(feeder, pdata) \ +#define FEEDER_DECLARE(feeder, ctype) \ static struct feeder_class feeder ## _class = { \ .name = #feeder, \ .methods = feeder ## _methods, \ .size = sizeof(struct pcm_feeder), \ - .desc = feeder ## _desc, \ - .data = pdata, \ + .type = ctype, \ }; \ SYSINIT(feeder, SI_SUB_DRIVERS, SI_ORDER_ANY, feeder_register, \ &feeder ## _class) -enum { - FEEDER_ROOT, - FEEDER_FORMAT, - FEEDER_MIXER, - FEEDER_RATE, - FEEDER_EQ, - FEEDER_VOLUME, - FEEDER_MATRIX, - FEEDER_LAST, -}; - /* feeder_format */ enum { FEEDFORMAT_CHANNELS diff --git a/sys/dev/sound/pcm/feeder_chain.c b/sys/dev/sound/pcm/feeder_chain.c index 56de32441de7..32dd4ca14faf 100644 --- a/sys/dev/sound/pcm/feeder_chain.c +++ b/sys/dev/sound/pcm/feeder_chain.c @@ -144,12 +144,10 @@ feeder_build_format(struct pcm_channel *c, struct feeder_chain_desc *cdesc) int ret; desc = &(cdesc->desc); - desc->type = FEEDER_FORMAT; desc->in = 0; desc->out = 0; - desc->flags = 0; - fc = feeder_getclass(desc); + fc = feeder_getclass(FEEDER_FORMAT); if (fc == NULL) { device_printf(c->dev, "%s(): can't find feeder_format\n", __func__); @@ -217,12 +215,10 @@ feeder_build_rate(struct pcm_channel *c, struct feeder_chain_desc *cdesc) return (ret); desc = &(cdesc->desc); - desc->type = FEEDER_RATE; desc->in = 0; desc->out = 0; - desc->flags = 0; - fc = feeder_getclass(desc); + fc = feeder_getclass(FEEDER_RATE); if (fc == NULL) { device_printf(c->dev, "%s(): can't find feeder_rate\n", __func__); @@ -295,12 +291,10 @@ feeder_build_matrix(struct pcm_channel *c, struct feeder_chain_desc *cdesc) return (ret); desc = &(cdesc->desc); - desc->type = FEEDER_MATRIX; desc->in = 0; desc->out = 0; - desc->flags = 0; - fc = feeder_getclass(desc); + fc = feeder_getclass(FEEDER_MATRIX); if (fc == NULL) { device_printf(c->dev, "%s(): can't find feeder_matrix\n", __func__); @@ -352,12 +346,10 @@ feeder_build_volume(struct pcm_channel *c, struct feeder_chain_desc *cdesc) return (ret); desc = &(cdesc->desc); - desc->type = FEEDER_VOLUME; desc->in = 0; desc->out = 0; - desc->flags = 0; - fc = feeder_getclass(desc); + fc = feeder_getclass(FEEDER_VOLUME); if (fc == NULL) { device_printf(c->dev, "%s(): can't find feeder_volume\n", __func__); @@ -420,12 +412,10 @@ feeder_build_eq(struct pcm_channel *c, struct feeder_chain_desc *cdesc) return (ret); desc = &(cdesc->desc); - desc->type = FEEDER_EQ; desc->in = 0; desc->out = 0; - desc->flags = 0; - fc = feeder_getclass(desc); + fc = feeder_getclass(FEEDER_EQ); if (fc == NULL) { device_printf(c->dev, "%s(): can't find feeder_eq\n", __func__); @@ -467,7 +457,7 @@ feeder_build_root(struct pcm_channel *c, struct feeder_chain_desc *cdesc) struct feeder_class *fc; int ret; - fc = feeder_getclass(NULL); + fc = feeder_getclass(FEEDER_ROOT); if (fc == NULL) { device_printf(c->dev, "%s(): can't find feeder_root\n", __func__); @@ -500,12 +490,10 @@ feeder_build_mixer(struct pcm_channel *c, struct feeder_chain_desc *cdesc) int ret; desc = &(cdesc->desc); - desc->type = FEEDER_MIXER; desc->in = 0; desc->out = 0; - desc->flags = 0; - fc = feeder_getclass(desc); + fc = feeder_getclass(FEEDER_MIXER); if (fc == NULL) { device_printf(c->dev, "%s(): can't find feeder_mixer\n", __func__); @@ -695,11 +683,11 @@ feeder_chain(struct pcm_channel *c) cdesc.origin.rate = c->speed; cdesc.target.afmt = hwfmt; cdesc.target.matrix = hwmatrix; - cdesc.target.rate = sndbuf_getspd(c->bufhard); + cdesc.target.rate = c->bufhard->spd; } else { cdesc.origin.afmt = hwfmt; cdesc.origin.matrix = hwmatrix; - cdesc.origin.rate = sndbuf_getspd(c->bufhard); + cdesc.origin.rate = c->bufhard->spd; cdesc.target.afmt = softfmt; cdesc.target.matrix = softmatrix; cdesc.target.rate = c->speed; diff --git a/sys/dev/sound/pcm/feeder_eq.c b/sys/dev/sound/pcm/feeder_eq.c index 23e27b922486..3838328fb0bb 100644 --- a/sys/dev/sound/pcm/feeder_eq.c +++ b/sys/dev/sound/pcm/feeder_eq.c @@ -419,11 +419,6 @@ feed_eq_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b, return (dst - b); } -static struct pcm_feederdesc feeder_eq_desc[] = { - { FEEDER_EQ, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 } -}; - static kobj_method_t feeder_eq_methods[] = { KOBJMETHOD(feeder_init, feed_eq_init), KOBJMETHOD(feeder_free, feed_eq_free), @@ -432,7 +427,7 @@ static kobj_method_t feeder_eq_methods[] = { KOBJMETHOD_END }; -FEEDER_DECLARE(feeder_eq, NULL); +FEEDER_DECLARE(feeder_eq, FEEDER_EQ); static int32_t feed_eq_scan_preamp_arg(const char *s) diff --git a/sys/dev/sound/pcm/feeder_format.c b/sys/dev/sound/pcm/feeder_format.c index 0feac43374b8..d2c4d7618ab4 100644 --- a/sys/dev/sound/pcm/feeder_format.c +++ b/sys/dev/sound/pcm/feeder_format.c @@ -172,11 +172,6 @@ feed_format_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b, return (dst - b); } -static struct pcm_feederdesc feeder_format_desc[] = { - { FEEDER_FORMAT, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 } -}; - static kobj_method_t feeder_format_methods[] = { KOBJMETHOD(feeder_init, feed_format_init), KOBJMETHOD(feeder_free, feed_format_free), @@ -185,4 +180,4 @@ static kobj_method_t feeder_format_methods[] = { KOBJMETHOD_END }; -FEEDER_DECLARE(feeder_format, NULL); +FEEDER_DECLARE(feeder_format, FEEDER_FORMAT); diff --git a/sys/dev/sound/pcm/feeder_matrix.c b/sys/dev/sound/pcm/feeder_matrix.c index 43258a311d82..2c7a3e04690d 100644 --- a/sys/dev/sound/pcm/feeder_matrix.c +++ b/sys/dev/sound/pcm/feeder_matrix.c @@ -398,11 +398,6 @@ feed_matrix_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b, return (dst - b); } -static struct pcm_feederdesc feeder_matrix_desc[] = { - { FEEDER_MATRIX, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 } -}; - static kobj_method_t feeder_matrix_methods[] = { KOBJMETHOD(feeder_init, feed_matrix_init), KOBJMETHOD(feeder_free, feed_matrix_free), @@ -410,7 +405,7 @@ static kobj_method_t feeder_matrix_methods[] = { KOBJMETHOD_END }; -FEEDER_DECLARE(feeder_matrix, NULL); +FEEDER_DECLARE(feeder_matrix, FEEDER_MATRIX); /* External */ int @@ -418,7 +413,7 @@ feeder_matrix_setup(struct pcm_feeder *f, struct pcmchan_matrix *m_in, struct pcmchan_matrix *m_out) { - if (f == NULL || f->desc == NULL || f->desc->type != FEEDER_MATRIX || + if (f == NULL || f->desc == NULL || f->class->type != FEEDER_MATRIX || f->data == NULL) return (EINVAL); diff --git a/sys/dev/sound/pcm/feeder_mixer.c b/sys/dev/sound/pcm/feeder_mixer.c index b6b81ad9a51c..10de42ba727a 100644 --- a/sys/dev/sound/pcm/feeder_mixer.c +++ b/sys/dev/sound/pcm/feeder_mixer.c @@ -145,8 +145,8 @@ feed_mixer_rec(struct pcm_channel *c) b = c->bufsoft; b->rp = 0; b->rl = 0; - cnt = sndbuf_getsize(b); - maxfeed = SND_FXROUND(SND_FXDIV_MAX, sndbuf_getalign(b)); + cnt = b->bufsize; + maxfeed = SND_FXROUND(SND_FXDIV_MAX, b->align); do { cnt = FEEDER_FEED(c->feeder->source, c, b->tmpbuf, @@ -158,7 +158,7 @@ feed_mixer_rec(struct pcm_channel *c) } while (cnt != 0); /* Not enough data */ - if (b->rl < sndbuf_getalign(b)) { + if (b->rl < b->align) { b->rl = 0; return (0); } @@ -187,11 +187,11 @@ feed_mixer_rec(struct pcm_channel *c) if (ch->flags & CHN_F_MMAP) sndbuf_dispose(bs, NULL, sndbuf_getready(bs)); cnt = sndbuf_getfree(bs); - if (cnt < sndbuf_getalign(bs)) { + if (cnt < bs->align) { CHN_UNLOCK(ch); continue; } - maxfeed = SND_FXROUND(SND_FXDIV_MAX, sndbuf_getalign(bs)); + maxfeed = SND_FXROUND(SND_FXDIV_MAX, bs->align); do { cnt = FEEDER_FEED(ch->feeder, ch, bs->tmpbuf, min(cnt, maxfeed), b); @@ -244,7 +244,7 @@ feed_mixer_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b, if (c->direction == PCMDIR_REC) return (feed_mixer_rec(c)); - sz = sndbuf_getsize(src); + sz = src->bufsize; if (sz < count) count = sz; @@ -260,7 +260,7 @@ feed_mixer_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b, * list of children and calling mixer function to mix count bytes from * each into our destination buffer, b. */ - tmp = sndbuf_getbuf(src); + tmp = src->buf; rcnt = 0; mcnt = 0; passthrough = 0; /* 'passthrough' / 'exclusive' marker */ @@ -358,11 +358,6 @@ feed_mixer_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b, return (rcnt); } -static struct pcm_feederdesc feeder_mixer_desc[] = { - { FEEDER_MIXER, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 } -}; - static kobj_method_t feeder_mixer_methods[] = { KOBJMETHOD(feeder_init, feed_mixer_init), KOBJMETHOD(feeder_free, feed_mixer_free), @@ -371,4 +366,4 @@ static kobj_method_t feeder_mixer_methods[] = { KOBJMETHOD_END }; -FEEDER_DECLARE(feeder_mixer, NULL); +FEEDER_DECLARE(feeder_mixer, FEEDER_MIXER); diff --git a/sys/dev/sound/pcm/feeder_rate.c b/sys/dev/sound/pcm/feeder_rate.c index 9c29142b9d6b..c2c232a97177 100644 --- a/sys/dev/sound/pcm/feeder_rate.c +++ b/sys/dev/sound/pcm/feeder_rate.c @@ -1705,11 +1705,6 @@ z_resampler_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b, return (count - left); } -static struct pcm_feederdesc feeder_rate_desc[] = { - { FEEDER_RATE, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, -}; - static kobj_method_t feeder_rate_methods[] = { KOBJMETHOD(feeder_init, z_resampler_init), KOBJMETHOD(feeder_free, z_resampler_free), @@ -1719,4 +1714,4 @@ static kobj_method_t feeder_rate_methods[] = { KOBJMETHOD_END }; -FEEDER_DECLARE(feeder_rate, NULL); +FEEDER_DECLARE(feeder_rate, FEEDER_RATE); diff --git a/sys/dev/sound/pcm/feeder_volume.c b/sys/dev/sound/pcm/feeder_volume.c index ddcbf29804f3..101cc7ba003b 100644 --- a/sys/dev/sound/pcm/feeder_volume.c +++ b/sys/dev/sound/pcm/feeder_volume.c @@ -306,11 +306,6 @@ feed_volume_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b, return (dst - b); } -static struct pcm_feederdesc feeder_volume_desc[] = { - { FEEDER_VOLUME, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 } -}; - static kobj_method_t feeder_volume_methods[] = { KOBJMETHOD(feeder_init, feed_volume_init), KOBJMETHOD(feeder_free, feed_volume_free), @@ -319,7 +314,7 @@ static kobj_method_t feeder_volume_methods[] = { KOBJMETHOD_END }; -FEEDER_DECLARE(feeder_volume, NULL); +FEEDER_DECLARE(feeder_volume, FEEDER_VOLUME); /* Extern */ @@ -337,7 +332,7 @@ feeder_volume_apply_matrix(struct pcm_feeder *f, struct pcmchan_matrix *m) struct feed_volume_info *info; uint32_t i; - if (f == NULL || f->desc == NULL || f->desc->type != FEEDER_VOLUME || + if (f == NULL || f->desc == NULL || f->class->type != FEEDER_VOLUME || f->data == NULL || m == NULL || m->channels < SND_CHN_MIN || m->channels > SND_CHN_MAX) return (EINVAL); diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c index f281dff36248..55ce9596dde9 100644 --- a/sys/dev/sound/pcm/mixer.c +++ b/sys/dev/sound/pcm/mixer.c @@ -63,13 +63,8 @@ struct snd_mixer { u_int32_t child[32]; u_int8_t realdev[32]; char name[MIXER_NAMELEN]; - struct mtx *lock; + struct mtx lock; oss_mixer_enuminfo enuminfo; - /** - * Counter is incremented when applications change any of this - * mixer's controls. A change in value indicates that persistent - * mixer applications should update their displays. - */ int modify_counter; }; @@ -131,12 +126,12 @@ mixer_lookup(char *devname) #define MIXER_SET_UNLOCK(x, y) do { \ if ((y) != 0) \ - snd_mtxunlock((x)->lock); \ + mtx_unlock(&(x)->lock); \ } while (0) #define MIXER_SET_LOCK(x, y) do { \ if ((y) != 0) \ - snd_mtxlock((x)->lock); \ + mtx_lock(&(x)->lock); \ } while (0) static int @@ -149,12 +144,12 @@ mixer_set_softpcmvol(struct snd_mixer *m, struct snddev_info *d, if (!PCM_REGISTERED(d)) return (EINVAL); - if (mtx_owned(m->lock)) + if (mtx_owned(&m->lock)) dropmtx = 1; else dropmtx = 0; - if (!(d->flags & SD_F_MPSAFE) || mtx_owned(d->lock) != 0) + if (!(d->flags & SD_F_MPSAFE) || mtx_owned(&d->lock) != 0) acquiremtx = 0; else acquiremtx = 1; @@ -202,12 +197,12 @@ mixer_set_eq(struct snd_mixer *m, struct snddev_info *d, if (!PCM_REGISTERED(d)) return (EINVAL); - if (mtx_owned(m->lock)) + if (mtx_owned(&m->lock)) dropmtx = 1; else dropmtx = 0; - if (!(d->flags & SD_F_MPSAFE) || mtx_owned(d->lock) != 0) + if (!(d->flags & SD_F_MPSAFE) || mtx_owned(&d->lock) != 0) acquiremtx = 0; else acquiremtx = 1; @@ -258,7 +253,7 @@ mixer_set(struct snd_mixer *m, u_int dev, u_int32_t muted, u_int lev) return (-1); /* It is safe to drop this mutex due to Giant. */ - if (!(d->flags & SD_F_MPSAFE) && mtx_owned(m->lock) != 0) + if (!(d->flags & SD_F_MPSAFE) && mtx_owned(&m->lock) != 0) dropmtx = 1; else dropmtx = 0; @@ -372,7 +367,7 @@ mixer_setrecsrc(struct snd_mixer *mixer, u_int32_t src) d = device_get_softc(mixer->dev); if (d == NULL) return -1; - if (!(d->flags & SD_F_MPSAFE) && mtx_owned(mixer->lock) != 0) + if (!(d->flags & SD_F_MPSAFE) && mtx_owned(&mixer->lock) != 0) dropmtx = 1; else dropmtx = 0; @@ -609,14 +604,6 @@ mix_getparent(struct snd_mixer *m, u_int32_t dev) } u_int32_t -mix_getchild(struct snd_mixer *m, u_int32_t dev) -{ - if (m == NULL || dev >= SOUND_MIXER_NRDEVICES) - return 0; - return m->child[dev]; -} - -u_int32_t mix_getdevs(struct snd_mixer *m) { return m->devs; @@ -660,8 +647,8 @@ mixer_obj_create(device_t dev, kobj_class_t cls, void *devinfo, strlcat(m->name, ":", sizeof(m->name)); strlcat(m->name, desc, sizeof(m->name)); } - m->lock = snd_mtxcreate(m->name, (type == MIXER_TYPE_PRIMARY) ? - "primary pcm mixer" : "secondary pcm mixer"); + mtx_init(&m->lock, m->name, (type == MIXER_TYPE_PRIMARY) ? + "primary pcm mixer" : "secondary pcm mixer", MTX_DEF); m->type = type; m->devinfo = devinfo; m->busy = 0; @@ -673,8 +660,8 @@ mixer_obj_create(device_t dev, kobj_class_t cls, void *devinfo, } if (MIXER_INIT(m)) { - snd_mtxlock(m->lock); - snd_mtxfree(m->lock); + mtx_lock(&m->lock); + mtx_destroy(&m->lock); kobj_delete((kobj_t)m, M_MIXER); return (NULL); } @@ -693,7 +680,7 @@ mixer_delete(struct snd_mixer *m) MIXER_UNINIT(m); - snd_mtxfree(m->lock); + mtx_destroy(&m->lock); kobj_delete((kobj_t)m, M_MIXER); return (0); @@ -805,20 +792,20 @@ mixer_uninit(device_t dev) pdev->si_drv1 = NULL; destroy_dev(pdev); - snd_mtxlock(m->lock); + mtx_lock(&m->lock); for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) mixer_set(m, i, 0, 0); mixer_setrecsrc(m, SOUND_MASK_MIC); - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); /* mixer uninit can sleep --hps */ MIXER_UNINIT(m); - snd_mtxfree(m->lock); + mtx_destroy(&m->lock); kobj_delete((kobj_t)m, M_MIXER); d->mixer_dev = NULL; @@ -835,11 +822,11 @@ mixer_reinit(device_t dev) pdev = mixer_get_devt(dev); m = pdev->si_drv1; - snd_mtxlock(m->lock); + mtx_lock(&m->lock); i = MIXER_REINIT(m); if (i) { - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return i; } @@ -851,7 +838,7 @@ mixer_reinit(device_t dev) } mixer_setrecsrc(m, m->recsrc); - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return 0; } @@ -864,21 +851,21 @@ sysctl_hw_snd_hwvol_mixer(SYSCTL_HANDLER_ARGS) struct snd_mixer *m; m = oidp->oid_arg1; - snd_mtxlock(m->lock); + mtx_lock(&m->lock); strlcpy(devname, snd_mixernames[m->hwvol_mixer], sizeof(devname)); - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); error = sysctl_handle_string(oidp, &devname[0], sizeof(devname), req); - snd_mtxlock(m->lock); + mtx_lock(&m->lock); if (error == 0 && req->newptr != NULL) { dev = mixer_lookup(devname); if (dev == -1) { - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return EINVAL; } else { m->hwvol_mixer = dev; } } - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return error; } @@ -917,9 +904,9 @@ mixer_hwvol_mute(device_t dev) pdev = mixer_get_devt(dev); m = pdev->si_drv1; - snd_mtxlock(m->lock); + mtx_lock(&m->lock); mixer_hwvol_mute_locked(m); - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); } void @@ -955,9 +942,9 @@ mixer_hwvol_step(device_t dev, int left_step, int right_step) pdev = mixer_get_devt(dev); m = pdev->si_drv1; - snd_mtxlock(m->lock); + mtx_lock(&m->lock); mixer_hwvol_step_locked(m, left_step, right_step); - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); } int @@ -975,9 +962,9 @@ mix_set(struct snd_mixer *m, u_int dev, u_int left, u_int right) KASSERT(m != NULL, ("NULL snd_mixer")); - snd_mtxlock(m->lock); + mtx_lock(&m->lock); ret = mixer_set(m, dev, m->mutedevs, left | (right << 8)); - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return ((ret != 0) ? ENXIO : 0); } @@ -989,9 +976,9 @@ mix_get(struct snd_mixer *m, u_int dev) KASSERT(m != NULL, ("NULL snd_mixer")); - snd_mtxlock(m->lock); + mtx_lock(&m->lock); ret = mixer_get(m, dev); - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return (ret); } @@ -1003,9 +990,9 @@ mix_setrecsrc(struct snd_mixer *m, u_int32_t src) KASSERT(m != NULL, ("NULL snd_mixer")); - snd_mtxlock(m->lock); + mtx_lock(&m->lock); ret = mixer_setrecsrc(m, src); - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return ((ret != 0) ? ENXIO : 0); } @@ -1017,21 +1004,13 @@ mix_getrecsrc(struct snd_mixer *m) KASSERT(m != NULL, ("NULL snd_mixer")); - snd_mtxlock(m->lock); + mtx_lock(&m->lock); ret = mixer_getrecsrc(m); - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return (ret); } -int -mix_get_type(struct snd_mixer *m) -{ - KASSERT(m != NULL, ("NULL snd_mixer")); - - return (m->type); -} - device_t mix_get_dev(struct snd_mixer *m) { @@ -1058,9 +1037,9 @@ mixer_open(struct cdev *i_dev, int flags, int mode, struct thread *td) /* XXX Need Giant magic entry ??? */ - snd_mtxlock(m->lock); + mtx_lock(&m->lock); m->busy = 1; - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return (0); } @@ -1082,10 +1061,10 @@ mixer_close(struct cdev *i_dev, int flags, int mode, struct thread *td) /* XXX Need Giant magic entry ??? */ - snd_mtxlock(m->lock); + mtx_lock(&m->lock); ret = (m->busy == 0) ? EBADF : 0; m->busy = 0; - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return (ret); } @@ -1163,9 +1142,9 @@ mixer_ioctl_channel(struct cdev *dev, u_long cmd, caddr_t arg, int mode, if ((j == SOUND_MIXER_DEVMASK || j == SOUND_MIXER_CAPS || j == SOUND_MIXER_STEREODEVS) && (cmd & ~0xff) == MIXER_READ(0)) { - snd_mtxlock(m->lock); + mtx_lock(&m->lock); *(int *)arg = mix_getdevs(m); - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); if (rdch != NULL) *(int *)arg |= SOUND_MASK_RECLEV; if (wrch != NULL) @@ -1282,9 +1261,9 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, if (m == NULL) return (EBADF); - snd_mtxlock(m->lock); + mtx_lock(&m->lock); if (from == MIXER_CMD_CDEV && !m->busy) { - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return (EBADF); } switch (cmd) { @@ -1320,7 +1299,7 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, ret = mixer_set(m, j, m->mutedevs, *arg_i); break; } - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return ((ret == 0) ? 0 : ENXIO); } if ((cmd & ~0xff) == MIXER_READ(0)) { @@ -1344,11 +1323,11 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, break; } *arg_i = v; - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return ((v != -1) ? 0 : ENXIO); } done: - snd_mtxunlock(m->lock); + mtx_unlock(&m->lock); return (ret); } @@ -1477,7 +1456,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi) } m = d->mixer_dev->si_drv1; - mtx_lock(m->lock); + mtx_lock(&m->lock); /* * At this point, the following synchronization stuff @@ -1490,6 +1469,11 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi) mi->dev = i; snprintf(mi->id, sizeof(mi->id), "mixer%d", i); strlcpy(mi->name, m->name, sizeof(mi->name)); + /** + * Counter is incremented when applications change any of this + * mixer's controls. A change in value indicates that + * persistent mixer applications should update their displays. + */ mi->modify_counter = m->modify_counter; mi->card_number = i; /* @@ -1549,7 +1533,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi) snprintf(mi->devnode, sizeof(mi->devnode), "/dev/mixer%d", i); mi->legacy_device = i; - mtx_unlock(m->lock); + mtx_unlock(&m->lock); PCM_UNLOCK(d); @@ -1568,35 +1552,5 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi) struct mtx * mixer_get_lock(struct snd_mixer *m) { - if (m->lock == NULL) { - return (&Giant); - } - return (m->lock); -} - -int -mix_get_locked(struct snd_mixer *m, u_int dev, int *pleft, int *pright) -{ - int level; - - level = mixer_get(m, dev); - if (level < 0) { - *pright = *pleft = -1; - return (-1); - } - - *pleft = level & 0xFF; - *pright = (level >> 8) & 0xFF; - - return (0); -} - -int -mix_set_locked(struct snd_mixer *m, u_int dev, int left, int right) -{ - int level; - - level = (left & 0xFF) | ((right & 0xFF) << 8); - - return (mixer_set(m, dev, m->mutedevs, level)); + return (&m->lock); } diff --git a/sys/dev/sound/pcm/mixer.h b/sys/dev/sound/pcm/mixer.h index 7139a766b392..c47247ab570d 100644 --- a/sys/dev/sound/pcm/mixer.h +++ b/sys/dev/sound/pcm/mixer.h @@ -47,13 +47,10 @@ void mixer_hwvol_step(device_t dev, int left_step, int right_step); int mixer_busy(struct snd_mixer *m); -int mix_get_locked(struct snd_mixer *m, u_int dev, int *pleft, int *pright); -int mix_set_locked(struct snd_mixer *m, u_int dev, int left, int right); int mix_set(struct snd_mixer *m, u_int dev, u_int left, u_int right); int mix_get(struct snd_mixer *m, u_int dev); int mix_setrecsrc(struct snd_mixer *m, u_int32_t src); u_int32_t mix_getrecsrc(struct snd_mixer *m); -int mix_get_type(struct snd_mixer *m); device_t mix_get_dev(struct snd_mixer *m); void mix_setdevs(struct snd_mixer *m, u_int32_t v); @@ -65,7 +62,6 @@ u_int32_t mix_getmutedevs(struct snd_mixer *m); void mix_setparentchild(struct snd_mixer *m, u_int32_t parent, u_int32_t childs); void mix_setrealdev(struct snd_mixer *m, u_int32_t dev, u_int32_t realdev); u_int32_t mix_getparent(struct snd_mixer *m, u_int32_t dev); -u_int32_t mix_getchild(struct snd_mixer *m, u_int32_t dev); void *mix_getdevinfo(struct snd_mixer *m); struct mtx *mixer_get_lock(struct snd_mixer *m); diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c index 51d0fb3bb686..a7c53ac85eb8 100644 --- a/sys/dev/sound/pcm/sndstat.c +++ b/sys/dev/sound/pcm/sndstat.c @@ -491,29 +491,29 @@ sndstat_build_sound4_nvlist(struct snddev_info *d, nvlist_t **dip) nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_RIGHTVOL, CHN_GETVOLUME(c, SND_VOL_C_PCM, SND_CHN_T_FR)); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_FORMAT, - sndbuf_getfmt(c->bufhard)); + c->bufhard->fmt); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_RATE, - sndbuf_getspd(c->bufhard)); + c->bufhard->spd); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_SIZE, - sndbuf_getsize(c->bufhard)); + c->bufhard->bufsize); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_BLKSZ, - sndbuf_getblksz(c->bufhard)); + c->bufhard->blksz); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_BLKCNT, - sndbuf_getblkcnt(c->bufhard)); + c->bufhard->blkcnt); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_FREE, sndbuf_getfree(c->bufhard)); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_READY, sndbuf_getready(c->bufhard)); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_FORMAT, - sndbuf_getfmt(c->bufsoft)); + c->bufsoft->fmt); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_RATE, - sndbuf_getspd(c->bufsoft)); + c->bufsoft->spd); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_SIZE, - sndbuf_getsize(c->bufsoft)); + c->bufsoft->bufsize); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_BLKSZ, - sndbuf_getblksz(c->bufsoft)); + c->bufsoft->blksz); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_BLKCNT, - sndbuf_getblkcnt(c->bufsoft)); + c->bufsoft->blkcnt); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_FREE, sndbuf_getfree(c->bufsoft)); nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_READY, @@ -524,7 +524,8 @@ sndstat_build_sound4_nvlist(struct snddev_info *d, nvlist_t **dip) c->parentchannel->name : "userland"); } else { sbuf_printf(&sb, "[%s", (c->direction == PCMDIR_REC) ? - "hardware" : "userland"); + "hardware" : + ((d->flags & SD_F_PVCHANS) ? "vchans" : "userland")); } sbuf_printf(&sb, " -> "); f = c->feeder; @@ -532,12 +533,12 @@ sndstat_build_sound4_nvlist(struct snddev_info *d, nvlist_t **dip) f = f->source; while (f != NULL) { sbuf_printf(&sb, "%s", f->class->name); - if (f->desc->type == FEEDER_FORMAT) { + if (f->class->type == FEEDER_FORMAT) { snd_afmt2str(f->desc->in, buf, sizeof(buf)); sbuf_printf(&sb, "(%s -> ", buf); snd_afmt2str(f->desc->out, buf, sizeof(buf)); sbuf_printf(&sb, "%s)", buf); - } else if (f->desc->type == FEEDER_MATRIX) { + } else if (f->class->type == FEEDER_MATRIX) { sbuf_printf(&sb, "(%d.%dch -> %d.%dch)", AFMT_CHANNEL(f->desc->in) - AFMT_EXTCHANNEL(f->desc->in), @@ -545,7 +546,7 @@ sndstat_build_sound4_nvlist(struct snddev_info *d, nvlist_t **dip) AFMT_CHANNEL(f->desc->out) - AFMT_EXTCHANNEL(f->desc->out), AFMT_EXTCHANNEL(f->desc->out)); - } else if (f->desc->type == FEEDER_RATE) { + } else if (f->class->type == FEEDER_RATE) { sbuf_printf(&sb, "(%d -> %d)", FEEDER_GET(f, FEEDRATE_SRC), FEEDER_GET(f, FEEDRATE_DST)); @@ -561,7 +562,8 @@ sndstat_build_sound4_nvlist(struct snddev_info *d, nvlist_t **dip) "userland" : c->parentchannel->name); } else { sbuf_printf(&sb, "%s]", (c->direction == PCMDIR_REC) ? - "userland" : "hardware"); + ((d->flags & SD_F_RVCHANS) ? "vchans" : "userland") : + "hardware"); } CHN_UNLOCK(c); @@ -1265,14 +1267,11 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose) (c->parentchannel != NULL) ? c->parentchannel->name : "", c->name); sbuf_printf(s, "spd %d", c->speed); - if (c->speed != sndbuf_getspd(c->bufhard)) { - sbuf_printf(s, "/%d", - sndbuf_getspd(c->bufhard)); - } + if (c->speed != c->bufhard->spd) + sbuf_printf(s, "/%d", c->bufhard->spd); sbuf_printf(s, ", fmt 0x%08x", c->format); - if (c->format != sndbuf_getfmt(c->bufhard)) { - sbuf_printf(s, "/0x%08x", - sndbuf_getfmt(c->bufhard)); + if (c->format != c->bufhard->fmt) { + sbuf_printf(s, "/0x%08x", c->bufhard->fmt); } sbuf_printf(s, ", flags 0x%08x, 0x%08x", c->flags, c->feederflags); @@ -1291,24 +1290,24 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose) c->xruns, c->feedcount, sndbuf_getfree(c->bufhard), sndbuf_getfree(c->bufsoft), - sndbuf_getsize(c->bufhard), - sndbuf_getblksz(c->bufhard), - sndbuf_getblkcnt(c->bufhard), - sndbuf_getsize(c->bufsoft), - sndbuf_getblksz(c->bufsoft), - sndbuf_getblkcnt(c->bufsoft)); + c->bufhard->bufsize, + c->bufhard->blksz, + c->bufhard->blkcnt, + c->bufsoft->bufsize, + c->bufsoft->blksz, + c->bufsoft->blkcnt); } else { sbuf_printf(s, "underruns %d, feed %u, ready %d " "\n\t\t[b:%d/%d/%d|bs:%d/%d/%d]", c->xruns, c->feedcount, sndbuf_getready(c->bufsoft), - sndbuf_getsize(c->bufhard), - sndbuf_getblksz(c->bufhard), - sndbuf_getblkcnt(c->bufhard), - sndbuf_getsize(c->bufsoft), - sndbuf_getblksz(c->bufsoft), - sndbuf_getblkcnt(c->bufsoft)); + c->bufhard->bufsize, + c->bufhard->blksz, + c->bufhard->blkcnt, + c->bufsoft->bufsize, + c->bufsoft->blksz, + c->bufsoft->blkcnt); } sbuf_printf(s, "\n\t"); @@ -1320,7 +1319,8 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose) c->parentchannel->name : "userland"); } else { sbuf_printf(s, "\t{%s}", (c->direction == PCMDIR_REC) ? - "hardware" : "userland"); + "hardware" : + ((d->flags & SD_F_PVCHANS) ? "vchans" : "userland")); } sbuf_printf(s, " -> "); f = c->feeder; @@ -1328,10 +1328,10 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose) f = f->source; while (f != NULL) { sbuf_printf(s, "%s", f->class->name); - if (f->desc->type == FEEDER_FORMAT) { + if (f->class->type == FEEDER_FORMAT) { sbuf_printf(s, "(0x%08x -> 0x%08x)", f->desc->in, f->desc->out); - } else if (f->desc->type == FEEDER_MATRIX) { + } else if (f->class->type == FEEDER_MATRIX) { sbuf_printf(s, "(%d.%d -> %d.%d)", AFMT_CHANNEL(f->desc->in) - AFMT_EXTCHANNEL(f->desc->in), @@ -1339,7 +1339,7 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose) AFMT_CHANNEL(f->desc->out) - AFMT_EXTCHANNEL(f->desc->out), AFMT_EXTCHANNEL(f->desc->out)); - } else if (f->desc->type == FEEDER_RATE) { + } else if (f->class->type == FEEDER_RATE) { sbuf_printf(s, "(0x%08x q:%d %d -> %d)", f->desc->out, @@ -1358,7 +1358,8 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose) "userland" : c->parentchannel->name); } else { sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC) ? - "userland" : "hardware"); + ((d->flags & SD_F_RVCHANS) ? "vchans" : "userland") : + "hardware"); } CHN_UNLOCK(c); diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index cb510d526fa8..29dac6b576ae 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -62,35 +62,6 @@ SYSCTL_NODE(_hw, OID_AUTO, snd, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, */ struct unrhdr *pcmsg_unrhdr = NULL; -void * -snd_mtxcreate(const char *desc, const char *type) -{ - struct mtx *m; - - m = malloc(sizeof(*m), M_DEVBUF, M_WAITOK | M_ZERO); - mtx_init(m, desc, type, MTX_DEF); - return m; -} - -void -snd_mtxfree(void *m) -{ - struct mtx *mtx = m; - - mtx_destroy(mtx); - free(mtx, M_DEVBUF); -} - -void -snd_mtxassert(void *m) -{ -#ifdef INVARIANTS - struct mtx *mtx = m; - - mtx_assert(mtx, MA_OWNED); -#endif -} - int snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand, void *param, void **cookiep) { @@ -361,7 +332,7 @@ pcm_init(device_t dev, void *devinfo) d = device_get_softc(dev); d->dev = dev; - d->lock = snd_mtxcreate(device_get_nameunit(dev), "sound cdev"); + mtx_init(&d->lock, device_get_nameunit(dev), "sound cdev", MTX_DEF); cv_init(&d->cv, device_get_nameunit(dev)); i = 0; @@ -467,7 +438,7 @@ pcm_unregister(device_t dev) d = device_get_softc(dev); - if (!PCM_ALIVE(d)) { + if (!PCM_REGISTERED(d)) { device_printf(dev, "unregister: device not configured\n"); return (0); } @@ -498,7 +469,7 @@ pcm_unregister(device_t dev) dsp_destroy_dev(dev); cv_destroy(&d->cv); - snd_mtxfree(d->lock); + mtx_destroy(&d->lock); if (snd_unit == device_get_unit(dev)) { snd_unit = pcm_best_unit(-1); diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h index 6bd435d0ea25..3ba6eb3692ee 100644 --- a/sys/dev/sound/pcm/sound.h +++ b/sys/dev/sound/pcm/sound.h @@ -76,10 +76,6 @@ #include <sys/mutex.h> #include <sys/condvar.h> -#ifndef KOBJMETHOD_END -#define KOBJMETHOD_END { NULL, NULL } -#endif - struct pcm_channel; struct pcm_feeder; struct snd_dbuf; @@ -137,8 +133,8 @@ struct snd_mixer; "\015PVCHANS" \ "\016RVCHANS" -#define PCM_ALIVE(x) ((x) != NULL && (x)->lock != NULL) -#define PCM_REGISTERED(x) (PCM_ALIVE(x) && ((x)->flags & SD_F_REGISTERED)) +#define PCM_REGISTERED(x) \ + ((x) != NULL && ((x)->flags & SD_F_REGISTERED)) #define PCM_MAXCHANS 10000 #define PCM_CHANCOUNT(d) \ @@ -148,8 +144,6 @@ struct snd_mixer; #define RANGE(var, low, high) (var) = \ (((var)<(low))? (low) : ((var)>(high))? (high) : (var)) -#define DSP_DEFAULT_SPEED 8000 - extern int snd_unit; extern int snd_verbose; extern devclass_t pcm_devclass; @@ -173,12 +167,6 @@ void *pcm_getdevinfo(device_t dev); int snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand, void *param, void **cookiep); -void *snd_mtxcreate(const char *desc, const char *type); -void snd_mtxfree(void *m); -void snd_mtxassert(void *m); -#define snd_mtxlock(m) mtx_lock(m) -#define snd_mtxunlock(m) mtx_unlock(m) - int sndstat_register(device_t dev, char *str); int sndstat_unregister(device_t dev); @@ -186,7 +174,6 @@ int sndstat_unregister(device_t dev); enum { SCF_PCM, SCF_MIDI, - SCF_SYNTH, }; /* @@ -225,7 +212,7 @@ struct snddev_info { void *devinfo; device_t dev; char status[SND_STATUSLEN]; - struct mtx *lock; + struct mtx lock; struct cdev *mixer_dev; struct cdev *dsp_dev; uint32_t pvchanrate, pvchanformat, pvchanmode; @@ -247,123 +234,21 @@ int sound_oss_card_info(oss_card_info *); #define PCM_MODE_PLAY 0x02 #define PCM_MODE_REC 0x04 -#define PCM_LOCKOWNED(d) mtx_owned((d)->lock) -#define PCM_LOCK(d) mtx_lock((d)->lock) -#define PCM_UNLOCK(d) mtx_unlock((d)->lock) -#define PCM_TRYLOCK(d) mtx_trylock((d)->lock) -#define PCM_LOCKASSERT(d) mtx_assert((d)->lock, MA_OWNED) -#define PCM_UNLOCKASSERT(d) mtx_assert((d)->lock, MA_NOTOWNED) +#define PCM_LOCKOWNED(d) mtx_owned(&(d)->lock) +#define PCM_LOCK(d) mtx_lock(&(d)->lock) +#define PCM_UNLOCK(d) mtx_unlock(&(d)->lock) +#define PCM_TRYLOCK(d) mtx_trylock(&(d)->lock) +#define PCM_LOCKASSERT(d) mtx_assert(&(d)->lock, MA_OWNED) +#define PCM_UNLOCKASSERT(d) mtx_assert(&(d)->lock, MA_NOTOWNED) /* * For PCM_[WAIT | ACQUIRE | RELEASE], be sure to surround these * with PCM_LOCK/UNLOCK() sequence, or I'll come to gnaw upon you! */ -#ifdef SND_DIAGNOSTIC -#define PCM_WAIT(x) do { \ - if (!PCM_LOCKOWNED(x)) \ - panic("%s(%d): [PCM WAIT] Mutex not owned!", \ - __func__, __LINE__); \ - while ((x)->flags & SD_F_BUSY) { \ - if (snd_verbose > 3) \ - device_printf((x)->dev, \ - "%s(%d): [PCM WAIT] calling cv_wait().\n", \ - __func__, __LINE__); \ - cv_wait(&(x)->cv, (x)->lock); \ - } \ -} while (0) - -#define PCM_ACQUIRE(x) do { \ - if (!PCM_LOCKOWNED(x)) \ - panic("%s(%d): [PCM ACQUIRE] Mutex not owned!", \ - __func__, __LINE__); \ - if ((x)->flags & SD_F_BUSY) \ - panic("%s(%d): [PCM ACQUIRE] " \ - "Trying to acquire BUSY cv!", __func__, __LINE__); \ - (x)->flags |= SD_F_BUSY; \ -} while (0) - -#define PCM_RELEASE(x) do { \ - if (!PCM_LOCKOWNED(x)) \ - panic("%s(%d): [PCM RELEASE] Mutex not owned!", \ - __func__, __LINE__); \ - if ((x)->flags & SD_F_BUSY) { \ - (x)->flags &= ~SD_F_BUSY; \ - cv_broadcast(&(x)->cv); \ - } else \ - panic("%s(%d): [PCM RELEASE] Releasing non-BUSY cv!", \ - __func__, __LINE__); \ -} while (0) - -/* Quick version, for shorter path. */ -#define PCM_ACQUIRE_QUICK(x) do { \ - if (PCM_LOCKOWNED(x)) \ - panic("%s(%d): [PCM ACQUIRE QUICK] Mutex owned!", \ - __func__, __LINE__); \ - PCM_LOCK(x); \ - PCM_WAIT(x); \ - PCM_ACQUIRE(x); \ - PCM_UNLOCK(x); \ -} while (0) - -#define PCM_RELEASE_QUICK(x) do { \ - if (PCM_LOCKOWNED(x)) \ - panic("%s(%d): [PCM RELEASE QUICK] Mutex owned!", \ - __func__, __LINE__); \ - PCM_LOCK(x); \ - PCM_RELEASE(x); \ - PCM_UNLOCK(x); \ -} while (0) - -#define PCM_BUSYASSERT(x) do { \ - if (!((x) != NULL && ((x)->flags & SD_F_BUSY))) \ - panic("%s(%d): [PCM BUSYASSERT] " \ - "Failed, snddev_info=%p", __func__, __LINE__, x); \ -} while (0) - -#define PCM_GIANT_ENTER(x) do { \ - int _pcm_giant = 0; \ - if (PCM_LOCKOWNED(x)) \ - panic("%s(%d): [GIANT ENTER] PCM lock owned!", \ - __func__, __LINE__); \ - if (mtx_owned(&Giant) != 0 && snd_verbose > 3) \ - device_printf((x)->dev, \ - "%s(%d): [GIANT ENTER] Giant owned!\n", \ - __func__, __LINE__); \ - if (!((x)->flags & SD_F_MPSAFE) && mtx_owned(&Giant) == 0) \ - do { \ - mtx_lock(&Giant); \ - _pcm_giant = 1; \ - } while (0) - -#define PCM_GIANT_EXIT(x) do { \ - if (PCM_LOCKOWNED(x)) \ - panic("%s(%d): [GIANT EXIT] PCM lock owned!", \ - __func__, __LINE__); \ - if (!(_pcm_giant == 0 || _pcm_giant == 1)) \ - panic("%s(%d): [GIANT EXIT] _pcm_giant screwed!", \ - __func__, __LINE__); \ - if ((x)->flags & SD_F_MPSAFE) { \ - if (_pcm_giant == 1) \ - panic("%s(%d): [GIANT EXIT] MPSAFE Giant?", \ - __func__, __LINE__); \ - if (mtx_owned(&Giant) != 0 && snd_verbose > 3) \ - device_printf((x)->dev, \ - "%s(%d): [GIANT EXIT] Giant owned!\n", \ - __func__, __LINE__); \ - } \ - if (_pcm_giant != 0) { \ - if (mtx_owned(&Giant) == 0) \ - panic("%s(%d): [GIANT EXIT] Giant not owned!", \ - __func__, __LINE__); \ - _pcm_giant = 0; \ - mtx_unlock(&Giant); \ - } \ -} while (0) -#else /* !SND_DIAGNOSTIC */ #define PCM_WAIT(x) do { \ PCM_LOCKASSERT(x); \ while ((x)->flags & SD_F_BUSY) \ - cv_wait(&(x)->cv, (x)->lock); \ + cv_wait(&(x)->cv, &(x)->lock); \ } while (0) #define PCM_ACQUIRE(x) do { \ @@ -429,7 +314,6 @@ int sound_oss_card_info(oss_card_info *); mtx_unlock(&Giant); \ } \ } while (0) -#endif /* SND_DIAGNOSTIC */ #define PCM_GIANT_LEAVE(x) \ PCM_GIANT_EXIT(x); \ diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c index 31a4f7db8d70..dcb49e3003d0 100644 --- a/sys/dev/sound/pcm/vchan.c +++ b/sys/dev/sound/pcm/vchan.c @@ -47,13 +47,6 @@ #define FMTLIST_OFFSET 4 #define DIGFMTS_MAX 2 -#ifdef SND_DEBUG -static int snd_passthrough_verbose = 0; -SYSCTL_INT(_hw_snd, OID_AUTO, passthrough_verbose, CTLFLAG_RWTUN, - &snd_passthrough_verbose, 0, "passthrough verbosity"); - -#endif - struct vchan_info { struct pcm_channel *channel; struct pcmchan_caps caps; @@ -492,7 +485,7 @@ sysctl_dev_pcm_vchanrate(SYSCTL_HANDLER_ARGS) } } } - *vchanrate = sndbuf_getspd(c->bufsoft); + *vchanrate = c->bufsoft->spd; CHN_UNLOCK(c); } @@ -591,7 +584,7 @@ sysctl_dev_pcm_vchanformat(SYSCTL_HANDLER_ARGS) } } } - *vchanformat = sndbuf_getfmt(c->bufsoft); + *vchanformat = c->bufsoft->fmt; CHN_UNLOCK(c); } @@ -723,11 +716,7 @@ vchan_destroy(struct pcm_channel *c) } int -#ifdef SND_DEBUG -vchan_passthrough(struct pcm_channel *c, const char *caller) -#else vchan_sync(struct pcm_channel *c) -#endif { int ret; @@ -744,13 +733,6 @@ vchan_sync(struct pcm_channel *c) if (ret != 0) c->flags |= CHN_F_DIRTY; -#ifdef SND_DEBUG - if (snd_passthrough_verbose) { - device_printf(c->dev, "%s(%s/%s) %s() -> re-sync err=%d\n", - __func__, c->name, c->comm, caller, ret); - } -#endif - return (ret); } diff --git a/sys/dev/sound/pcm/vchan.h b/sys/dev/sound/pcm/vchan.h index 8c1de9496ef3..5d8057cd4b7f 100644 --- a/sys/dev/sound/pcm/vchan.h +++ b/sys/dev/sound/pcm/vchan.h @@ -39,17 +39,12 @@ extern bool snd_vchans_enable; int vchan_create(struct pcm_channel *, struct pcm_channel **); int vchan_destroy(struct pcm_channel *); -#ifdef SND_DEBUG -int vchan_passthrough(struct pcm_channel *, const char *); -#define vchan_sync(c) vchan_passthrough(c, __func__) -#else int vchan_sync(struct pcm_channel *); -#endif #define VCHAN_SYNC_REQUIRED(c) \ (((c)->flags & CHN_F_VIRTUAL) && (((c)->flags & CHN_F_DIRTY) || \ - sndbuf_getfmt((c)->bufhard) != (c)->parentchannel->format || \ - sndbuf_getspd((c)->bufhard) != (c)->parentchannel->speed)) + (c)->bufhard->fmt != (c)->parentchannel->format || \ + (c)->bufhard->spd != (c)->parentchannel->speed)) void vchan_initsys(device_t); diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index ff9f59fe42ab..65c1327ee0f2 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -2664,7 +2664,7 @@ uaudio_chan_init(struct uaudio_chan *ch, struct snd_dbuf *b, /* store mutex and PCM channel */ ch->pcm_ch = c; - ch->pcm_mtx = c->lock; + ch->pcm_mtx = &c->lock; /* compute worst case buffer */ diff --git a/sys/dev/tpm/tpm20.c b/sys/dev/tpm/tpm20.c index 067e7ccae8f9..6c587818058d 100644 --- a/sys/dev/tpm/tpm20.c +++ b/sys/dev/tpm/tpm20.c @@ -42,7 +42,7 @@ MALLOC_DEFINE(M_TPM20, "tpm_buffer", "buffer for tpm 2.0 driver"); static void tpm20_discard_buffer(void *arg); -#ifdef TPM_HARVEST +#if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM static void tpm20_harvest(void *arg, int unused); #endif static int tpm20_save_state(device_t dev, bool suspend); @@ -184,7 +184,7 @@ tpm20_ioctl(struct cdev *dev, u_long cmd, caddr_t data, return (ENOTTY); } -#ifdef TPM_HARVEST +#if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM static const struct random_source random_tpm = { .rs_ident = "TPM", .rs_source = RANDOM_PURE_TPM, @@ -212,7 +212,7 @@ tpm20_init(struct tpm_sc *sc) if (result != 0) tpm20_release(sc); -#ifdef TPM_HARVEST +#if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM random_source_register(&random_tpm); TIMEOUT_TASK_INIT(taskqueue_thread, &sc->harvest_task, 0, tpm20_harvest, sc); @@ -227,7 +227,7 @@ void tpm20_release(struct tpm_sc *sc) { -#ifdef TPM_HARVEST +#if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM if (device_is_attached(sc->dev)) taskqueue_drain_timeout(taskqueue_thread, &sc->harvest_task); random_source_deregister(&random_tpm); @@ -254,7 +254,7 @@ tpm20_shutdown(device_t dev) return (tpm20_save_state(dev, false)); } -#ifdef TPM_HARVEST +#if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM /* * Get TPM_HARVEST_SIZE random bytes and add them * into system entropy pool. diff --git a/sys/dev/tpm/tpm20.h b/sys/dev/tpm/tpm20.h index 7c2ccd30143a..b2cfcd4f25bd 100644 --- a/sys/dev/tpm/tpm20.h +++ b/sys/dev/tpm/tpm20.h @@ -128,7 +128,7 @@ struct tpm_sc { lwpid_t owner_tid; struct callout discard_buffer_callout; -#ifdef TPM_HARVEST +#if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM struct timeout_task harvest_task; #endif diff --git a/sys/dev/tpm/tpm_crb.c b/sys/dev/tpm/tpm_crb.c index 017ebd45c7ea..28b4f21eccfb 100644 --- a/sys/dev/tpm/tpm_crb.c +++ b/sys/dev/tpm/tpm_crb.c @@ -301,6 +301,48 @@ tpmcrb_cancel_cmd(struct tpm_sc *sc) return (true); } +static bool +tpmcrb_state_idle(struct tpmcrb_sc *crb_sc, bool wait) +{ + struct tpm_sc *sc; + int mask, timeout; + + timeout = wait ? TPM_TIMEOUT_C : 0; + + sc = &crb_sc->base; + OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE); + + if (timeout > 0) { + mask = TPM_CRB_CTRL_STS_IDLE_BIT; + if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS, mask, mask, + timeout)) + return (false); + } + + return (true); +} + +static bool +tpmcrb_state_ready(struct tpmcrb_sc *crb_sc, bool wait) +{ + struct tpm_sc *sc; + int mask, timeout; + + timeout = wait ? TPM_TIMEOUT_C : 0; + + sc = &crb_sc->base; + OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_READY); + + if (timeout > 0) { + mask = TPM_CRB_CTRL_REQ_GO_READY; + if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS, mask, !mask, + timeout)) + return (false); + } + + return (true); +} + int tpmcrb_transmit(device_t dev, size_t length) { @@ -335,22 +377,15 @@ tpmcrb_transmit(device_t dev, size_t length) /* Switch device to idle state if necessary */ if (!(TPM_READ_4(dev, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_IDLE_BIT)) { - OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE); - - mask = TPM_CRB_CTRL_STS_IDLE_BIT; - if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS, - mask, mask, TPM_TIMEOUT_C)) { + if (!tpmcrb_state_idle(crb_sc, true)) { device_printf(dev, "Failed to transition to idle state\n"); return (EIO); } } - /* Switch to ready state */ - OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_READY); - mask = TPM_CRB_CTRL_REQ_GO_READY; - if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS, - mask, !mask, TPM_TIMEOUT_C)) { + /* Switch to ready state */ + if (!tpmcrb_state_ready(crb_sc, true)) { device_printf(dev, "Failed to transition to ready state\n"); return (EIO); @@ -394,7 +429,11 @@ tpmcrb_transmit(device_t dev, size_t length) bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off + TPM_HEADER_SIZE, &sc->buf[TPM_HEADER_SIZE], bytes_available - TPM_HEADER_SIZE); - OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE); + if (!tpmcrb_state_idle(crb_sc, false)) { + device_printf(dev, + "Failed to transition to idle state post-send\n"); + return (EIO); + } tpmcrb_relinquish_locality(sc); sc->pending_data_length = bytes_available; diff --git a/sys/dev/usb/wlan/if_mtw.c b/sys/dev/usb/wlan/if_mtw.c index 6967e5081542..8384c0a2d9fc 100644 --- a/sys/dev/usb/wlan/if_mtw.c +++ b/sys/dev/usb/wlan/if_mtw.c @@ -174,7 +174,7 @@ static int mtw_read(struct mtw_softc *, uint16_t, uint32_t *); static int mtw_read_region_1(struct mtw_softc *, uint16_t, uint8_t *, int); static int mtw_write_2(struct mtw_softc *, uint16_t, uint16_t); static int mtw_write(struct mtw_softc *, uint16_t, uint32_t); -static int mtw_write_region_1(struct mtw_softc *, uint16_t, uint8_t *, int); +static int mtw_write_region_1(struct mtw_softc *, uint16_t, const uint8_t *, int); static int mtw_set_region_4(struct mtw_softc *, uint16_t, uint32_t, int); static int mtw_efuse_read_2(struct mtw_softc *, uint16_t, uint16_t *); static int mtw_bbp_read(struct mtw_softc *, uint8_t, uint8_t *); @@ -1277,7 +1277,8 @@ mtw_write(struct mtw_softc *sc, uint16_t reg, uint32_t val) } static int -mtw_write_region_1(struct mtw_softc *sc, uint16_t reg, uint8_t *buf, int len) +mtw_write_region_1(struct mtw_softc *sc, uint16_t reg, const uint8_t *buf, + int len) { usb_device_request_t req; @@ -1286,7 +1287,8 @@ mtw_write_region_1(struct mtw_softc *sc, uint16_t reg, uint8_t *buf, int len) USETW(req.wValue, 0); USETW(req.wIndex, reg); USETW(req.wLength, len); - return (usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, buf)); + return (usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, + __DECONST(uint8_t *, buf))); } static int @@ -1911,7 +1913,7 @@ mtw_key_set_cb(void *arg) /* map net80211 cipher to RT2860 security mode */ switch (cipher) { case IEEE80211_CIPHER_WEP: - if (k->wk_keylen < 8) + if (ieee80211_crypto_get_key_len(k) < 8) mode = MTW_MODE_WEP40; else mode = MTW_MODE_WEP104; @@ -1936,13 +1938,19 @@ mtw_key_set_cb(void *arg) } if (cipher == IEEE80211_CIPHER_TKIP) { - mtw_write_region_1(sc, base, k->wk_key, 16); - mtw_write_region_1(sc, base + 16, &k->wk_key[24], 8); - mtw_write_region_1(sc, base + 24, &k->wk_key[16], 8); + /* TODO: note the direct use of tx/rx mic offsets! ew! */ + mtw_write_region_1(sc, base, + ieee80211_crypto_get_key_data(k), 16); + /* rxmic */ + mtw_write_region_1(sc, base + 16, + ieee80211_crypto_get_key_rxmic_data(k), 8); + /* txmic */ + mtw_write_region_1(sc, base + 24, + ieee80211_crypto_get_key_txmic_data(k), 8); } else { /* roundup len to 16-bit: XXX fix write_region_1() instead */ mtw_write_region_1(sc, base, k->wk_key, - (k->wk_keylen + 1) & ~1); + (ieee80211_crypto_get_key_len(k) + 1) & ~1); } if (!(k->wk_flags & IEEE80211_KEY_GROUP) || diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c index 471c6b3714b2..d9daa5bfd70a 100644 --- a/sys/dev/virtio/network/if_vtnet.c +++ b/sys/dev/virtio/network/if_vtnet.c @@ -1346,20 +1346,40 @@ vtnet_ioctl_ifcap(struct vtnet_softc *sc, struct ifreq *ifr) VTNET_CORE_LOCK_ASSERT(sc); if (mask & IFCAP_TXCSUM) { + if (if_getcapenable(ifp) & IFCAP_TXCSUM && + if_getcapenable(ifp) & IFCAP_TSO4) { + /* Disable tso4, because txcsum will be disabled. */ + if_setcapenablebit(ifp, 0, IFCAP_TSO4); + if_sethwassistbits(ifp, 0, CSUM_IP_TSO); + mask &= ~IFCAP_TSO4; + } if_togglecapenable(ifp, IFCAP_TXCSUM); if_togglehwassist(ifp, VTNET_CSUM_OFFLOAD); } if (mask & IFCAP_TXCSUM_IPV6) { + if (if_getcapenable(ifp) & IFCAP_TXCSUM_IPV6 && + if_getcapenable(ifp) & IFCAP_TSO6) { + /* Disable tso6, because txcsum6 will be disabled. */ + if_setcapenablebit(ifp, 0, IFCAP_TSO6); + if_sethwassistbits(ifp, 0, CSUM_IP6_TSO); + mask &= ~IFCAP_TSO6; + } if_togglecapenable(ifp, IFCAP_TXCSUM_IPV6); if_togglehwassist(ifp, VTNET_CSUM_OFFLOAD_IPV6); } if (mask & IFCAP_TSO4) { - if_togglecapenable(ifp, IFCAP_TSO4); - if_togglehwassist(ifp, IFCAP_TSO4); + if (if_getcapenable(ifp) & (IFCAP_TXCSUM | IFCAP_TSO4)) { + /* tso4 can only be enabled, if txcsum is enabled. */ + if_togglecapenable(ifp, IFCAP_TSO4); + if_togglehwassist(ifp, CSUM_IP_TSO); + } } if (mask & IFCAP_TSO6) { - if_togglecapenable(ifp, IFCAP_TSO6); - if_togglehwassist(ifp, IFCAP_TSO6); + if (if_getcapenable(ifp) & (IFCAP_TXCSUM_IPV6 | IFCAP_TSO6)) { + /* tso6 can only be enabled, if txcsum6 is enabled. */ + if_togglecapenable(ifp, IFCAP_TSO6); + if_togglehwassist(ifp, CSUM_IP6_TSO); + } } if (mask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6 | IFCAP_LRO)) { @@ -2505,10 +2525,6 @@ vtnet_txq_offload(struct vtnet_txq *txq, struct mbuf *m, hdr->csum_start = vtnet_gtoh16(sc, csum_start); hdr->csum_offset = vtnet_gtoh16(sc, m->m_pkthdr.csum_data); txq->vtntx_stats.vtxs_csum++; - } else if ((flags & (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) && - (proto == IPPROTO_TCP || proto == IPPROTO_UDP) && - (m->m_pkthdr.csum_data == 0xFFFF)) { - hdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID; } if (flags & (CSUM_IP_TSO | CSUM_IP6_TSO)) { @@ -2622,8 +2638,7 @@ vtnet_txq_encap(struct vtnet_txq *txq, struct mbuf **m_head, int flags) m->m_flags &= ~M_VLANTAG; } - if (m->m_pkthdr.csum_flags & - (VTNET_CSUM_ALL_OFFLOAD | CSUM_DATA_VALID)) { + if (m->m_pkthdr.csum_flags & VTNET_CSUM_ALL_OFFLOAD) { m = vtnet_txq_offload(txq, m, hdr); if ((*m_head = m) == NULL) { error = ENOBUFS; diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c index bcf67ddc9689..a1376be954ee 100644 --- a/sys/dev/vt/vt_core.c +++ b/sys/dev/vt/vt_core.c @@ -876,7 +876,9 @@ vt_processkey(keyboard_t *kbd, struct vt_device *vd, int c) { struct vt_window *vw = vd->vd_curwindow; +#ifdef RANDOM_ENABLE_KBD random_harvest_queue(&c, sizeof(c), RANDOM_KEYBOARD); +#endif #if VT_ALT_TO_ESC_HACK if (c & RELKEY) { switch (c & ~RELKEY) { diff --git a/sys/dev/vt/vt_sysmouse.c b/sys/dev/vt/vt_sysmouse.c index f2f5a0fa5c3a..873dce123f7a 100644 --- a/sys/dev/vt/vt_sysmouse.c +++ b/sys/dev/vt/vt_sysmouse.c @@ -32,7 +32,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> #include "opt_evdev.h" #include <sys/param.h> @@ -222,7 +221,9 @@ sysmouse_process_event(mouse_info_t *mi) unsigned char buf[MOUSE_SYS_PACKETSIZE]; int x, y, iy, z; +#ifdef RANDOM_ENABLE_MOUSE random_harvest_queue(mi, sizeof *mi, RANDOM_MOUSE); +#endif mtx_lock(&sysmouse_lock); switch (mi->operation) { diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c index 4a2b80a7ccdd..92ea6d2b4501 100644 --- a/sys/fs/cd9660/cd9660_vnops.c +++ b/sys/fs/cd9660/cd9660_vnops.c @@ -193,8 +193,8 @@ cd9660_getattr(struct vop_getattr_args *ap) vap->va_ctime = ip->inode.iso_ctime; vap->va_rdev = VN_ISDEV(vp) ? ip->inode.iso_rdev : NODEV; - vap->va_size = (u_quad_t) ip->i_size; - if (ip->i_size == 0 && (vap->va_mode & S_IFMT) == S_IFLNK) { + vap->va_size = ip->i_size; + if (ip->i_size == 0 && vp->v_type == VLNK) { struct vop_readlink_args rdlnk; struct iovec aiov; struct uio auio; diff --git a/sys/fs/cuse/cuse.c b/sys/fs/cuse/cuse.c index b2524324584a..b914b2d5017c 100644 --- a/sys/fs/cuse/cuse.c +++ b/sys/fs/cuse/cuse.c @@ -1516,13 +1516,6 @@ cuse_client_open(struct cdev *dev, int fflags, int devtype, struct thread *td) } pcc = malloc(sizeof(*pcc), M_CUSE, M_WAITOK | M_ZERO); - if (devfs_set_cdevpriv(pcc, &cuse_client_free)) { - printf("Cuse: Cannot set cdevpriv.\n"); - /* drop reference on server */ - cuse_server_unref(pcs); - free(pcc, M_CUSE); - return (ENOMEM); - } pcc->fflags = fflags; pcc->server_dev = pcsd; pcc->server = pcs; @@ -1553,10 +1546,12 @@ cuse_client_open(struct cdev *dev, int fflags, int devtype, struct thread *td) } cuse_server_unlock(pcs); - if (error) { - devfs_clear_cdevpriv(); /* XXX bugfix */ + if (error != 0) return (error); - } + + if ((error = devfs_set_cdevpriv(pcc, &cuse_client_free)) != 0) + return (error); + pccmd = &pcc->cmds[CUSE_CMD_OPEN]; cuse_cmd_lock(pccmd); @@ -1575,9 +1570,6 @@ cuse_client_open(struct cdev *dev, int fflags, int devtype, struct thread *td) cuse_cmd_unlock(pccmd); - if (error) - devfs_clear_cdevpriv(); /* XXX bugfix */ - return (error); } diff --git a/sys/fs/tarfs/tarfs_io.c b/sys/fs/tarfs/tarfs_io.c index a3d8df62d7df..e250c5cbce5a 100644 --- a/sys/fs/tarfs/tarfs_io.c +++ b/sys/fs/tarfs/tarfs_io.c @@ -444,7 +444,7 @@ tarfs_zread_zstd(struct tarfs_zio *zio, struct uio *uiop) } if (zio->opos < off) { /* to be discarded */ - zob.size = min(off - zio->opos, len); + zob.size = MIN(off - zio->opos, len); zob.pos = 0; } else { zob.size = len; diff --git a/sys/fs/tarfs/tarfs_vfsops.c b/sys/fs/tarfs/tarfs_vfsops.c index 4cc70e4d5781..cae780cb71e5 100644 --- a/sys/fs/tarfs/tarfs_vfsops.c +++ b/sys/fs/tarfs/tarfs_vfsops.c @@ -441,7 +441,7 @@ tarfs_alloc_one(struct tarfs_mount *tmp, size_t *blknump) int endmarker = 0; char *namep, *sep; struct tarfs_node *parent, *tnp, *other; - size_t namelen = 0, linklen = 0, realsize = 0, sz; + size_t namelen = 0, linklen = 0, realsize = 0, extsize = 0, sz; ssize_t res; dev_t rdev; gid_t gid; @@ -588,10 +588,7 @@ again: char *eol, *key, *value, *sep; size_t len = strtoul(line, &sep, 10); if (len == 0 || sep == line || *sep != ' ') { - TARFS_DPF(ALLOC, "%s: exthdr syntax error\n", - __func__); - error = EINVAL; - goto bad; + goto syntax; } if ((uintptr_t)line + len < (uintptr_t)line || line + len > exthdr + sz) { @@ -606,16 +603,18 @@ again: key = sep + 1; sep = strchr(key, '='); if (sep == NULL) { - TARFS_DPF(ALLOC, "%s: exthdr syntax error\n", - __func__); - error = EINVAL; - goto bad; + goto syntax; } *sep = '\0'; value = sep + 1; TARFS_DPF(ALLOC, "%s: exthdr %s=%s\n", __func__, key, value); - if (strcmp(key, "path") == 0) { + if (strcmp(key, "size") == 0) { + extsize = strtol(value, &sep, 10); + if (sep != eol) { + goto syntax; + } + } else if (strcmp(key, "path") == 0) { name = value; namelen = eol - value; } else if (strcmp(key, "linkpath") == 0) { @@ -625,47 +624,42 @@ again: sparse = true; major = strtol(value, &sep, 10); if (sep != eol) { - printf("exthdr syntax error\n"); - error = EINVAL; - goto bad; + goto syntax; } } else if (strcmp(key, "GNU.sparse.minor") == 0) { sparse = true; minor = strtol(value, &sep, 10); if (sep != eol) { - printf("exthdr syntax error\n"); - error = EINVAL; - goto bad; + goto syntax; } } else if (strcmp(key, "GNU.sparse.name") == 0) { sparse = true; name = value; namelen = eol - value; if (namelen == 0) { - printf("exthdr syntax error\n"); - error = EINVAL; - goto bad; + goto syntax; } } else if (strcmp(key, "GNU.sparse.realsize") == 0) { sparse = true; realsize = strtoul(value, &sep, 10); if (sep != eol) { - printf("exthdr syntax error\n"); - error = EINVAL; - goto bad; + goto syntax; } } else if (strcmp(key, "SCHILY.fflags") == 0) { flags |= tarfs_strtofflags(value, &sep); if (sep != eol) { - printf("exthdr syntax error\n"); - error = EINVAL; - goto bad; + goto syntax; } } } goto again; } + /* do we have a size from an exthdr? */ + if (extsize > 0) { + sz = extsize; + } + /* sparse file consistency checks */ if (sparse) { TARFS_DPF(ALLOC, "%s: %s: sparse %ld.%ld (%zu bytes)\n", __func__, @@ -832,6 +826,10 @@ skip: sbuf_delete(namebuf); } return (0); +syntax: + TARFS_DPF(ALLOC, "%s: exthdr syntax error\n", __func__); + error = EINVAL; + goto bad; eof: TARFS_DPF(IO, "%s: premature end of file\n", __func__); error = EIO; diff --git a/sys/geom/zero/g_zero.c b/sys/geom/zero/g_zero.c index 7952147d660a..25d462a9f918 100644 --- a/sys/geom/zero/g_zero.c +++ b/sys/geom/zero/g_zero.c @@ -3,6 +3,7 @@ * * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> * All rights reserved. + * Copyright (c) 2025 Mateusz Piotrowski <0mp@FreeBSD.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,53 +35,97 @@ #include <sys/queue.h> #include <sys/sysctl.h> #include <sys/systm.h> +#include <sys/uio.h> +#include <sys/types.h> #include <geom/geom.h> #define G_ZERO_CLASS_NAME "ZERO" -static int g_zero_clear_sysctl(SYSCTL_HANDLER_ARGS); +static int g_zero_byte_sysctl(SYSCTL_HANDLER_ARGS); SYSCTL_DECL(_kern_geom); static SYSCTL_NODE(_kern_geom, OID_AUTO, zero, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "GEOM_ZERO stuff"); static int g_zero_clear = 1; -SYSCTL_PROC(_kern_geom_zero, OID_AUTO, clear, - CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, &g_zero_clear, 0, - g_zero_clear_sysctl, "I", +SYSCTL_INT(_kern_geom_zero, OID_AUTO, clear, + CTLFLAG_RWTUN, &g_zero_clear, 0, "Clear read data buffer"); static int g_zero_byte = 0; -SYSCTL_INT(_kern_geom_zero, OID_AUTO, byte, CTLFLAG_RWTUN, &g_zero_byte, 0, +static uint8_t g_zero_buffer[PAGE_SIZE]; +SYSCTL_PROC(_kern_geom_zero, OID_AUTO, byte, + CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, &g_zero_byte, 0, + g_zero_byte_sysctl, "I", "Byte (octet) value to clear the buffers with"); static struct g_provider *gpp; static int -g_zero_clear_sysctl(SYSCTL_HANDLER_ARGS) +g_zero_byte_sysctl(SYSCTL_HANDLER_ARGS) { int error; - error = sysctl_handle_int(oidp, &g_zero_clear, 0, req); + // XXX: Confirm that this is called on module load as well. + // XXX: Shouldn't we lock here to avoid changing the byte value if the + // driver is in the process of handling I/O? + error = sysctl_handle_int(oidp, &g_zero_byte, 0, req); if (error != 0 || req->newptr == NULL) return (error); - if (gpp == NULL) - return (ENXIO); - if (g_zero_clear) - gpp->flags &= ~G_PF_ACCEPT_UNMAPPED; - else - gpp->flags |= G_PF_ACCEPT_UNMAPPED; + memset(g_zero_buffer, g_zero_byte, PAGE_SIZE); return (0); } static void +g_zero_fill_pages(struct bio *bp) +{ + struct iovec aiovec; + struct uio auio; + size_t length; + vm_offset_t offset; + + aiovec.iov_base = g_zero_buffer; + aiovec.iov_len = PAGE_SIZE; + auio.uio_iov = &aiovec; + auio.uio_iovcnt = 1; + auio.uio_offset = 0; + auio.uio_segflg = UIO_SYSSPACE; + auio.uio_rw = UIO_WRITE; + auio.uio_td = curthread; + + /* + * To handle the unmapped I/O request, we need to fill the pages in the + * bp->bio_ma array with the g_zero_byte value. However, instead of + * setting every byte individually, we use uiomove_fromphys() to fill a + * page at a time with g_zero_buffer. + */ + bp->bio_resid = bp->bio_length; + offset = bp->bio_ma_offset & PAGE_MASK; + for (int i = 0; i < bp->bio_ma_n && bp->bio_resid > 0; i++) { + length = MIN(PAGE_SIZE - offset, bp->bio_resid); + auio.uio_resid = length; + + (void)uiomove_fromphys(&bp->bio_ma[i], offset, length, &auio); + + offset = 0; + bp->bio_resid -= length; + } +} + + +static void g_zero_start(struct bio *bp) { - int error = ENXIO; + int error; switch (bp->bio_cmd) { case BIO_READ: - if (g_zero_clear && (bp->bio_flags & BIO_UNMAPPED) == 0) - memset(bp->bio_data, g_zero_byte, bp->bio_length); + if (g_zero_clear) { + if ((bp->bio_flags & BIO_UNMAPPED) != 0) + g_zero_fill_pages(bp); + else + memset(bp->bio_data, g_zero_byte, + bp->bio_length); + } /* FALLTHROUGH */ case BIO_DELETE: case BIO_WRITE: @@ -106,9 +151,8 @@ g_zero_init(struct g_class *mp) gp->start = g_zero_start; gp->access = g_std_access; gpp = pp = g_new_providerf(gp, "%s", gp->name); - pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE; - if (!g_zero_clear) - pp->flags |= G_PF_ACCEPT_UNMAPPED; + pp->flags |= G_PF_ACCEPT_UNMAPPED | G_PF_DIRECT_SEND | + G_PF_DIRECT_RECEIVE; pp->mediasize = 1152921504606846976LLU; pp->sectorsize = 512; g_error_provider(pp, 0); diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index a71a601733e5..2fa0621bdfca 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -194,7 +194,6 @@ struct filedesc0 { */ static int __exclusive_cache_line openfiles; /* actual number of open files */ struct mtx sigio_lock; /* mtx to protect pointers to sigio */ -void __read_mostly (*mq_fdclose)(struct thread *td, int fd, struct file *fp); /* * If low >= size, just return low. Otherwise find the first zero bit in the @@ -1413,11 +1412,8 @@ closefp_impl(struct filedesc *fdp, int fd, struct file *fp, struct thread *td, if (__predict_false(!TAILQ_EMPTY(&fdp->fd_kqlist))) knote_fdclose(td, fd); - /* - * We need to notify mqueue if the object is of type mqueue. - */ - if (__predict_false(fp->f_type == DTYPE_MQUEUE)) - mq_fdclose(td, fd, fp); + if (fp->f_ops->fo_fdclose != NULL) + fp->f_ops->fo_fdclose(fp, fd, td); FILEDESC_XUNLOCK(fdp); #ifdef AUDIT diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 1baa24d278bf..a48408fd482a 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -627,12 +627,20 @@ knote_fork(struct knlist *list, int pid) kev.data = kn->kn_id; /* parent */ kev.udata = kn->kn_kevent.udata;/* preserve udata */ error = kqueue_register(kq, &kev, NULL, M_NOWAIT); + + /* + * Serialize updates to the kn_kevent fields with threads + * scanning the queue. + */ + list->kl_lock(list->kl_lockarg); if (error) kn->kn_fflags |= NOTE_TRACKERR; - if (kn->kn_fop->f_event(kn, NOTE_FORK)) - KNOTE_ACTIVATE(kn, 0); - list->kl_lock(list->kl_lockarg); - KQ_LOCK(kq); + if (kn->kn_fop->f_event(kn, NOTE_FORK)) { + KQ_LOCK(kq); + KNOTE_ACTIVATE(kn, 1); + } else { + KQ_LOCK(kq); + } kn_leave_flux(kn); KQ_UNLOCK_FLUX(kq); } diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 523b7e314a10..d1149dd4fb3b 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -1065,8 +1065,10 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) * than duplicate it under a different name. */ error = vfs_buildopts(optuio, &opts); - if (error) + if (error) { + opts = NULL; goto done_free; + } cuflags = flags & (JAIL_CREATE | JAIL_UPDATE); if (!cuflags) { @@ -2331,7 +2333,8 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) (void)kern_close(td, jfd_out); if (g_path != NULL) free(g_path, M_TEMP); - vfs_freeopts(opts); + if (opts != NULL) + vfs_freeopts(opts); prison_free(mypr); return (error); } @@ -3043,14 +3046,19 @@ do_jail_attach(struct thread *td, struct prison *pr, int drflags) PROC_LOCK(p); oldcred = crcopysafe(p, newcred); newcred->cr_prison = pr; - proc_set_cred(p, newcred); - setsugid(p); #ifdef RACCT racct_proc_ucred_changed(p, oldcred, newcred); #endif #ifdef RCTL crhold(newcred); #endif + /* + * Takes over 'newcred''s reference, so 'newcred' must not be used + * besides this point except on RCTL where we took an additional + * reference above. + */ + proc_set_cred(p, newcred); + setsugid(p); PROC_UNLOCK(p); #ifdef RCTL rctl_proc_ucred_changed(p, newcred); diff --git a/sys/kern/kern_jaildesc.c b/sys/kern/kern_jaildesc.c index a564393d3366..f4e31801201f 100644 --- a/sys/kern/kern_jaildesc.c +++ b/sys/kern/kern_jaildesc.c @@ -54,7 +54,7 @@ static fo_close_t jaildesc_close; static fo_fill_kinfo_t jaildesc_fill_kinfo; static fo_cmp_t jaildesc_cmp; -static struct fileops jaildesc_ops = { +static const struct fileops jaildesc_ops = { .fo_read = invfo_rdwr, .fo_write = invfo_rdwr, .fo_truncate = invfo_truncate, diff --git a/sys/kern/kern_loginclass.c b/sys/kern/kern_loginclass.c index 0c111c4f78d8..07d388f18f8d 100644 --- a/sys/kern/kern_loginclass.c +++ b/sys/kern/kern_loginclass.c @@ -222,13 +222,18 @@ sys_setloginclass(struct thread *td, struct setloginclass_args *uap) PROC_LOCK(p); oldcred = crcopysafe(p, newcred); newcred->cr_loginclass = newlc; - proc_set_cred(p, newcred); #ifdef RACCT racct_proc_ucred_changed(p, oldcred, newcred); #endif #ifdef RCTL crhold(newcred); #endif + /* + * Takes over 'newcred''s reference, so 'newcred' must not be used + * besides this point except on RCTL where we took an additional + * reference above. + */ + proc_set_cred(p, newcred); PROC_UNLOCK(p); #ifdef RCTL rctl_proc_ucred_changed(p, newcred); diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 3c145851b683..81099aa7d28d 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -422,7 +422,7 @@ again: * pid must be in same session (EPERM) * pid can't have done an exec (EACCES) * if pgid != pid - * there must exist some pid in same session having pgid (EPERM) + * there must exist some pid in same session having pgid (EPERM) * pid must not be session leader (EPERM) */ #ifndef _SYS_SYSPROTO_H_ @@ -603,8 +603,8 @@ user_setcred(struct thread *td, const u_int flags, if (error != 0) return (error); /* These fields have exactly the same sizes and positions. */ - memcpy(&wcred, &wcred32, &wcred32.setcred32_copy_end - - &wcred32.setcred32_copy_start); + memcpy(&wcred, &wcred32, __rangeof(struct setcred32, + setcred32_copy_start, setcred32_copy_end)); /* Remaining fields are pointers and need PTRIN*(). */ PTRIN_CP(wcred32, wcred, sc_supp_groups); PTRIN_CP(wcred32, wcred, sc_label); @@ -832,22 +832,31 @@ kern_setcred(struct thread *const td, const u_int flags, if (error != 0) goto unlock_finish; +#ifdef RACCT /* - * Set the new credentials, noting that they have changed. + * Hold a reference to 'new_cred', as we need to call some functions on + * it after proc_set_cred_enforce_proc_lim(). */ + crhold(new_cred); +#endif + + /* Set the new credentials. */ cred_set = proc_set_cred_enforce_proc_lim(p, new_cred); if (cred_set) { setsugid(p); - to_free_cred = old_cred; #ifdef RACCT + /* Adjust RACCT counters. */ racct_proc_ucred_changed(p, old_cred, new_cred); #endif -#ifdef RCTL - crhold(new_cred); -#endif + to_free_cred = old_cred; MPASS(error == 0); - } else + } else { +#ifdef RACCT + /* Matches the crhold() just before the containing 'if'. */ + crfree(new_cred); +#endif error = EAGAIN; + } unlock_finish: PROC_UNLOCK(p); @@ -857,10 +866,12 @@ unlock_finish: * finishing operations. */ -#ifdef RCTL +#ifdef RACCT if (cred_set) { +#ifdef RCTL rctl_proc_ucred_changed(p, new_cred); - /* Paired with the crhold() just above. */ +#endif + /* Paired with the crhold() above. */ crfree(new_cred); } #endif @@ -991,16 +1002,19 @@ sys_setuid(struct thread *td, struct setuid_args *uap) change_euid(newcred, uip); setsugid(p); } - /* - * This also transfers the proc count to the new user. - */ - proc_set_cred(p, newcred); + #ifdef RACCT racct_proc_ucred_changed(p, oldcred, newcred); #endif #ifdef RCTL crhold(newcred); #endif + /* + * Takes over 'newcred''s reference, so 'newcred' must not be used + * besides this point except on RCTL where we took an additional + * reference above. + */ + proc_set_cred(p, newcred); PROC_UNLOCK(p); #ifdef RCTL rctl_proc_ucred_changed(p, newcred); @@ -1404,13 +1418,18 @@ sys_setreuid(struct thread *td, struct setreuid_args *uap) change_svuid(newcred, newcred->cr_uid); setsugid(p); } - proc_set_cred(p, newcred); #ifdef RACCT racct_proc_ucred_changed(p, oldcred, newcred); #endif #ifdef RCTL crhold(newcred); #endif + /* + * Takes over 'newcred''s reference, so 'newcred' must not be used + * besides this point except on RCTL where we took an additional + * reference above. + */ + proc_set_cred(p, newcred); PROC_UNLOCK(p); #ifdef RCTL rctl_proc_ucred_changed(p, newcred); @@ -1552,13 +1571,18 @@ sys_setresuid(struct thread *td, struct setresuid_args *uap) change_svuid(newcred, suid); setsugid(p); } - proc_set_cred(p, newcred); #ifdef RACCT racct_proc_ucred_changed(p, oldcred, newcred); #endif #ifdef RCTL crhold(newcred); #endif + /* + * Takes over 'newcred''s reference, so 'newcred' must not be used + * besides this point except on RCTL where we took an additional + * reference above. + */ + proc_set_cred(p, newcred); PROC_UNLOCK(p); #ifdef RCTL rctl_proc_ucred_changed(p, newcred); @@ -2783,7 +2807,7 @@ cru2xt(struct thread *td, struct xucred *xcr) * 'enforce_proc_lim' being true and if no new process can be accounted to the * new real UID because of the current limit (see the inner comment for more * details) and the caller does not have privilege (PRIV_PROC_LIMIT) to override - * that. + * that. In this case, the reference to 'newcred' is not taken over. */ static bool _proc_set_cred(struct proc *p, struct ucred *newcred, bool enforce_proc_lim) @@ -2792,10 +2816,6 @@ _proc_set_cred(struct proc *p, struct ucred *newcred, bool enforce_proc_lim) MPASS(oldcred != NULL); PROC_LOCK_ASSERT(p, MA_OWNED); - KASSERT(newcred->cr_users == 0, ("%s: users %d not 0 on cred %p", - __func__, newcred->cr_users, newcred)); - KASSERT(newcred->cr_ref == 1, ("%s: ref %ld not 1 on cred %p", - __func__, newcred->cr_ref, newcred)); if (newcred->cr_ruidinfo != oldcred->cr_ruidinfo) { /* @@ -2821,8 +2841,10 @@ _proc_set_cred(struct proc *p, struct ucred *newcred, bool enforce_proc_lim) __func__, oldcred->cr_users, oldcred)); oldcred->cr_users--; mtx_unlock(&oldcred->cr_mtx); + mtx_lock(&newcred->cr_mtx); + newcred->cr_users++; + mtx_unlock(&newcred->cr_mtx); p->p_ucred = newcred; - newcred->cr_users = 1; PROC_UPDATE_COW(p); if (newcred->cr_ruidinfo != oldcred->cr_ruidinfo) (void)chgproccnt(oldcred->cr_ruidinfo, -1, 0); diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c index 17b64ad00bb5..d1324935bdc3 100644 --- a/sys/kern/kern_racct.c +++ b/sys/kern/kern_racct.c @@ -949,8 +949,10 @@ racct_proc_exit(struct proc *p) } /* - * Called after credentials change, to move resource utilisation - * between raccts. + * Called to signal credentials change, to move resource utilisation + * between raccts. Must be called with the proc lock held, in the same span as + * the credentials change itself (i.e., without the proc lock being unlocked + * between the two), but the order does not matter. */ void racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred, diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 3180c66cb42b..4f9053460455 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -1447,6 +1447,14 @@ thread_suspend_check(int return_instead) } /* + * We might get here with return_instead == 1 if + * other checks missed it. Then we must not suspend + * regardless of P_SHOULDSTOP() or debugger request. + */ + if (return_instead) + return (EINTR); + + /* * If the process is waiting for us to exit, * this thread should just suicide. * Assumes that P_SINGLE_EXIT implies P_STOPPED_SINGLE. @@ -1481,10 +1489,9 @@ thread_suspend_check(int return_instead) * gets taken off all queues. */ thread_suspend_one(td); - if (return_instead == 0) { - p->p_boundary_count++; - td->td_flags |= TDF_BOUNDARY; - } + MPASS(!return_instead); + p->p_boundary_count++; + td->td_flags |= TDF_BOUNDARY; PROC_SUNLOCK(p); mi_switch(SW_INVOL | SWT_SUSPEND); PROC_LOCK(p); diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index bc0725230cca..8cf5ffcdbb96 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -90,6 +90,7 @@ static fo_poll_t soo_poll; static fo_kqfilter_t soo_kqfilter; static fo_stat_t soo_stat; static fo_close_t soo_close; +static fo_fdclose_t soo_fdclose; static fo_chmod_t soo_chmod; static fo_fill_kinfo_t soo_fill_kinfo; static fo_aio_queue_t soo_aio_queue; @@ -105,6 +106,7 @@ const struct fileops socketops = { .fo_kqfilter = soo_kqfilter, .fo_stat = soo_stat, .fo_close = soo_close, + .fo_fdclose = soo_fdclose, .fo_chmod = soo_chmod, .fo_chown = invfo_chown, .fo_sendfile = invfo_sendfile, @@ -362,6 +364,16 @@ soo_close(struct file *fp, struct thread *td) return (error); } +static void +soo_fdclose(struct file *fp, int fd __unused, struct thread *td) +{ + struct socket *so; + + so = fp->f_data; + if (so->so_proto->pr_fdclose != NULL) + so->so_proto->pr_fdclose(so); +} + static int soo_chmod(struct file *fp, mode_t mode, struct ucred *cred, struct thread *td) { diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c index 4c1bb1ff228e..68eda5ecb039 100644 --- a/sys/kern/uipc_mqueue.c +++ b/sys/kern/uipc_mqueue.c @@ -267,7 +267,6 @@ static int _mqueue_send(struct mqueue *mq, struct mqueue_msg *msg, static int _mqueue_recv(struct mqueue *mq, struct mqueue_msg **msg, int timo); static void mqueue_send_notification(struct mqueue *mq); -static void mqueue_fdclose(struct thread *td, int fd, struct file *fp); static void mq_proc_exit(void *arg, struct proc *p); /* @@ -688,7 +687,6 @@ mqfs_init(struct vfsconf *vfc) mqfs_fixup_dir(root); exit_tag = EVENTHANDLER_REGISTER(process_exit, mq_proc_exit, NULL, EVENTHANDLER_PRI_ANY); - mq_fdclose = mqueue_fdclose; p31b_setcfg(CTL_P1003_1B_MESSAGE_PASSING, _POSIX_MESSAGE_PASSING); mqfs_osd_jail_slot = osd_jail_register(NULL, methods); return (0); @@ -2473,35 +2471,6 @@ sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap) } static void -mqueue_fdclose(struct thread *td, int fd, struct file *fp) -{ - struct mqueue *mq; -#ifdef INVARIANTS - struct filedesc *fdp; - - fdp = td->td_proc->p_fd; - FILEDESC_LOCK_ASSERT(fdp); -#endif - - if (fp->f_ops == &mqueueops) { - mq = FPTOMQ(fp); - mtx_lock(&mq->mq_mutex); - notifier_remove(td->td_proc, mq, fd); - - /* have to wakeup thread in same process */ - if (mq->mq_flags & MQ_RSEL) { - mq->mq_flags &= ~MQ_RSEL; - selwakeup(&mq->mq_rsel); - } - if (mq->mq_flags & MQ_WSEL) { - mq->mq_flags &= ~MQ_WSEL; - selwakeup(&mq->mq_wsel); - } - mtx_unlock(&mq->mq_mutex); - } -} - -static void mq_proc_exit(void *arg __unused, struct proc *p) { struct filedesc *fdp; @@ -2566,6 +2535,33 @@ mqf_close(struct file *fp, struct thread *td) return (0); } +static void +mqf_fdclose(struct file *fp, int fd, struct thread *td) +{ + struct mqueue *mq; +#ifdef INVARIANTS + struct filedesc *fdp; + + fdp = td->td_proc->p_fd; + FILEDESC_LOCK_ASSERT(fdp); +#endif + + mq = FPTOMQ(fp); + mtx_lock(&mq->mq_mutex); + notifier_remove(td->td_proc, mq, fd); + + /* have to wakeup thread in same process */ + if (mq->mq_flags & MQ_RSEL) { + mq->mq_flags &= ~MQ_RSEL; + selwakeup(&mq->mq_rsel); + } + if (mq->mq_flags & MQ_WSEL) { + mq->mq_flags &= ~MQ_WSEL; + selwakeup(&mq->mq_wsel); + } + mtx_unlock(&mq->mq_mutex); +} + static int mqf_stat(struct file *fp, struct stat *st, struct ucred *active_cred) { @@ -2694,6 +2690,7 @@ static const struct fileops mqueueops = { .fo_kqfilter = mqf_kqfilter, .fo_stat = mqf_stat, .fo_close = mqf_close, + .fo_fdclose = mqf_fdclose, .fo_chmod = mqf_chmod, .fo_chown = mqf_chown, .fo_sendfile = invfo_sendfile, diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index eb9544628137..00aa5f9309b2 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -54,7 +54,8 @@ * consumer of a socket is starting to tear down the socket, and that the * protocol should terminate the connection. Historically, pr_abort() also * detached protocol state from the socket state, but this is no longer the - * case. + * case. pr_fdclose() is called when userspace invokes close(2) on a socket + * file descriptor. * * socreate() creates a socket and attaches protocol state. This is a public * interface that may be used by socket layer consumers to create new diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 807271488af2..60736af5adf6 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -793,12 +793,18 @@ uipc_connect2(struct socket *so1, struct socket *so2) } static void +maybe_schedule_gc(void) +{ + if (atomic_load_int(&unp_rights) != 0) + taskqueue_enqueue_timeout(taskqueue_thread, &unp_gc_task, -1); +} + +static void uipc_detach(struct socket *so) { struct unpcb *unp, *unp2; struct mtx *vplock; struct vnode *vp; - int local_unp_rights; unp = sotounpcb(so); KASSERT(unp != NULL, ("uipc_detach: unp == NULL")); @@ -854,7 +860,6 @@ uipc_detach(struct socket *so) UNP_REF_LIST_UNLOCK(); UNP_PCB_LOCK(unp); - local_unp_rights = unp_rights; unp->unp_socket->so_pcb = NULL; unp->unp_socket = NULL; free(unp->unp_addr, M_SONAME); @@ -865,8 +870,7 @@ uipc_detach(struct socket *so) mtx_unlock(vplock); vrele(vp); } - if (local_unp_rights) - taskqueue_enqueue_timeout(taskqueue_thread, &unp_gc_task, -1); + maybe_schedule_gc(); switch (so->so_type) { case SOCK_STREAM: @@ -902,6 +906,18 @@ uipc_disconnect(struct socket *so) return (0); } +static void +uipc_fdclose(struct socket *so __unused) +{ + /* + * Ensure that userspace can't create orphaned file descriptors without + * triggering garbage collection. Triggering GC from uipc_detach() is + * not sufficient, since that's only closed once a socket reference + * count drops to zero. + */ + maybe_schedule_gc(); +} + static int uipc_listen(struct socket *so, int backlog, struct thread *td) { @@ -1372,8 +1388,8 @@ uipc_soreceive_stream_or_seqpacket(struct socket *so, struct sockaddr **psa, struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp) { struct sockbuf *sb = &so->so_rcv; - struct mbuf *control, *m, *first, *last, *next; - u_int ctl, space, datalen, mbcnt, lastlen; + struct mbuf *control, *m, *first, *part, *next; + u_int ctl, space, datalen, mbcnt, partlen; int error, flags; bool nonblock, waitall, peek; @@ -1457,22 +1473,16 @@ restart: control = NULL; /* - * Find split point for the next copyout. On exit from the loop: - * last == NULL - socket to be flushed - * last != NULL - * lastlen > last->m_len - uio to be filled, last to be adjusted - * lastlen == 0 - MT_CONTROL, M_EOR or M_NOTREADY encountered + * Find split point for the next copyout. On exit from the loop, + * 'next' points to the new head of the buffer STAILQ and 'datalen' + * contains the amount of data we will copy out at the end. The + * copyout is protected by the I/O lock only, as writers can only + * append to the buffer. We need to record the socket buffer state + * and do all length adjustments before dropping the socket buffer lock. */ - space = uio->uio_resid; - datalen = 0; - for (m = first, last = sb->uxst_fnrdy, lastlen = 0; - m != sb->uxst_fnrdy; + for (space = uio->uio_resid, m = next = first, part = NULL, datalen = 0; + space > 0 && m != sb->uxst_fnrdy && m->m_type == MT_DATA; m = STAILQ_NEXT(m, m_stailq)) { - if (m->m_type != MT_DATA) { - last = m; - lastlen = 0; - break; - } if (space >= m->m_len) { space -= m->m_len; datalen += m->m_len; @@ -1480,29 +1490,28 @@ restart: if (m->m_flags & M_EXT) mbcnt += m->m_ext.ext_size; if (m->m_flags & M_EOR) { - last = STAILQ_NEXT(m, m_stailq); - lastlen = 0; flags |= MSG_EOR; + next = STAILQ_NEXT(m, m_stailq); break; } } else { datalen += space; - last = m; - lastlen = space; + partlen = space; + if (!peek) { + m->m_len -= partlen; + m->m_data += partlen; + } + next = part = m; break; } + next = STAILQ_NEXT(m, m_stailq); } - UIPC_STREAM_SBCHECK(sb); if (!peek) { - if (last == NULL) + if (next == NULL) STAILQ_INIT(&sb->uxst_mbq); - else { - STAILQ_FIRST(&sb->uxst_mbq) = last; - MPASS(last->m_len > lastlen); - last->m_len -= lastlen; - last->m_data += lastlen; - } + else + STAILQ_FIRST(&sb->uxst_mbq) = next; MPASS(sb->sb_acc >= datalen); sb->sb_acc -= datalen; sb->sb_ccc -= datalen; @@ -1629,33 +1638,34 @@ restart: } } - for (m = first; m != last; m = next) { + for (m = first; datalen > 0; m = next) { + void *data; + u_int len; + next = STAILQ_NEXT(m, m_stailq); - error = uiomove(mtod(m, char *), m->m_len, uio); + if (m == part) { + data = peek ? + mtod(m, char *) : mtod(m, char *) - partlen; + len = partlen; + } else { + data = mtod(m, char *); + len = m->m_len; + } + error = uiomove(data, len, uio); if (__predict_false(error)) { - SOCK_IO_RECV_UNLOCK(so); if (!peek) - for (; m != last; m = next) { + for (; m != part && datalen > 0; m = next) { next = STAILQ_NEXT(m, m_stailq); + MPASS(datalen >= m->m_len); + datalen -= m->m_len; m_free(m); } - return (error); - } - if (!peek) - m_free(m); - } - if (last != NULL && lastlen > 0) { - if (!peek) { - MPASS(!(m->m_flags & M_PKTHDR)); - MPASS(last->m_data - M_START(last) >= lastlen); - error = uiomove(mtod(last, char *) - lastlen, - lastlen, uio); - } else - error = uiomove(mtod(last, char *), lastlen, uio); - if (__predict_false(error)) { SOCK_IO_RECV_UNLOCK(so); return (error); } + datalen -= len; + if (!peek && m != part) + m_free(m); } if (waitall && !(flags & MSG_EOR) && uio->uio_resid > 0) goto restart; @@ -3216,11 +3226,9 @@ unp_disconnect(struct unpcb *unp, struct unpcb *unp2) #endif LIST_REMOVE(unp, unp_reflink); UNP_REF_LIST_UNLOCK(); - if (so) { - SOCK_LOCK(so); - so->so_state &= ~SS_ISCONNECTED; - SOCK_UNLOCK(so); - } + SOCK_LOCK(so); + so->so_state &= ~SS_ISCONNECTED; + SOCK_UNLOCK(so); break; case SOCK_STREAM: @@ -4208,10 +4216,12 @@ unp_gc(__unused void *arg, int pending) struct socket *so; so = unref[i]->f_data; - CURVNET_SET(so->so_vnet); - socantrcvmore(so); - unp_dispose(so); - CURVNET_RESTORE(); + if (!SOLISTENING(so)) { + CURVNET_SET(so->so_vnet); + socantrcvmore(so); + unp_dispose(so); + CURVNET_RESTORE(); + } } /* @@ -4378,6 +4388,7 @@ static struct protosw streamproto = { .pr_connect2 = uipc_connect2, .pr_detach = uipc_detach, .pr_disconnect = uipc_disconnect, + .pr_fdclose = uipc_fdclose, .pr_listen = uipc_listen, .pr_peeraddr = uipc_peeraddr, .pr_send = uipc_sendfile, @@ -4408,6 +4419,7 @@ static struct protosw dgramproto = { .pr_connect2 = uipc_connect2, .pr_detach = uipc_detach, .pr_disconnect = uipc_disconnect, + .pr_fdclose = uipc_fdclose, .pr_peeraddr = uipc_peeraddr, .pr_sosend = uipc_sosend_dgram, .pr_sense = uipc_sense, @@ -4432,6 +4444,7 @@ static struct protosw seqpacketproto = { .pr_connect2 = uipc_connect2, .pr_detach = uipc_detach, .pr_disconnect = uipc_disconnect, + .pr_fdclose = uipc_fdclose, .pr_listen = uipc_listen, .pr_peeraddr = uipc_peeraddr, .pr_sense = uipc_sense, diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 02d4b8426757..2a790237d30e 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -2752,7 +2752,11 @@ struct __aiocb_private32 { #ifdef COMPAT_FREEBSD6 typedef struct oaiocb32 { int aio_fildes; /* File descriptor */ +#ifdef __amd64__ uint64_t aio_offset __packed; /* File offset for I/O */ +#else + uint64_t aio_offset; /* File offset for I/O */ +#endif uint32_t aio_buf; /* I/O buffer in process space */ uint32_t aio_nbytes; /* Number of bytes for I/O */ struct osigevent32 aio_sigevent; /* Signal to deliver */ @@ -2764,7 +2768,11 @@ typedef struct oaiocb32 { typedef struct aiocb32 { int32_t aio_fildes; /* File descriptor */ +#ifdef __amd64__ uint64_t aio_offset __packed; /* File offset for I/O */ +#else + uint64_t aio_offset; /* File offset for I/O*/ +#endif uint32_t aio_buf; /* I/O buffer in process space */ uint32_t aio_nbytes; /* Number of bytes for I/O */ int __spare__[2]; diff --git a/sys/kern/vfs_inotify.c b/sys/kern/vfs_inotify.c index e60d8426ee42..fd1ef39b13f7 100644 --- a/sys/kern/vfs_inotify.c +++ b/sys/kern/vfs_inotify.c @@ -381,7 +381,14 @@ inotify_unlink_watch_locked(struct inotify_softc *sc, struct inotify_watch *watc static void inotify_free_watch(struct inotify_watch *watch) { - vrele(watch->vp); + /* + * Formally, we don't need to lock the vnode here. However, if we + * don't, and vrele() releases the last reference, it's possible the + * vnode will be recycled while a different thread holds the vnode lock. + * Work around this bug by acquiring the lock here. + */ + (void)vn_lock(watch->vp, LK_EXCLUSIVE | LK_RETRY); + vput(watch->vp); free(watch, M_INOTIFY); } diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 2aded5d568cb..3e5bf6106ba3 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -383,6 +383,7 @@ SUBDIR= \ smbfs \ snp \ sound \ + ${_spe} \ ${_speaker} \ spi \ ${_splash} \ @@ -678,6 +679,10 @@ _irdma= irdma .endif .endif +.if ${MACHINE_CPUARCH} == "aarch64" +_spe= spe +.endif + .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" || \ ${MACHINE_CPUARCH} == "riscv" .if !empty(OPT_FDT) diff --git a/sys/modules/cxgbe/Makefile b/sys/modules/cxgbe/Makefile index c2ee71465789..a76017f58f8d 100644 --- a/sys/modules/cxgbe/Makefile +++ b/sys/modules/cxgbe/Makefile @@ -15,10 +15,12 @@ SUBDIR+= ${_tom} SUBDIR+= ${_iw_cxgbe} SUBDIR+= ${_cxgbei} SUBDIR+= ccr +SUBDIR+= ${_nvmf_che} .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "aarch64" _tom= tom _cxgbei= cxgbei +_nvmf_che= nvmf_che .if ${MK_OFED} != "no" || defined(ALL_MODULES) _iw_cxgbe= iw_cxgbe .endif diff --git a/sys/modules/cxgbe/nvmf_che/Makefile b/sys/modules/cxgbe/nvmf_che/Makefile new file mode 100644 index 000000000000..143904d61c71 --- /dev/null +++ b/sys/modules/cxgbe/nvmf_che/Makefile @@ -0,0 +1,16 @@ + +CXGBE = ${SRCTOP}/sys/dev/cxgbe +.PATH: ${CXGBE}/nvmf + +KMOD= nvmf_che + +SRCS= \ + nvmf_che.c \ + opt_inet.h \ + bus_if.h \ + device_if.h \ + pci_if.h \ + +CFLAGS+= -I${CXGBE} + +.include <bsd.kmod.mk> diff --git a/sys/modules/iwlwifi/Makefile b/sys/modules/iwlwifi/Makefile index 5d4830537a0b..6fe64a611900 100644 --- a/sys/modules/iwlwifi/Makefile +++ b/sys/modules/iwlwifi/Makefile @@ -91,7 +91,7 @@ CFLAGS+= -DCONFIG_IWLWIFI_DEVICE_TRACING=1 #CFLAGS+= -DCONFIG_THERMAL=1 #CFLAGS+= -DCONFIG_EFI=1 -# XXX-BZ how to do this just for pcie/drv.c (and gcc vs. clang)? -CFLAGS += -Wno-override-init -Wno-initializer-overrides +CWARNFLAGS.clang.drv.c+= -Wno-initializer-overrides +CWARNFLAGS.drv.c+= -Wno-override-init ${CWARNFLAGS.${COMPILER_TYPE}.${.IMPSRC:T}} .include <bsd.kmod.mk> diff --git a/sys/modules/spe/Makefile b/sys/modules/spe/Makefile new file mode 100644 index 000000000000..da4035620bbf --- /dev/null +++ b/sys/modules/spe/Makefile @@ -0,0 +1,24 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/arm64/spe + +KMOD = spe +SRCS = \ + arm_spe_dev.c \ + arm_spe_backend.c \ + arm_spe.h \ + arm_spe_dev.h + +SRCS+= opt_platform.h + +SRCS.DEV_ACPI= \ + arm_spe_acpi.c + +.if !empty(OPT_FDT) +SRCS+= \ + arm_spe_fdt.c +.endif + +EXPORT_SYMS= YES + +.include <bsd.kmod.mk> diff --git a/sys/modules/tpm/Makefile b/sys/modules/tpm/Makefile index d929649d40fe..e7a87a22d2ed 100644 --- a/sys/modules/tpm/Makefile +++ b/sys/modules/tpm/Makefile @@ -17,7 +17,7 @@ SRCS+= tpm20.c tpm_tis_core.c .if defined(${OPT_FDT}) SRCS+= tpm_spibus.c tpm_tis_spibus.c spibus_if.h .endif -.if ${MACHINE_ARCH:Namd64:Ni386:Narm64} == "" +.if ${MACHINE_ARCH:Namd64:Ni386:Naarch64} == "" SRCS+= acpi_if.h SRCS+= tpm_tis_acpi.c SRCS+= tpm_crb.c diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile index ec531ed646a7..7a4d0bb51376 100644 --- a/sys/modules/zfs/Makefile +++ b/sys/modules/zfs/Makefile @@ -475,8 +475,6 @@ CFLAGS.zstd_ldm.c= -U__BMI__ -fno-tree-vectorize ${NO_WBITWISE_INSTEAD_OF_LOGICA CFLAGS.zstd_opt.c= -U__BMI__ -fno-tree-vectorize ${NO_WBITWISE_INSTEAD_OF_LOGICAL} .if ${MACHINE_ARCH} == "aarch64" -__ZFS_ZSTD_AARCH64_FLAGS= -include ${SRCDIR}/zstd/include/aarch64_compat.h -CFLAGS.zstd.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} CFLAGS.entropy_common.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} CFLAGS.error_private.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} CFLAGS.fse_compress.c+= ${__ZFS_ZSTD_AARCH64_FLAGS} diff --git a/sys/modules/zfs/zfs_config.h b/sys/modules/zfs/zfs_config.h index 39b9229653af..f012910f58e7 100644 --- a/sys/modules/zfs/zfs_config.h +++ b/sys/modules/zfs/zfs_config.h @@ -856,7 +856,7 @@ /* #undef ZFS_DEVICE_MINOR */ /* Define the project alias string. */ -#define ZFS_META_ALIAS "zfs-2.4.99-129-FreeBSD_g0455150f1" +#define ZFS_META_ALIAS "zfs-2.4.99-220-FreeBSD_ge63d026b9" /* Define the project author. */ #define ZFS_META_AUTHOR "OpenZFS" @@ -886,7 +886,7 @@ #define ZFS_META_NAME "zfs" /* Define the project release. */ -#define ZFS_META_RELEASE "129-FreeBSD_g0455150f1" +#define ZFS_META_RELEASE "220-FreeBSD_ge63d026b9" /* Define the project version. */ #define ZFS_META_VERSION "2.4.99" diff --git a/sys/modules/zfs/zfs_gitrev.h b/sys/modules/zfs/zfs_gitrev.h index 87d2071cb0d2..f632d7d06ebe 100644 --- a/sys/modules/zfs/zfs_gitrev.h +++ b/sys/modules/zfs/zfs_gitrev.h @@ -1 +1 @@ -#define ZFS_META_GITREV "zfs-2.4.99-129-g0455150f1" +#define ZFS_META_GITREV "zfs-2.4.99-220-ge63d026b9" diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c index 9ebdd11f70f3..77b5a5d53a67 100644 --- a/sys/net/ieee8023ad_lacp.c +++ b/sys/net/ieee8023ad_lacp.c @@ -1264,6 +1264,8 @@ lacp_compose_key(struct lacp_port *lp) case IFM_400G_DR4: case IFM_400G_AUI8_AC: case IFM_400G_AUI8: + case IFM_400G_SR8: + case IFM_400G_CR8: key = IFM_400G_FR8; break; default: diff --git a/sys/net/if_media.h b/sys/net/if_media.h index a2cac00550ef..892b7d1e3e52 100644 --- a/sys/net/if_media.h +++ b/sys/net/if_media.h @@ -260,6 +260,8 @@ uint64_t ifmedia_baudrate(int); #define IFM_40G_LM4 IFM_X(119) /* 40GBase-LM4 */ #define IFM_100_BX IFM_X(120) /* 100Base-BX */ #define IFM_1000_BX IFM_X(121) /* 1000Base-BX */ +#define IFM_400G_SR8 IFM_X(122) /* 400GBase-SR8 */ +#define IFM_400G_CR8 IFM_X(123) /* 400GBase-CR8 */ /* * Please update ieee8023ad_lacp.c:lacp_compose_key() @@ -550,6 +552,8 @@ struct ifmedia_description { { IFM_400G_DR4, "400GBase-DR4" }, \ { IFM_400G_AUI8_AC, "400G-AUI8-AC" }, \ { IFM_400G_AUI8, "400G-AUI8" }, \ + { IFM_400G_SR8, "400GBase-SR8" }, \ + { IFM_400G_CR8, "400GBase-CR8" }, \ { 0, NULL }, \ } @@ -897,6 +901,8 @@ struct ifmedia_baudrate { { IFM_ETHER | IFM_400G_DR4, IF_Gbps(400ULL) }, \ { IFM_ETHER | IFM_400G_AUI8_AC, IF_Gbps(400ULL) }, \ { IFM_ETHER | IFM_400G_AUI8, IF_Gbps(400ULL) }, \ + { IFM_ETHER | IFM_400G_SR8, IF_Gbps(400ULL) }, \ + { IFM_ETHER | IFM_400G_CR8, IF_Gbps(400ULL) }, \ \ { IFM_IEEE80211 | IFM_IEEE80211_FH1, IF_Mbps(1) }, \ { IFM_IEEE80211 | IFM_IEEE80211_FH2, IF_Mbps(2) }, \ diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c index 1c18baac3417..674df4d17eb4 100644 --- a/sys/net/if_ovpn.c +++ b/sys/net/if_ovpn.c @@ -2691,7 +2691,7 @@ ovpn_clone_create(struct if_clone *ifc, char *name, size_t len, return (EEXIST); sc = malloc(sizeof(struct ovpn_softc), M_OVPN, M_WAITOK | M_ZERO); - sc->ifp = if_alloc(IFT_ENC); + sc->ifp = if_alloc(IFT_TUNNEL); rm_init_flags(&sc->lock, "if_ovpn_lock", RM_RECURSE); sc->refcount = 0; diff --git a/sys/net/iflib.c b/sys/net/iflib.c index d2625da19cd2..3181bdbcb849 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -3449,25 +3449,6 @@ iflib_remove_mbuf(iflib_txq_t txq) return (m); } -static inline caddr_t -calc_next_txd(iflib_txq_t txq, int cidx, uint8_t qid) -{ - qidx_t size; - int ntxd; - caddr_t start, end, cur, next; - - ntxd = txq->ift_size; - size = txq->ift_txd_size[qid]; - start = txq->ift_ifdi[qid].idi_vaddr; - - if (__predict_false(size == 0)) - return (start); - cur = start + size * cidx; - end = start + size * ntxd; - next = CACHE_PTR_NEXT(cur); - return (next < end ? next : start); -} - /* * Pad an mbuf to ensure a minimum ethernet frame size. * min_frame_size is the frame size (less CRC) to pad the mbuf to @@ -3521,37 +3502,22 @@ iflib_encap(iflib_txq_t txq, struct mbuf **m_headp) bus_dma_tag_t buf_tag; bus_dma_segment_t *segs; struct mbuf *m_head, **ifsd_m; - void *next_txd; bus_dmamap_t map; struct if_pkt_info pi; int remap = 0; - int err, nsegs, ndesc, max_segs, pidx, cidx, next, ntxd; + int err, nsegs, ndesc, max_segs, pidx; ctx = txq->ift_ctx; sctx = ctx->ifc_sctx; scctx = &ctx->ifc_softc_ctx; segs = txq->ift_segs; - ntxd = txq->ift_size; m_head = *m_headp; map = NULL; /* * If we're doing TSO the next descriptor to clean may be quite far ahead */ - cidx = txq->ift_cidx; pidx = txq->ift_pidx; - if (ctx->ifc_flags & IFC_PREFETCH) { - next = (cidx + CACHE_PTR_INCREMENT) & (ntxd - 1); - if (!(ctx->ifc_flags & IFLIB_HAS_TXCQ)) { - next_txd = calc_next_txd(txq, cidx, 0); - prefetch(next_txd); - } - - /* prefetch the next cache line of mbuf pointers and flags */ - prefetch(&txq->ift_sds.ifsd_m[next]); - prefetch(&txq->ift_sds.ifsd_map[next]); - next = (cidx + CACHE_LINE_SIZE) & (ntxd - 1); - } map = txq->ift_sds.ifsd_map[pidx]; ifsd_m = txq->ift_sds.ifsd_m; @@ -3737,24 +3703,16 @@ defrag_failed: static void iflib_tx_desc_free(iflib_txq_t txq, int n) { - uint32_t qsize, cidx, mask, gen; + uint32_t qsize, cidx, gen; struct mbuf *m, **ifsd_m; - bool do_prefetch; cidx = txq->ift_cidx; gen = txq->ift_gen; qsize = txq->ift_size; - mask = qsize - 1; ifsd_m = txq->ift_sds.ifsd_m; - do_prefetch = (txq->ift_ctx->ifc_flags & IFC_PREFETCH); while (n-- > 0) { - if (do_prefetch) { - prefetch(ifsd_m[(cidx + 3) & mask]); - prefetch(ifsd_m[(cidx + 4) & mask]); - } if ((m = ifsd_m[cidx]) != NULL) { - prefetch(&ifsd_m[(cidx + CACHE_PTR_INCREMENT) & mask]); if (m->m_pkthdr.csum_flags & CSUM_TSO) { bus_dmamap_sync(txq->ift_tso_buf_tag, txq->ift_sds.ifsd_tso_map[cidx], @@ -7230,9 +7188,13 @@ iflib_simple_transmit(if_t ifp, struct mbuf *m) ctx = if_getsoftc(ifp); - if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING) - return (EBUSY); + if (__predict_false((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0 + || !LINK_ACTIVE(ctx))) { + DBG_COUNTER_INC(tx_frees); + m_freem(m); + return (ENETDOWN); + } + txq = iflib_simple_select_queue(ctx, m); mtx_lock(&txq->ift_mtx); error = iflib_encap(txq, &m); diff --git a/sys/net/sff8436.h b/sys/net/sff8436.h index deed74c7cdb4..dbf5c69df832 100644 --- a/sys/net/sff8436.h +++ b/sys/net/sff8436.h @@ -151,7 +151,7 @@ enum { * OM2 fiber, units of 1 m */ SFF_8436_LEN_OM1 = 145, /* Link length supported for 1310 nm * 50um multi-mode fiber, units of 1m*/ - SFF_8436_LEN_ASM = 144, /* Link length of passive cable assembly + SFF_8436_LEN_ASM = 146, /* Link length of passive cable assembly * Length is specified as in the INF * 8074, units of 1m. 0 means this is * not value assembly. Value of 255 diff --git a/sys/net80211/ieee80211_crypto.h b/sys/net80211/ieee80211_crypto.h index 89b8b4f9daa4..48115da586b5 100644 --- a/sys/net80211/ieee80211_crypto.h +++ b/sys/net80211/ieee80211_crypto.h @@ -94,6 +94,7 @@ struct ieee80211_key { ieee80211_keyix wk_keyix; /* h/w key index */ ieee80211_keyix wk_rxkeyix; /* optional h/w rx key index */ + /* TODO: deprecate direct access to wk_key, wk_txmic, wk_rxmic */ uint8_t wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]; #define wk_txmic wk_key+IEEE80211_KEYBUF_SIZE+0 /* XXX can't () right */ #define wk_rxmic wk_key+IEEE80211_KEYBUF_SIZE+8 /* XXX can't () right */ @@ -300,5 +301,109 @@ void ieee80211_notify_michael_failure(struct ieee80211vap *, uint16_t ieee80211_crypto_init_aad(const struct ieee80211_frame *, uint8_t *, int); +/** + * @brief Return the key data. + * + * This returns a pointer to the key data. Note it does not + * guarantee the TX/RX MIC will be immediately after the key. + * Callers must use ieee80211_crypto_get_key_txmic_data() + * and ieee80211_crypto_get_key_rxmic_data() for that. + * + * Note: there's no locking; this needs to be called in + * a situation where the ieee80211_key won't disappear. + * + * @param k ieee80211_key + * @returns NULL if no key data is available, or a pointer + * to the key data. + */ +static inline const uint8_t * +ieee80211_crypto_get_key_data(const struct ieee80211_key *k) +{ + return (k->wk_key); +} + +/** + * @brief Return the key length in bytes. + * + * This doesn't include any TX/RX MIC (eg from TKIP). + * + * Note: there's no locking; this needs to be called in + * a situation where the ieee80211_key won't disappear. + * + * @param k ieee80211_key + * @returns the key length (without any MIC) in bytes + */ +static inline const uint16_t +ieee80211_crypto_get_key_len(const struct ieee80211_key *k) +{ + return (k->wk_keylen); +} + +/** + * @brief Return the TX MIC data. + * + * This returns a pointer to the TX MIC data. + * + * Note: there's no locking; this needs to be called in + * a situation where the ieee80211_key won't disappear. + * + * @param k ieee80211_key + * @returns NULL if no key data is available, or a pointer + * to the TX MIC data. + */ +static inline const uint8_t * +ieee80211_crypto_get_key_txmic_data(const struct ieee80211_key *k) +{ + return (k->wk_txmic); +} + +/** + * @brief Return the TX MIC length in bytes. + * + * Note: there's no locking; this needs to be called in + * a situation where the ieee80211_key won't disappear. + * + * @param k ieee80211_key + * @returns the TX MIC length in bytes + */ +static inline const uint16_t +ieee80211_crypto_get_key_txmic_len(const struct ieee80211_key *k) +{ + return (k->wk_cipher->ic_miclen); +} + +/** + * @brief Return the RX MIC data. + * + * This returns a pointer to the RX MIC data. + * + * Note: there's no locking; this needs to be called in + * a situation where the ieee80211_key won't disappear. + * + * @param k ieee80211_key + * @returns NULL if no key data is available, or a pointer + * to the RX MIC data. + */ +static inline const uint8_t * +ieee80211_crypto_get_key_rxmic_data(const struct ieee80211_key *k) +{ + return (k->wk_rxmic); +} + +/** + * @brief Return the RX MIC length in bytes. + * + * Note: there's no locking; this needs to be called in + * a situation where the ieee80211_key won't disappear. + * + * @param k ieee80211_key + * @returns the RX MIC length in bytes + */ +static inline const uint16_t +ieee80211_crypto_get_key_rxmic_len(const struct ieee80211_key *k) +{ + return (k->wk_cipher->ic_miclen); +} + #endif /* defined(__KERNEL__) || defined(_KERNEL) */ #endif /* _NET80211_IEEE80211_CRYPTO_H_ */ diff --git a/sys/netinet/ip_ecn.c b/sys/netinet/ip_ecn.c index 30d2c95ddbd7..2f700c43bbfa 100644 --- a/sys/netinet/ip_ecn.c +++ b/sys/netinet/ip_ecn.c @@ -92,7 +92,7 @@ * modify outer ECN (TOS) field on ingress operation (tunnel encapsulation). */ void -ip_ecn_ingress(int mode, u_int8_t *outer, const u_int8_t *inner) +ip_ecn_ingress(int mode, uint8_t *outer, const uint8_t *inner) { if (!outer || !inner) @@ -124,7 +124,7 @@ ip_ecn_ingress(int mode, u_int8_t *outer, const u_int8_t *inner) * the caller should drop the packet if the return value is 0. */ int -ip_ecn_egress(int mode, const u_int8_t *outer, u_int8_t *inner) +ip_ecn_egress(int mode, const uint8_t *outer, uint8_t *inner) { if (!outer || !inner) @@ -158,9 +158,9 @@ ip_ecn_egress(int mode, const u_int8_t *outer, u_int8_t *inner) #ifdef INET6 void -ip6_ecn_ingress(int mode, u_int32_t *outer, const u_int32_t *inner) +ip6_ecn_ingress(int mode, uint32_t *outer, const uint32_t *inner) { - u_int8_t outer8, inner8; + uint8_t outer8, inner8; if (!outer || !inner) panic("NULL pointer passed to ip6_ecn_ingress"); @@ -168,13 +168,13 @@ ip6_ecn_ingress(int mode, u_int32_t *outer, const u_int32_t *inner) inner8 = (ntohl(*inner) >> 20) & 0xff; ip_ecn_ingress(mode, &outer8, &inner8); *outer &= ~htonl(0xff << 20); - *outer |= htonl((u_int32_t)outer8 << 20); + *outer |= htonl((uint32_t)outer8 << 20); } int -ip6_ecn_egress(int mode, const u_int32_t *outer, u_int32_t *inner) +ip6_ecn_egress(int mode, const uint32_t *outer, uint32_t *inner) { - u_int8_t outer8, inner8, oinner8; + uint8_t outer8, inner8, oinner8; if (!outer || !inner) panic("NULL pointer passed to ip6_ecn_egress"); @@ -185,7 +185,7 @@ ip6_ecn_egress(int mode, const u_int32_t *outer, u_int32_t *inner) return (0); if (inner8 != oinner8) { *inner &= ~htonl(0xff << 20); - *inner |= htonl((u_int32_t)inner8 << 20); + *inner |= htonl((uint32_t)inner8 << 20); } return (1); } diff --git a/sys/netinet/ip_ecn.h b/sys/netinet/ip_ecn.h index 7390d812606f..6632418fc9ca 100644 --- a/sys/netinet/ip_ecn.h +++ b/sys/netinet/ip_ecn.h @@ -44,7 +44,7 @@ #define ECN_NOCARE (-1) /* no consideration to ECN */ #ifdef _KERNEL -extern void ip_ecn_ingress(int, u_int8_t *, const u_int8_t *); -extern int ip_ecn_egress(int, const u_int8_t *, u_int8_t *); +extern void ip_ecn_ingress(int, uint8_t *, const uint8_t *); +extern int ip_ecn_egress(int, const uint8_t *, uint8_t *); #endif #endif diff --git a/sys/netinet/tcp_hpts.h b/sys/netinet/tcp_hpts.h index 6b05f9701ac2..13527f7f9a4a 100644 --- a/sys/netinet/tcp_hpts.h +++ b/sys/netinet/tcp_hpts.h @@ -32,6 +32,10 @@ #define HPTS_MSEC_IN_SEC 1000 #define HPTS_USEC_IN_MSEC 1000 +/* + * The following functions should also be available + * to userspace as well. + */ static inline uint32_t tcp_tv_to_usec(const struct timeval *sv) { @@ -50,6 +54,13 @@ tcp_tv_to_lusec(const struct timeval *sv) return ((uint64_t)((sv->tv_sec * HPTS_USEC_IN_SEC) + sv->tv_usec)); } +static inline uint64_t +tcp_tv_to_lusectick(const struct timeval *sv) +{ + return ((uint64_t)((sv->tv_sec * HPTS_USEC_IN_SEC) + sv->tv_usec)); +} + + struct hpts_diag { uint32_t p_hpts_active; /* bbr->flex7 x */ uint32_t p_nxt_slot; /* bbr->flex1 x */ diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index fa7035771714..6c072e0fec38 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -535,6 +535,10 @@ syncache_timer(void *xsch) TCPSTAT_INC(tcps_sndtotal); TCPSTAT_INC(tcps_sc_retransmitted); } else { + /* + * Most likely we are memory constrained, so free + * resources. + */ syncache_drop(sc, sch); TCPSTAT_INC(tcps_sc_dropped); } @@ -734,7 +738,7 @@ syncache_unreach(struct in_conninfo *inc, tcp_seq th_seq, uint16_t port) goto done; /* - * If we've rertransmitted 3 times and this is our second error, + * If we've retransmitted 3 times and this is our second error, * we remove the entry. Otherwise, we allow it to continue on. * This prevents us from incorrectly nuking an entry during a * spurious network outage. @@ -1562,6 +1566,10 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, TCPSTAT_INC(tcps_sndacks); TCPSTAT_INC(tcps_sndtotal); } else { + /* + * Most likely we are memory constrained, so free + * resources. + */ syncache_drop(sc, sch); TCPSTAT_INC(tcps_sc_dropped); } @@ -1747,6 +1755,9 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, TCPSTAT_INC(tcps_sndacks); TCPSTAT_INC(tcps_sndtotal); } else { + /* + * Most likely we are memory constrained, so free resources. + */ if (sc != &scs) syncache_free(sc); TCPSTAT_INC(tcps_sc_dropped); diff --git a/sys/netinet6/ip6_ecn.h b/sys/netinet6/ip6_ecn.h index 45a28e9f419a..169e027dc265 100644 --- a/sys/netinet6/ip6_ecn.h +++ b/sys/netinet6/ip6_ecn.h @@ -37,6 +37,6 @@ */ #ifdef _KERNEL -extern void ip6_ecn_ingress(int, u_int32_t *, const u_int32_t *); -extern int ip6_ecn_egress(int, const u_int32_t *, u_int32_t *); +extern void ip6_ecn_ingress(int, uint32_t *, const uint32_t *); +extern int ip6_ecn_egress(int, const uint32_t *, uint32_t *); #endif diff --git a/sys/netlink/netlink_generic.c b/sys/netlink/netlink_generic.c index 00f47e60f013..d20ec4c7545f 100644 --- a/sys/netlink/netlink_generic.c +++ b/sys/netlink/netlink_generic.c @@ -366,8 +366,10 @@ genl_register_family(const char *family_name, size_t hdrsize, GENL_LOCK(); for (u_int i = 0; i < MAX_FAMILIES; i++) if (families[i].family_name != NULL && - strcmp(families[i].family_name, family_name) == 0) + strcmp(families[i].family_name, family_name) == 0) { + GENL_UNLOCK(); return (0); + } /* Microoptimization: index 0 is reserved for the control family. */ gf = NULL; diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c index d15d7760d7f1..c27b6bc274fb 100644 --- a/sys/netpfil/ipfw/ip_fw2.c +++ b/sys/netpfil/ipfw/ip_fw2.c @@ -2120,8 +2120,8 @@ do { \ pkey = &args->f_id.dst_ip6; else pkey = &args->f_id.src_ip6; - } else /* only for L3 */ - break; + } + break; case LOOKUP_DSCP: if (is_ipv4) key = ip->ip_tos >> 2; diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index a39f5fe58cd6..5e919e35b07b 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -11075,10 +11075,12 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0 break; action = pf_test_state(&s, &pd, &reason); if (action == PF_PASS || action == PF_AFRT) { - if (V_pfsync_update_state_ptr != NULL) - V_pfsync_update_state_ptr(s); - r = s->rule; - a = s->anchor; + if (s != NULL) { + if (V_pfsync_update_state_ptr != NULL) + V_pfsync_update_state_ptr(s); + r = s->rule; + a = s->anchor; + } } else if (s == NULL) { /* Validate remote SYN|ACK, re-create original SYN if * valid. */ @@ -11127,10 +11129,12 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0 default: action = pf_test_state(&s, &pd, &reason); if (action == PF_PASS || action == PF_AFRT) { - if (V_pfsync_update_state_ptr != NULL) - V_pfsync_update_state_ptr(s); - r = s->rule; - a = s->anchor; + if (s != NULL) { + if (V_pfsync_update_state_ptr != NULL) + V_pfsync_update_state_ptr(s); + r = s->rule; + a = s->anchor; + } } else if (s == NULL) { action = pf_test_rule(&r, &s, &pd, &a, &ruleset, &reason, inp, &match_rules); diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c index 7aeb8266ca8c..3510de3c6b3d 100644 --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -301,9 +301,8 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, struct pf_addr *naddr, bzero(&init_addr, sizeof(init_addr)); - if (udp_mapping) { - MPASS(*udp_mapping == NULL); - } + MPASS(udp_mapping == NULL || + *udp_mapping == NULL); /* * If we are UDP and have an existing mapping we can get source port @@ -354,16 +353,22 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, struct pf_addr *naddr, if (pd->ndport == htons(ICMP_ECHO)) { low = 1; high = 65535; - } else + } else { + MPASS(udp_mapping == NULL || + *udp_mapping == NULL); return (0); /* Don't try to modify non-echo ICMP */ + } } #ifdef INET6 if (pd->proto == IPPROTO_ICMPV6) { if (pd->ndport == htons(ICMP6_ECHO_REQUEST)) { low = 1; high = 65535; - } else + } else { + MPASS(udp_mapping == NULL || + *udp_mapping == NULL); return (0); /* Don't try to modify non-echo ICMP */ + } } #endif /* INET6 */ @@ -386,6 +391,8 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, struct pf_addr *naddr, */ if (pd->proto == IPPROTO_SCTP) { key.port[sidx] = pd->nsport; + MPASS(udp_mapping == NULL || + *udp_mapping == NULL); if (!pf_find_state_all_exists(&key, dir)) { *nport = pd->nsport; return (0); @@ -400,8 +407,18 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, struct pf_addr *naddr, */ key.port[sidx] = pd->nsport; if (!pf_find_state_all_exists(&key, dir)) { - *nport = pd->nsport; - return (0); + if (udp_mapping && *udp_mapping != NULL) { + (*udp_mapping)->endpoints[1].port = pd->nsport; + if (pf_udp_mapping_insert(*udp_mapping) == 0) { + *nport = pd->nsport; + return (0); + } + } else { + MPASS(udp_mapping == NULL || + *udp_mapping == NULL); + *nport = pd->nsport; + return (0); + } } } else if (low == high) { key.port[sidx] = htons(low); @@ -413,6 +430,8 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, struct pf_addr *naddr, return (0); } } else { + MPASS(udp_mapping == NULL || + *udp_mapping == NULL); *nport = htons(low); return (0); } @@ -440,6 +459,8 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, struct pf_addr *naddr, key.port[sidx] = htons(tmp); if (!pf_find_state_all_exists(&key, dir)) { *nport = htons(tmp); + MPASS(udp_mapping == NULL || + *udp_mapping == NULL); return (0); } } @@ -457,6 +478,8 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, struct pf_addr *naddr, } else { key.port[sidx] = htons(tmp); if (!pf_find_state_all_exists(&key, dir)) { + MPASS(udp_mapping == NULL || + *udp_mapping == NULL); *nport = htons(tmp); return (0); } @@ -473,13 +496,13 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_krule *r, struct pf_addr *naddr, */ if (pf_map_addr_sn(pd->naf, r, &pd->nsaddr, naddr, &(pd->naf), NULL, &init_addr, rpool, sn_type)) - return (1); + goto failed; break; case PF_POOL_NONE: case PF_POOL_SRCHASH: case PF_POOL_BITMASK: default: - return (1); + goto failed; } } while (! PF_AEQ(&init_addr, naddr, pd->naf) ); diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c index ae17b3289593..b1f74597aa42 100644 --- a/sys/powerpc/aim/mmu_oea.c +++ b/sys/powerpc/aim/mmu_oea.c @@ -1090,10 +1090,9 @@ moea_copy_pages(vm_page_t *ma, vm_offset_t a_offset, void moea_zero_page(vm_page_t m) { - vm_offset_t off, pa = VM_PAGE_TO_PHYS(m); + vm_offset_t pa = VM_PAGE_TO_PHYS(m); - for (off = 0; off < PAGE_SIZE; off += cacheline_size) - __asm __volatile("dcbz 0,%0" :: "r"(pa + off)); + bzero((void *)pa, PAGE_SIZE); } void diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 01bf4c7e90a8..62bbb6ddaf9b 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -1567,15 +1567,14 @@ void moea64_zero_page(vm_page_t m) { vm_paddr_t pa = VM_PAGE_TO_PHYS(m); - vm_offset_t va, off; + vm_offset_t va; mtx_lock(&moea64_scratchpage_mtx); moea64_set_scratchpage_pa(0, pa); va = moea64_scratchpage_va[0]; - for (off = 0; off < PAGE_SIZE; off += cacheline_size) - __asm __volatile("dcbz 0,%0" :: "r"(va + off)); + bzero((void *)va, PAGE_SIZE); mtx_unlock(&moea64_scratchpage_mtx); } @@ -1584,11 +1583,10 @@ void moea64_zero_page_dmap(vm_page_t m) { vm_paddr_t pa = VM_PAGE_TO_PHYS(m); - vm_offset_t va, off; + vm_offset_t va; va = PHYS_TO_DMAP(pa); - for (off = 0; off < PAGE_SIZE; off += cacheline_size) - __asm __volatile("dcbz 0,%0" :: "r"(va + off)); + bzero((void *)va, PAGE_SIZE); } vm_offset_t diff --git a/sys/powerpc/booke/pmap_32.c b/sys/powerpc/booke/pmap_32.c index efeefb6a91c5..5186a8852ed3 100644 --- a/sys/powerpc/booke/pmap_32.c +++ b/sys/powerpc/booke/pmap_32.c @@ -803,15 +803,14 @@ mmu_booke_zero_page_area(vm_page_t m, int off, int size) static void mmu_booke_zero_page(vm_page_t m) { - vm_offset_t off, va; + vm_offset_t va; va = zero_page_va; mtx_lock(&zero_page_mutex); mmu_booke_kenter(va, VM_PAGE_TO_PHYS(m)); - for (off = 0; off < PAGE_SIZE; off += cacheline_size) - __asm __volatile("dcbz 0,%0" :: "r"(va + off)); + bzero((void *)va, PAGE_SIZE); mmu_booke_kremove(va); diff --git a/sys/powerpc/booke/pmap_64.c b/sys/powerpc/booke/pmap_64.c index affa08ebee3f..5a414b9026c8 100644 --- a/sys/powerpc/booke/pmap_64.c +++ b/sys/powerpc/booke/pmap_64.c @@ -679,12 +679,11 @@ mmu_booke_zero_page_area(vm_page_t m, int off, int size) static void mmu_booke_zero_page(vm_page_t m) { - vm_offset_t off, va; + vm_offset_t va; va = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)); - for (off = 0; off < PAGE_SIZE; off += cacheline_size) - __asm __volatile("dcbz 0,%0" :: "r"(va + off)); + bzero((void *)va, PAGE_SIZE); } /* diff --git a/sys/powerpc/conf/GENERIC64 b/sys/powerpc/conf/GENERIC64 index 91c91d58d058..e215651e4c3d 100644 --- a/sys/powerpc/conf/GENERIC64 +++ b/sys/powerpc/conf/GENERIC64 @@ -207,6 +207,10 @@ device xz # lzma decompression # Note that 'bpf' is required for DHCP. device bpf # Berkeley packet filter +# random(4) +options RANDOM_ENABLE_KBD +options RANDOM_ENABLE_MOUSE + # USB support options USB_DEBUG # enable debug msgs device uhci # UHCI PCI->USB interface diff --git a/sys/powerpc/conf/GENERIC64LE b/sys/powerpc/conf/GENERIC64LE index 5fb9715de655..4759b70a3d1f 100644 --- a/sys/powerpc/conf/GENERIC64LE +++ b/sys/powerpc/conf/GENERIC64LE @@ -203,6 +203,10 @@ device xz # lzma decompression # Note that 'bpf' is required for DHCP. device bpf # Berkeley packet filter +# random(4) +options RANDOM_ENABLE_KBD +options RANDOM_ENABLE_MOUSE + # USB support options USB_DEBUG # enable debug msgs device uhci # UHCI PCI->USB interface diff --git a/sys/riscv/conf/GENERIC b/sys/riscv/conf/GENERIC index a8500fe80019..36e3fcd41970 100644 --- a/sys/riscv/conf/GENERIC +++ b/sys/riscv/conf/GENERIC @@ -197,6 +197,10 @@ device mmcsd # MMC/SD flash cards # Note that 'bpf' is required for DHCP. device bpf # Berkeley packet filter +# random(4) +options RANDOM_ENABLE_KBD +options RANDOM_ENABLE_MOUSE + # Flattened Device Tree options FDT @@ -204,6 +208,10 @@ options FDT device iicbus # Bus support, required for iicoc below. device iicoc # OpenCores I2C controller support +# random(4) +device tpm # Trusted Platform Module +options RANDOM_ENABLE_TPM # enable entropy from TPM 2.0 + # Include SoC specific configuration include "std.allwinner" include "std.cvitek" diff --git a/sys/sys/_types.h b/sys/sys/_types.h index fe345b43d5eb..6b70b8dc6e32 100644 --- a/sys/sys/_types.h +++ b/sys/sys/_types.h @@ -183,7 +183,7 @@ typedef struct { __attribute__((__aligned__(__alignof__(long long)))); #ifndef _STANDALONE long double __max_align2 - __attribute__((__aligned__(__alignof__(long long)))); + __attribute__((__aligned__(__alignof__(long double)))); #endif } __max_align_t; diff --git a/sys/sys/efi-edk2.h b/sys/sys/efi-edk2.h new file mode 100644 index 000000000000..b27b26bd613c --- /dev/null +++ b/sys/sys/efi-edk2.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2017-2025 Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _SYS_EFI_EDK2_H_ +#define _SYS_EFI_EDK2_H_ + +/* + * Defines to adjust the types that EDK2 uses for FreeBSD so we can + * use the code and headers mostly unchanged. The headers are imported + * all into one directory to avoid case issues with filenames and + * included. The actual code is heavily modified since it has too many + * annoying dependencies that are difficult to satisfy. + */ + +#include <stdlib.h> +#include <stdint.h> + +typedef int8_t INT8; +typedef int16_t INT16; +typedef int32_t INT32; +typedef int64_t INT64; +typedef intptr_t INTN; +typedef uint8_t UINT8; +typedef uint16_t UINT16; +typedef uint32_t UINT32; +typedef uint64_t UINT64; +typedef uintptr_t UINTN; +//typedef uintptr_t EFI_PHYSICAL_ADDRESS; +//typedef uint32_t EFI_IPv4_ADDRESS; +//typedef uint8_t EFI_MAC_ADDRESS[6]; +//typedef uint8_t EFI_IPv6_ADDRESS[16]; +typedef uint8_t CHAR8; +typedef uint16_t CHAR16; +typedef UINT8 BOOLEAN; +typedef void VOID; +//typedef uuid_t GUID; +//typedef uuid_t EFI_GUID; + +/* We can't actually call this stuff, so snip out API syntactic sugar */ +#define INTERFACE_DECL(x) struct x +#ifdef _STANDALONE +#if defined(__amd64__) +#define EFIAPI __attribute__((ms_abi)) +#endif +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options + #ifdef _MSC_EXTENSIONS + #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler + #else + #define EFIAPI // Substitute expresion to force C calling convention + #endif +#endif +#else +#define EFIAPI +#endif +#define IN +#define OUT +#define CONST const +#define OPTIONAL +//#define TRUE 1 +//#define FALSE 0 + +/* + * EDK2 has fine definitions for these, so let it define them. + */ +#undef NULL +#undef EFI_PAGE_SIZE +#undef EFI_PAGE_MASK + +/* + * Note: the EDK2 code assumed #pragma packed works and PACKED is a + * workaround for some old toolchain issues for EDK2 that aren't + * relevent to FreeBSD. + */ +#define PACKED + +/* + * For userland and the kernel, we're not compiling for the UEFI boot time + * (which use ms abi conventions on amd64), tell EDK2 to define VA_START + * correctly. For the boot loader, we can't do that, so don't. + */ +#ifndef _STANDALONE +#define NO_MSABI_VA_FUNCS 1 +#endif + +/* + * Finally, we need to define the processor we are in EDK2 terms. + */ +#if defined(__i386__) +#define MDE_CPU_IA32 +#elif defined(__amd64__) +#define MDE_CPU_X64 +#elif defined(__arm__) +#define MDE_CPU_ARM +#elif defined(__aarch64__) +#define MDE_CPU_AARCH64 +#elif defined(__riscv) +#define MDE_CPU_RISCV64 +#endif +/* FreeBSD doesn't have/use MDE_CPU_EBC or MDE_CPU_IPF (ia64) */ + +#if __SIZEOF_LONG__ == 4 +#define MAX_BIT 0x80000000 +#else +#define MAX_BIT 0x8000000000000000 +#endif + +/* + * Sometimes EFI is included after sys/param.h, and that causes a collision. We + * get a collision the other way too, so when including both, you have to + * include sys/param.h first. + */ +#undef MAX +#undef MIN + +#endif /* _SYS_EFI_EDK2_H_ */ diff --git a/sys/sys/efi-freebsd.h b/sys/sys/efi-freebsd.h new file mode 100644 index 000000000000..f3fd04a2196c --- /dev/null +++ b/sys/sys/efi-freebsd.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#ifndef _SYS_EFI_FREEBSD_H_ +#define _SYS_EFI_FREEBSD_H_ + +/* + * Minimal defines to allow FreeBSD to use the same type names as EDK2, + * but without depending on all of EDK2's types. + */ +#include <sys/_null.h> + +#endif /* _SYS_EFI_FREEBSD_H_ */ diff --git a/sys/sys/efi.h b/sys/sys/efi.h index f82c733898b4..b76ca4918f81 100644 --- a/sys/sys/efi.h +++ b/sys/sys/efi.h @@ -27,8 +27,9 @@ #ifndef _SYS_EFI_H_ #define _SYS_EFI_H_ -#include <sys/uuid.h> +#include <sys/types.h> #include <machine/efi.h> +#include <sys/efi-freebsd.h> #define EFI_PAGE_SHIFT 12 #define EFI_PAGE_SIZE (1 << EFI_PAGE_SHIFT) diff --git a/sys/sys/efi_map.h b/sys/sys/efi_map.h index 8b458cd08b00..d2206056b1f8 100644 --- a/sys/sys/efi_map.h +++ b/sys/sys/efi_map.h @@ -7,6 +7,8 @@ #ifndef _SYS_EFI_MAP_H_ #define _SYS_EFI_MAP_H_ +#ifdef _KERNEL + #include <sys/efi.h> #include <machine/metadata.h> @@ -21,4 +23,6 @@ void efi_map_add_entries(struct efi_map_header *efihdr); void efi_map_exclude_entries(struct efi_map_header *efihdr); void efi_map_print_entries(struct efi_map_header *efihdr); +#endif + #endif /* !_SYS_EFI_MAP_H_ */ diff --git a/sys/sys/extattr.h b/sys/sys/extattr.h index a16ef238656f..4aabb4af667b 100644 --- a/sys/sys/extattr.h +++ b/sys/sys/extattr.h @@ -71,8 +71,6 @@ int extattr_check_cred(struct vnode *vp, int attrnamespace, #else #include <sys/cdefs.h> -struct iovec; - __BEGIN_DECLS int extattrctl(const char *_path, int _cmd, const char *_filename, int _attrnamespace, const char *_attrname); diff --git a/sys/sys/file.h b/sys/sys/file.h index e0195c7c6c2a..89dba2b1c3f8 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -116,6 +116,7 @@ typedef int fo_kqfilter_t(struct file *fp, struct knote *kn); typedef int fo_stat_t(struct file *fp, struct stat *sb, struct ucred *active_cred); typedef int fo_close_t(struct file *fp, struct thread *td); +typedef void fo_fdclose_t(struct file *fp, int fd, struct thread *td); typedef int fo_chmod_t(struct file *fp, mode_t mode, struct ucred *active_cred, struct thread *td); typedef int fo_chown_t(struct file *fp, uid_t uid, gid_t gid, @@ -153,6 +154,7 @@ struct fileops { fo_kqfilter_t *fo_kqfilter; fo_stat_t *fo_stat; fo_close_t *fo_close; + fo_fdclose_t *fo_fdclose; fo_chmod_t *fo_chmod; fo_chown_t *fo_chown; fo_sendfile_t *fo_sendfile; diff --git a/sys/sys/mqueue.h b/sys/sys/mqueue.h index 50f6681ce218..211f09d57427 100644 --- a/sys/sys/mqueue.h +++ b/sys/sys/mqueue.h @@ -37,9 +37,4 @@ struct mq_attr { long __reserved[4]; /* Ignored for input, zeroed for output */ }; -#ifdef _KERNEL -struct thread; -struct file; -extern void (*mq_fdclose)(struct thread *td, int fd, struct file *fp); -#endif #endif diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index 7fb8dfdc7208..392ff7cf678e 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -94,6 +94,7 @@ typedef int pr_sopoll_t(struct socket *, int, struct thread *); typedef int pr_kqfilter_t(struct socket *, struct knote *); typedef void pr_sosetlabel_t(struct socket *); typedef void pr_close_t(struct socket *); +typedef void pr_fdclose_t(struct socket *); typedef int pr_bindat_t(int, struct socket *, struct sockaddr *, struct thread *); typedef int pr_connectat_t(int, struct socket *, struct sockaddr *, @@ -120,8 +121,8 @@ struct protosw { pr_detach_t *pr_detach; /* destruction: sofree() */ pr_connect_t *pr_connect; /* connect(2) */ pr_disconnect_t *pr_disconnect; /* sodisconnect() */ - pr_close_t *pr_close; /* close(2) */ - pr_shutdown_t *pr_shutdown; /* shutdown(2) */ + pr_close_t *pr_close; /* soclose(), socket refcount is 0 */ + pr_fdclose_t *pr_fdclose; /* close(2) */ pr_rcvd_t *pr_rcvd; /* soreceive_generic() if PR_WANTRCVD */ pr_aio_queue_t *pr_aio_queue; /* aio(9) */ /* Cache line #3 */ @@ -142,7 +143,9 @@ struct protosw { pr_sosetlabel_t *pr_sosetlabel; /* MAC, XXXGL: remove */ pr_setsbopt_t *pr_setsbopt; /* Socket buffer ioctls */ pr_chmod_t *pr_chmod; /* fchmod(2) */ +/* Cache line #5 */ pr_kqfilter_t *pr_kqfilter; /* kevent(2) */ + pr_shutdown_t *pr_shutdown; /* shutdown(2) */ }; #endif /* defined(_KERNEL) || defined(_WANT_PROTOSW) */ #ifdef _KERNEL diff --git a/sys/sys/random.h b/sys/sys/random.h index 803c07bbdfba..d801b04e5686 100644 --- a/sys/sys/random.h +++ b/sys/sys/random.h @@ -89,8 +89,7 @@ enum random_entropy_source { RANDOM_ENVIRONMENTAL_END = RANDOM_RANDOMDEV, /* Fast hardware random-number sources from here on. */ RANDOM_PURE_START, - RANDOM_PURE_SAFE = RANDOM_PURE_START, - RANDOM_PURE_GLXSB, + RANDOM_PURE_TPM = RANDOM_PURE_START, RANDOM_PURE_RDRAND, RANDOM_PURE_RDSEED, RANDOM_PURE_NEHEMIAH, @@ -99,11 +98,12 @@ enum random_entropy_source { RANDOM_PURE_BROADCOM, RANDOM_PURE_CCP, RANDOM_PURE_DARN, - RANDOM_PURE_TPM, RANDOM_PURE_VMGENID, RANDOM_PURE_QUALCOMM, RANDOM_PURE_ARMV8, RANDOM_PURE_ARM_TRNG, + RANDOM_PURE_SAFE, + RANDOM_PURE_GLXSB, ENTROPYSOURCE }; _Static_assert(ENTROPYSOURCE <= 32, diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index 8f106150e193..350e4073604e 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -219,13 +219,13 @@ int kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat); int kern_kldunload(struct thread *td, int fileid, int flags); int kern_kmq_notify(struct thread *, int, struct sigevent *); int kern_kmq_open(struct thread *, const char *, int, mode_t, - const struct mq_attr *); + const struct mq_attr *); int kern_kmq_setattr(struct thread *, int, const struct mq_attr *, - struct mq_attr *); + struct mq_attr *); int kern_kmq_timedreceive(struct thread *, int, char *, - size_t, unsigned int *, const struct timespec *); + size_t, unsigned int *, const struct timespec *); int kern_kmq_timedsend(struct thread *td, int, const char *, - size_t, unsigned int, const struct timespec *); + size_t, unsigned int, const struct timespec *); int kern_linkat(struct thread *td, int fd1, int fd2, const char *path1, const char *path2, enum uio_seg segflg, int flag); int kern_listen(struct thread *td, int s, int backlog); @@ -411,7 +411,7 @@ int kern_kexec_load(struct thread *td, u_long entry, struct freebsd11_dirent; -int freebsd11_kern_getdirentries(struct thread *td, int fd, char *ubuf, u_int - count, long *basep, void (*func)(struct freebsd11_dirent *)); +int freebsd11_kern_getdirentries(struct thread *td, int fd, char *ubuf, + u_int count, long *basep, void (*func)(struct freebsd11_dirent *)); #endif /* !_SYS_SYSCALLSUBR_H_ */ diff --git a/sys/tools/gdb/acttrace.py b/sys/tools/gdb/acttrace.py index fdd18a4833cd..da79fda59da1 100644 --- a/sys/tools/gdb/acttrace.py +++ b/sys/tools/gdb/acttrace.py @@ -11,11 +11,13 @@ import gdb from freebsd import * from pcpu import * + class acttrace(gdb.Command): """ Print the stack trace of all threads that were on-CPU at the time of the panic. """ + def __init__(self): super(acttrace, self).__init__("acttrace", gdb.COMMAND_USER) diff --git a/sys/tools/gdb/freebsd.py b/sys/tools/gdb/freebsd.py index 81ea60373348..f88eef876c7f 100644 --- a/sys/tools/gdb/freebsd.py +++ b/sys/tools/gdb/freebsd.py @@ -6,6 +6,7 @@ import gdb + def symval(name): sym = gdb.lookup_global_symbol(name) if sym is None: @@ -72,4 +73,6 @@ def tdfind(tid, pid=-1): tdfind.cached_threads[int(ntid)] = td if ntid == tid: return td + + tdfind.cached_threads = dict() diff --git a/sys/tools/gdb/pcpu.py b/sys/tools/gdb/pcpu.py index 94c451e6eca5..08ae81e5121e 100644 --- a/sys/tools/gdb/pcpu.py +++ b/sys/tools/gdb/pcpu.py @@ -7,6 +7,7 @@ import gdb from freebsd import * + class pcpu(gdb.Function): """ A function to look up PCPU and DPCPU fields by name. @@ -16,6 +17,7 @@ class pcpu(gdb.Function): omitted, and the currently selected thread is on-CPU, that CPU is used, otherwise an error is raised. """ + def __init__(self): super(pcpu, self).__init__("PCPU") @@ -73,5 +75,6 @@ class pcpu(gdb.Function): obj = gdb.Value(pcpu_base + pcpu_entry_addr - start + base) return obj.cast(pcpu_entry.type.pointer()).dereference() + # Register with gdb. pcpu() diff --git a/sys/tools/gdb/vnet.py b/sys/tools/gdb/vnet.py index 5f416b2a515a..6175a5d6f551 100644 --- a/sys/tools/gdb/vnet.py +++ b/sys/tools/gdb/vnet.py @@ -5,9 +5,9 @@ # import gdb -import traceback from freebsd import * + class vnet(gdb.Function): """ A function to look up VNET variables by name. @@ -18,6 +18,7 @@ class vnet(gdb.Function): pointer to a struct vnet (e.g., vnet0 or allprison.tqh_first->pr_vnet) or a string naming a jail. """ + def __init__(self): super(vnet, self).__init__("V") diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index 1fd6518cf4ed..d0e005088745 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -164,5 +164,8 @@ vm_addr_ok(vm_paddr_t pa, vm_paddr_t size, u_long alignment, return (vm_addr_align_ok(pa, alignment) && vm_addr_bound_ok(pa, size, boundary)); } + +extern bool vm_check_pg_zero; + #endif /* _KERNEL */ #endif /* !_VM_EXTERN_H_ */ diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 2e150b368d71..3bf16778d987 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -85,6 +85,8 @@ #include <sys/refcount.h> #include <sys/resourcevar.h> #include <sys/rwlock.h> +#include <sys/sched.h> +#include <sys/sf_buf.h> #include <sys/signalvar.h> #include <sys/sysctl.h> #include <sys/sysent.h> @@ -1220,6 +1222,24 @@ vm_fault_zerofill(struct faultstate *fs) if ((fs->m->flags & PG_ZERO) == 0) { pmap_zero_page(fs->m); } else { +#ifdef INVARIANTS + if (vm_check_pg_zero) { + struct sf_buf *sf; + unsigned long *p; + int i; + + sched_pin(); + sf = sf_buf_alloc(fs->m, SFB_CPUPRIVATE); + p = (unsigned long *)sf_buf_kva(sf); + for (i = 0; i < PAGE_SIZE / sizeof(*p); i++, p++) { + KASSERT(*p == 0, + ("zerocheck failed page %p PG_ZERO %d %jx", + fs->m, i, (uintmax_t)*p)); + } + sf_buf_free(sf); + sched_unpin(); + } +#endif VM_CNT_INC(v_ozfod); } VM_CNT_INC(v_zfod); diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 16878604fa11..b39d665f9e0f 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -84,6 +84,7 @@ #include <sys/sleepqueue.h> #include <sys/sbuf.h> #include <sys/sched.h> +#include <sys/sf_buf.h> #include <sys/smp.h> #include <sys/sysctl.h> #include <sys/vmmeter.h> @@ -145,6 +146,13 @@ SYSCTL_ULONG(_vm_stats_page, OID_AUTO, nofreeq_size, CTLFLAG_RD, &nofreeq_size, 0, "Size of the nofree queue"); +#ifdef INVARIANTS +bool vm_check_pg_zero = false; +SYSCTL_BOOL(_debug, OID_AUTO, vm_check_pg_zero, CTLFLAG_RWTUN, + &vm_check_pg_zero, 0, + "verify content of freed zero-filled pages"); +#endif + /* * bogus page -- for I/O to/from partially complete buffers, * or for paging into sparsely invalid regions. @@ -4050,14 +4058,24 @@ vm_page_free_prep(vm_page_t m) */ atomic_thread_fence_acq(); -#if defined(DIAGNOSTIC) && defined(PHYS_TO_DMAP) - if (PMAP_HAS_DMAP && (m->flags & PG_ZERO) != 0) { - uint64_t *p; +#ifdef INVARIANTS + if (vm_check_pg_zero && (m->flags & PG_ZERO) != 0) { + struct sf_buf *sf; + unsigned long *p; int i; - p = (uint64_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)); - for (i = 0; i < PAGE_SIZE / sizeof(uint64_t); i++, p++) - KASSERT(*p == 0, ("vm_page_free_prep %p PG_ZERO %d %jx", - m, i, (uintmax_t)*p)); + + sched_pin(); + sf = sf_buf_alloc(m, SFB_CPUPRIVATE | SFB_NOWAIT); + if (sf != NULL) { + p = (unsigned long *)sf_buf_kva(sf); + for (i = 0; i < PAGE_SIZE / sizeof(*p); i++, p++) { + KASSERT(*p == 0, + ("zerocheck failed page %p PG_ZERO %d %jx", + m, i, (uintmax_t)*p)); + } + sf_buf_free(sf); + } + sched_unpin(); } #endif if ((m->oflags & VPO_UNMANAGED) == 0) { diff --git a/sys/x86/conf/NOTES b/sys/x86/conf/NOTES index fadaf90d508f..643105096be2 100644 --- a/sys/x86/conf/NOTES +++ b/sys/x86/conf/NOTES @@ -444,7 +444,9 @@ device gve # Google Virtual NIC (gVNIC) device igc # Intel I225 2.5G Ethernet device ipw # Intel 2100 wireless NICs. device iwi # Intel 2200BG/2225BG/2915ABG wireless NICs. +device iwm # Intel IEEE 802.11ac wireless NICs. device iwn # Intel 4965/1000/5000/6000 wireless NICs. +device iwx # Intel IEEE 802.11ax wireless NICs. device mthca # Mellanox HCA InfiniBand device mlx4 # Shared code module between IB and Ethernet device mlx4ib # Mellanox ConnectX HCA InfiniBand |
