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. Leave both caller outputs unchanged on rejection. Before programming, copy active lengths and bytes by value; ignore inactive rows and unused bytes. Compare bytes using their explicit lengths, including embedded zero, 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, followed by that row's length. After the rows, write 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.
- On each poll, give ERR priority over simultaneous DONE. After a clean nonterminal poll, time out when unsigned elapsed ticks are at least LCP_TIMEOUT_TICKS=100000. A clean DONE takes priority over the elapsed-time comparison on that poll, even if the platform call returned after the threshold. This policy uses the observed poll result; it does not promise that every platform call completes before an absolute terminal timestamp. Read RESULT_LEN once and reject values above 16 before accessing data. On success, read exactly that many advancing RESULT_DATA bytes. Stop immediately if any operation fails. Append a firmware-only terminator, then compare the length and every byte against the captured predictor.
- On hardware error, timeout, reset, or abort, preserve all 17 output bytes and out_len. Quiesce and release the lease, and map each status distinctly. lcp_end(token,true) performs the required generation-safe ABORT/cleanup. Publish outputs only through the supplied lcp_commit. It serializes a final lease/reset/cancel/error check with copying length+1 bytes and out_len. It releases the lease on success and changes neither output on failure. Platform calls are bounded. Tick subtraction is valid because elapsed intervals stay below 2^32. Reset/cancel/error remain sticky for the lease. Other transactions and reset delivery cannot interleave inside the commit critical section.
