QUAC 100 Register Map

QV-REF-REGS Rev 1.0 — January 2026 Reference

Complete hardware register reference for the QUAC 100 Quantum-Resistant Universal Accelerator Card as accessed by the QuantaVirt hypervisor PQC driver. Covers BAR0 MMIO registers, command/response ring layout, interrupt configuration, DMA engine, NTT accelerator, QRNG, performance counters, and firmware update interface.

Register Map Overview #

The QUAC 100 exposes a single 64 KB BAR0 MMIO region. All registers are 32-bit unless noted. Multi-word registers use little-endian byte ordering. The driver must not access reserved fields — writes are ignored, reads return zero.

Offset RangeSizeRegionDescription
0x0000–0x00FF256 BDevice ControlGlobal device status, version, capability, reset
0x0100–0x01FF256 BCommand RingCommand submission ring base, head, tail, size
0x0200–0x02FF256 BResponse RingCompletion ring base, head, tail, size
0x0300–0x03FF256 BInterruptsMSI-X control, interrupt mask, cause, coalescing
0x0400–0x04FF256 BDMA EngineDMA control, scatter-gather, address translation
0x0500–0x05FF256 BNTT EngineNTT accelerator control, twiddle factor base, status
0x0600–0x06FF256 BQRNGQuantum RNG control, entropy pool, health status
0x0700–0x07FF256 BPerformance CountersOperation counts, latency histograms, throughput
0x0800–0x08FF256 BFirmware UpdateFirmware flash control, bank select, progress
0x0900–0xFFFF~62 KBReservedReserved for future use — do not access

PCIe Configuration Space #

RegisterOffsetValueDescription
Vendor ID0x000x1DB7Dyber, Inc.
Device ID0x020x0100QUAC 100
Revision ID0x080x01Revision A1
Class Code0x090x10 80 00Encryption controller (class 0x10, sub 0x80)
Subsystem Vendor ID0x2C0x1DB7Dyber, Inc.
Subsystem Device ID0x2E0x0100QUAC 100 (standard SKU)
BAR00x1064-bit MMIO64 KB memory-mapped I/O, prefetchable
MSI-X Capability0x40+16 vectorsMSI-X table in BAR0 + 0xFE00
PCIe Link—Gen4 x8Max 15.75 GT/s per lane, ~126 Gbps aggregate

BAR0 Memory Layout #

BAR0 Base Address (e.g. 0xfb000000)
┌─────────────────────────────────────────┐
│  0x0000  Device Control (256 B)         │
│  0x0100  Command Ring (256 B)           │
│  0x0200  Response Ring (256 B)          │
│  0x0300  Interrupt Control (256 B)      │
│  0x0400  DMA Engine (256 B)             │
│  0x0500  NTT Engine (256 B)             │
│  0x0600  QRNG (256 B)                   │
│  0x0700  Performance Counters (256 B)   │
│  0x0800  Firmware Update (256 B)        │
│  0x0900  Reserved (~62 KB)              │
│  0xFE00  MSI-X Table (256 B)            │
│  0xFF00  MSI-X PBA (256 B)              │
└─────────────────────────────────────────┘
Total: 64 KB (0x10000)

Device Control Registers (0x0000–0x00FF) #

OffsetNameR/WResetBitsDescription
0x0000DEV_IDRO0x1DB70100[31:16] Vendor, [15:0] DeviceDevice identification
0x0004DEV_REVRO0x00010000[31:16] HW rev, [15:0] FW major.minorHardware and firmware revision
0x0008DEV_STATUSRO0x00000001[0] ready, [1] error, [2] fw_update, [3] overtemp, [7:4] engine_countGlobal device status
0x000CDEV_CTRLRW0x00000000[0] enable, [1] soft_reset, [2] halt, [3] flushDevice control — set bit 0 to enable operations
0x0010DEV_CAPROvaries[0] ML-KEM, [1] ML-DSA, [2] SLH-DSA, [3] AES-GCM, [4] ChaCha20, [5] QRNG, [6] NTT, [7] DMA_SG, [8] FW_DUAL_BANKCapability flags — which crypto engines are present
0x0014DEV_CAP2ROvaries[3:0] max_cmd_ring_log2, [7:4] max_resp_ring_log2, [15:8] max_dma_size_log2, [23:16] ntt_max_degree_log2Extended capability parameters
0x0018FW_VERSIONROvaries[31:24] major, [23:16] minor, [15:0] patchFirmware version (e.g. 1.0.0 = 0x01000000)
0x001CFW_BUILDROvaries[31:0] build timestampFirmware build date as Unix epoch (seconds)
0x0020SERIAL_LOROunique[31:0]Device serial number (low 32 bits)
0x0024SERIAL_HIROunique[31:0]Device serial number (high 32 bits)
0x0028TEMPROvaries[15:0] die temp × 100 °C, [31:16] throttle thresholdDie temperature in centidegrees (e.g. 4500 = 45.00 °C)
0x002CPOWERROvaries[15:0] current mW, [31:16] peak mWPower consumption in milliwatts
0x0030UPTIMERO0[31:0]Seconds since last reset
0x0034ERR_COUNTRW1C0[31:0]Total error count — write 1 to clear
0x0038ERR_LASTRO0[15:0] error code, [31:16] engine_idLast error code and which engine raised it
Reset Sequence: Set DEV_CTRL[1] (soft_reset). Poll DEV_STATUS[0] (ready) — device returns to ready state within 50 ms. All rings and counters are cleared on reset.

Command Ring Registers (0x0100–0x01FF) #

The command ring is a circular buffer in host memory where the driver submits cryptographic operation descriptors. The QUAC 100 fetches commands via DMA.

OffsetNameR/WResetDescription
0x0100CMD_RING_BASE_LORW0Command ring physical base address [31:0] — must be 4 KB aligned
0x0104CMD_RING_BASE_HIRW0Command ring physical base address [63:32]
0x0108CMD_RING_SIZERW0[15:0] number of entries (must be power of 2, max 4096)
0x010CCMD_RING_HEADRO0[15:0] hardware consumer head index — device advances after fetching
0x0110CMD_RING_TAILRW0[15:0] software producer tail index — driver writes to submit
0x0114CMD_RING_CTRLRW0[0] enable, [1] pause, [2] abort_all
0x0118CMD_RING_STATUSRO0[0] active, [1] empty, [2] full, [3] error, [15:8] pending_count
0x011CCMD_RING_DBWO—Doorbell — write any value to notify device of new commands
/* Command submission flow */
1. Write command descriptor to ring[tail]
2. Advance tail: CMD_RING_TAIL = (tail + 1) % ring_size
3. Ring doorbell: write to CMD_RING_DB
4. Device fetches descriptor via DMA, advances HEAD
5. On completion, device writes response to response ring

Response Ring Registers (0x0200–0x02FF) #

OffsetNameR/WResetDescription
0x0200RESP_RING_BASE_LORW0Response ring physical base address [31:0] — 4 KB aligned
0x0204RESP_RING_BASE_HIRW0Response ring physical base address [63:32]
0x0208RESP_RING_SIZERW0[15:0] number of entries (power of 2, max 4096)
0x020CRESP_RING_HEADRW0[15:0] software consumer head — driver advances after processing
0x0210RESP_RING_TAILRO0[15:0] hardware producer tail — device advances after writing completion
0x0214RESP_RING_CTRLRW0[0] enable, [7:4] coalesce_count (batch N responses before interrupt)
0x0218RESP_RING_STATUSRO0[0] active, [1] empty, [2] full, [15:8] pending_count

Interrupt Registers (0x0300–0x03FF) #

OffsetNameR/WResetDescription
0x0300INT_STATUSRW1C0Interrupt cause — write 1 to acknowledge
0x0304INT_MASKRW0xFFFFFFFFInterrupt mask — 1 = masked (disabled), 0 = enabled
0x0308INT_FORCEWO—Force interrupt for testing — write bit position
0x030CINT_COALESCERW0x00010001[15:0] max_usec delay, [31:16] max_count before interrupt

Interrupt Bit Definitions (INT_STATUS / INT_MASK)

BitNameDescription
[0]RESP_READYOne or more responses available in response ring
[1]CMD_ERRORCommand processing error occurred
[2]DMA_COMPLETEDMA transfer completed
[3]DMA_ERRORDMA transfer error (bad address, IOMMU fault)
[4]QRNG_READYQRNG entropy pool has data available
[5]QRNG_HEALTHQRNG health test warning or failure
[6]TEMP_WARNDie temperature exceeded warning threshold
[7]TEMP_CRITDie temperature exceeded critical threshold — throttling active
[8]FW_UPDATE_DONEFirmware flash operation completed
[9]FW_UPDATE_ERRFirmware flash operation failed
[10]LINK_DOWNPCIe link state changed (for hot-plug support)
[11]WATCHDOGHardware watchdog expired (command took too long)
[15:12]Reserved—

DMA Engine Registers (0x0400–0x04FF) #

OffsetNameR/WResetDescription
0x0400DMA_CTRLRW0[0] enable, [1] sg_mode (scatter-gather), [3:2] burst_size (00=64B, 01=128B, 10=256B, 11=512B)
0x0404DMA_STATUSRO0[0] idle, [1] active, [2] error, [7:4] channel_count
0x0408DMA_SRC_LORW0Source address [31:0] (for single-descriptor DMA)
0x040CDMA_SRC_HIRW0Source address [63:32]
0x0410DMA_DST_LORW0Destination address [31:0]
0x0414DMA_DST_HIRW0Destination address [63:32]
0x0418DMA_LENRW0[31:0] transfer length in bytes (max 16 MB)
0x041CDMA_SG_BASE_LORW0Scatter-gather list base [31:0] — when sg_mode=1
0x0420DMA_SG_BASE_HIRW0Scatter-gather list base [63:32]
0x0424DMA_SG_COUNTRW0[15:0] number of SG entries (max 256)
0x0428DMA_XFER_COUNTRO0[31:0] total bytes transferred since last reset

NTT Engine Registers (0x0500–0x05FF) #

The Number Theoretic Transform engine implements the Radix-32 NTT used by ML-KEM and ML-DSA. It operates at 1 GHz on polynomial coefficients in the configured ring.

OffsetNameR/WResetDescription
0x0500NTT_CTRLRW0[0] start, [1] inverse, [2] auto_reduce, [4:3] radix (00=2, 01=4, 10=8, 11=32)
0x0504NTT_STATUSRO0[0] idle, [1] busy, [2] done, [3] error
0x0508NTT_MODULUSRW0x00000D01[31:0] polynomial modulus q (default 3329 for ML-KEM)
0x050CNTT_DEGREERW0x00000100[15:0] polynomial degree N (default 256)
0x0510NTT_TWIDDLE_BASE_LORW0Twiddle factor table physical address [31:0]
0x0514NTT_TWIDDLE_BASE_HIRW0Twiddle factor table physical address [63:32]
0x0518NTT_INPUT_BASE_LORW0Input polynomial coefficients physical address [31:0]
0x051CNTT_INPUT_BASE_HIRW0Input polynomial coefficients physical address [63:32]
0x0520NTT_OUTPUT_BASE_LORW0Output polynomial coefficients physical address [31:0]
0x0524NTT_OUTPUT_BASE_HIRW0Output polynomial coefficients physical address [63:32]
0x0528NTT_CYCLE_COUNTRO0[31:0] clock cycles for last NTT operation
Radix-32 NTT: The default radix-32 mode processes 32 butterfly operations per clock cycle at 1 GHz, completing a 256-point NTT in approximately 64 cycles (~64 ns). For ML-DSA (q = 8380417), set NTT_MODULUS = 0x007FE001.

QRNG Registers (0x0600–0x06FF) #

OffsetNameR/WResetDescription
0x0600QRNG_CTRLRW0[0] enable, [1] conditioning (SHAKE-256), [2] continuous_test
0x0604QRNG_STATUSRO0[0] ready (entropy available), [1] healthy, [2] test_fail, [3] depleted
0x0608QRNG_DATAROrandom[31:0] 32 bits of conditioned quantum random data — read drains pool
0x060CQRNG_POOL_LEVELROvaries[15:0] entropy pool level in bytes (max 4096)
0x0610QRNG_THROUGHPUTROvaries[31:0] raw entropy generation rate in bits/sec
0x0614QRNG_HEALTH_STATUSRO0[0] repetition_pass, [1] adaptive_pass, [2] chi_squared_pass, [3] startup_pass
0x0618QRNG_HEALTH_FAIL_CTRW1C0[31:0] cumulative health test failure count
0x061CQRNG_MIN_ENTROPYROvaries[15:0] estimated min-entropy per bit × 1000 (e.g. 997 = 0.997)

Performance Counters (0x0700–0x07FF) #

OffsetNameWidthDescription
0x0700CTR_MLKEM_KEYGEN64-bitML-KEM KeyGen operations completed
0x0708CTR_MLKEM_ENCAPS64-bitML-KEM Encapsulation operations completed
0x0710CTR_MLKEM_DECAPS64-bitML-KEM Decapsulation operations completed
0x0718CTR_MLDSA_KEYGEN64-bitML-DSA KeyGen operations completed
0x0720CTR_MLDSA_SIGN64-bitML-DSA Sign operations completed
0x0728CTR_MLDSA_VERIFY64-bitML-DSA Verify operations completed
0x0730CTR_AEAD_ENCRYPT64-bitAEAD encrypt operations completed
0x0738CTR_AEAD_DECRYPT64-bitAEAD decrypt operations completed
0x0740CTR_NTT_FWD64-bitForward NTT operations completed
0x0748CTR_NTT_INV64-bitInverse NTT operations completed
0x0750CTR_QRNG_BYTES64-bitTotal QRNG bytes generated
0x0758CTR_DMA_BYTES64-bitTotal DMA bytes transferred
0x0760CTR_CMD_TOTAL64-bitTotal commands submitted
0x0768CTR_CMD_ERRORS64-bitTotal command errors
0x0770CTR_AVG_LATENCY_NS32-bitRolling average command latency in nanoseconds
0x0774CTR_MAX_LATENCY_NS32-bitMaximum observed command latency in nanoseconds
0x0778CTR_THROUGHPUT_OPS32-bitOperations per second (1-second rolling window)
0x07FCCTR_RESETWO—Write 0xDEADBEEF to reset all counters

Firmware Update Registers (0x0800–0x08FF) #

OffsetNameR/WDescription
0x0800FW_UPDATE_CTRLRW[0] begin_update, [1] commit, [2] abort, [3] bank_select (0=A, 1=B)
0x0804FW_UPDATE_STATUSRO[0] idle, [1] erasing, [2] writing, [3] verifying, [4] complete, [5] error
0x0808FW_UPDATE_ADDRRWFlash write address offset (within firmware bank)
0x080CFW_UPDATE_DATAWO32-bit write data — write sequentially to program flash
0x0810FW_UPDATE_SIZERWTotal firmware image size in bytes
0x0814FW_UPDATE_CRCRWExpected CRC-32 of firmware image
0x0818FW_UPDATE_PROGRESSRO[15:0] bytes written, [31:16] total bytes — for progress reporting
0x081CFW_ACTIVE_BANKRO[0] active bank (0=A, 1=B)
Dual-Bank Safety: The QUAC 100 has dual firmware banks. Updates write to the inactive bank. If verification fails or the new firmware doesn't boot, the device automatically reverts to the previous working bank on the next power cycle.

Command Descriptor Format #

Each command descriptor is 64 bytes (16 DWORDs) written to the command ring.

DWORDByte OffsetFieldDescription
00x00opcode [15:0], flags [31:16]Operation code (see table below) and flags
10x04cmd_id [31:0]Driver-assigned command ID — echoed in response
20x08param_set [7:0], key_id [31:8]Algorithm parameter set (0=512, 1=768, 2=1024) and key handle
30x0Cinput_len [31:0]Input data length in bytes
4–50x10input_addr [63:0]Physical address of input data buffer
6–70x18output_addr [63:0]Physical address of output data buffer
8–90x20key_addr [63:0]Physical address of key material (if not using key_id)
100x28output_max_len [31:0]Maximum output buffer size
11–150x2CReservedMust be zero

Command Opcodes

OpcodeNameInputOutput
0x0001MLKEM_KEYGEN32B seedpk + sk
0x0002MLKEM_ENCAPSpk + 32B randomnessct + ss
0x0003MLKEM_DECAPSsk + ctss
0x0011MLDSA_KEYGEN32B seedpk + sk
0x0012MLDSA_SIGNsk + messagesig
0x0013MLDSA_VERIFYpk + message + sig1B result (0/1)
0x0021AES_GCM_ENCRYPTkey + nonce + plaintext + AADciphertext + tag
0x0022AES_GCM_DECRYPTkey + nonce + ciphertext + tag + AADplaintext (or error)
0x0023CHACHA_ENCRYPTkey + nonce + plaintext + AADciphertext + tag
0x0024CHACHA_DECRYPTkey + nonce + ciphertext + tag + AADplaintext (or error)
0x0031NTT_FORWARDpolynomial coefficientsNTT-domain coefficients
0x0032NTT_INVERSENTT-domain coefficientspolynomial coefficients
0x0041QRNG_READ—N random bytes
0x00F0SELF_TEST—test results
0x00FFNOP——

Response Descriptor Format #

Each response descriptor is 32 bytes (8 DWORDs) written by the device to the response ring.

DWORDByte OffsetFieldDescription
00x00status [15:0], flags [31:16]Response status code and flags
10x04cmd_id [31:0]Echoed command ID from original command
20x08output_len [31:0]Actual output data length in bytes
30x0Clatency_ns [31:0]Command processing time in nanoseconds
4–70x10ReservedMust be zero

Hardware Response Codes #

CodeNameDescription
0x0000QUAC100_RESP_SUCCESSOperation completed successfully
0x0001QUAC100_RESP_INVALID_OPCODEUnknown or unsupported opcode
0x0002QUAC100_RESP_INVALID_PARAMInvalid parameter set or key handle
0x0003QUAC100_RESP_INVALID_LENInput or output length out of range
0x0004QUAC100_RESP_DMA_ERRORDMA read/write failed — check IOMMU and address mapping
0x0005QUAC100_RESP_CRYPTO_FAILCryptographic operation failed (e.g. decryption tag mismatch)
0x0006QUAC100_RESP_KEY_NOT_FOUNDReferenced key_id not in hardware keystore
0x0007QUAC100_RESP_BUSYEngine busy — retry later
0x0008QUAC100_RESP_TIMEOUTOperation timed out (hardware watchdog)
0x0009QUAC100_RESP_SELF_TEST_FAILHardware self-test detected internal error
0x000AQUAC100_RESP_QRNG_DEPLETEDQRNG entropy pool empty — wait and retry
0x000BQUAC100_RESP_QRNG_HEALTH_FAILQRNG health test failed — entropy source degraded
0x000CQUAC100_RESP_OVERTEMPOperation rejected due to thermal throttling
0x000DQUAC100_RESP_FW_ERRORFirmware internal error — collect diagnostics and report
0x00FFQUAC100_RESP_UNKNOWNUnknown error — should not occur; indicates hardware fault