Q100FreeDesign Verification
Predict and safely read a build-tag prefix service
Question
Complete the C predictor and firmware transaction for a service returning the longest common byte prefix of one to eight bounded build tags. Nonnull inputs identify readable 8x16-byte and eight-length arrays. They remain stable while the driver captures them before its first platform call; later synchronized changes are permitted because the transaction uses its private copy. out identifies 17 writable bytes and out_len a separate writable byte disjoint from out. Input and output storage remains valid for the call; concurrent unsynchronized C access is not permitted. Use the supplied typed platform bindings, not raw MMIO or a generic C fence.
Implementation scaffold
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
typedef enum {
LCP_OK,LCP_BAD_ARG,LCP_HW_ERROR,LCP_TIMEOUT,LCP_ABORTED,LCP_RESET
} lcp_status_t;
typedef enum { LCP_IO_OK,LCP_IO_BUSY,LCP_IO_FAULT,LCP_IO_ABORTED,LCP_IO_RESET } lcp_io_t;
typedef uint64_t lcp_token_t;
enum { LCP_BUSY=1u<<0,LCP_DONE=1u<<1,LCP_ERR=1u<<2,LCP_TIMEOUT_TICKS=100000u };
// Supplied serialized platform lease and device-I/O operations.
extern lcp_io_t lcp_begin(lcp_token_t *token);
extern lcp_io_t lcp_write_tag_byte(lcp_token_t token,uint8_t tag,uint8_t byte,uint8_t value);
extern lcp_io_t lcp_write_tag_len(lcp_token_t token,uint8_t tag,uint8_t length);
extern lcp_io_t lcp_write_count(lcp_token_t token,uint8_t count);
extern lcp_io_t lcp_start(lcp_token_t token);
extern lcp_io_t lcp_status(lcp_token_t token,uint32_t *status);
extern lcp_io_t lcp_result_len(lcp_token_t token,uint8_t *length);
extern lcp_io_t lcp_result_byte(lcp_token_t token,uint8_t *value);
extern uint32_t platform_ticks(void);
// Commit checks the lease and sticky cancellation/error under the platform lock,
// then copies exactly length+1 bytes and length before releasing the lease.
// On any failure it changes neither caller output; the caller then calls lcp_end.
extern lcp_io_t lcp_commit(lcp_token_t token,const char result[17],uint8_t length,
char out[17],uint8_t *out_len);
// Quiesce the owned generation, optionally issue ABORT, and release its lease.
extern void lcp_end(lcp_token_t token,bool abort_request);
static lcp_status_t lcp_map_io(lcp_io_t io) {
// TODO: map reset/cancellation distinctly and other I/O failures to HW_ERROR.
}
static uint8_t lcp_reference(const char *tags,const uint8_t lengths[8],
uint8_t count,char result[16]) {
// TODO: predict the bounded byte prefix from the captured contiguous 8x16 image.
}
lcp_status_t lcp_run(const char tag[8][16],const uint8_t len[8],
uint8_t count,char out[17],uint8_t *out_len) {
// TODO: validate/capture, program/START, poll/read/verify and guarded commit.
}
Trace one case
tags=["asic-fyi","asic-flow","asic"], lengths=[8,9,4]RESULT_LEN=4; firmware output="asic\0"All three byte strings match through index 3 and the shortest tag ends there; only firmware appends the terminator.
Requirements
- Before any platform/MMIO operation, reject null pointers, count outside 1..8 or any active length above 16, preserving both caller outputs. Capture active lengths/bytes by value before programming; inactive rows and unused bytes do not participate. Bytes, including embedded zero, are compared by their explicit lengths rather than strlen.
- Acquire one exclusive platform lease; lcp_begin succeeds only for an idle, quiescent service. Write each active tag byte in increasing row/byte order, write that row length, then COUNT and START. The supplied START operation performs device-specific publication, clears stale terminal state and snapshots the programmed inputs. Every operation checks the same lease and detects sticky reset, cancellation or access failure; no later operation may touch an invalidated generation.
- Poll with ERR priority over simultaneous DONE. After each clean nonterminal poll, time out when unsigned elapsed ticks are at least LCP_TIMEOUT_TICKS=100000. ERR takes priority over DONE, and a clean DONE takes priority over the elapsed-time comparison on that poll, even if the platform call returned after the threshold. This is an observed poll policy, not a promise that every platform call completes before an absolute terminal timestamp. Read RESULT_LEN once, reject values above 16 before data access, then read exactly that many advancing RESULT_DATA bytes on the successful path. Stop immediately if an operation fails. Append a firmware-only terminator, and compare length and every byte against the captured predictor.
- On hardware error, timeout, reset or abort, preserve all 17 output bytes and out_len, quiesce/release the lease and map the status distinctly. lcp_end(token,true) performs the required generation-safe ABORT/cleanup. Only the supplied lcp_commit may publish outputs: it serializes a final lease/reset/cancel/error check with copying length+1 bytes and out_len, releases on success, and changes neither output on failure. Platform calls are bounded, tick subtraction is valid because elapsed intervals stay below 2^32, and reset/cancel/error are sticky for the lease. Other transactions and reset delivery cannot interleave inside the commit critical section.
