12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- /*
- * Marshall sysvars into a buffer to be sent to the FPGA.
- */
- #include "common.h"
- #include "sysvars.h"
- #include <stdio.h>
- /*
- * Marshall a set or subset of sysvar entries into a buffer
- * for use by another CPU (for which the address to said buffer
- * might differ from what this CPU uses.)
- *
- * Returns the number of entries successfully marshalled.
- * extaddr refers to the external address of the buffer, for which
- * internal pointers should be adjusted.
- *
- * On return, *buflen is adjusted to the number of bytes actually used.
- */
- size_t sysvar_marshall(enum sysvar_enum first, size_t count,
- void *buf, size_t *buflen, uintptr_t extaddr)
- {
- static const size_t align_mask = 3;
- size_t bytes = count * sizeof(sysvar_t);
- if (*buflen < bytes) {
- /* Only space for a partial result */
- count = *buflen / sizeof(sysvar_t);
- bytes = count * sizeof(sysvar_t);
- }
- sysvar_t *vp = (sysvar_t *)buf;
- size_t bufsize = *buflen;
- const sysvar_t *v = &sysvar_val[first];
- const sysvar_type_t *t = &sysvar_types[first];
- size_t ok = 0;
- intptr_t adjust = extaddr - (uintptr_t)buf;
- while (count--) {
- sysvar_t vv = *v++;
- sysvar_type_t type = *t++;
- if (type && type->datasize && vv.v_ptr) {
- size_t dsize = type->datasize(vv);
- size_t adj_bytes = (bytes + align_mask) & ~align_mask;
- if (adj_bytes + dsize > bufsize)
- break; /* Insufficient buffer space */
- char *dp = (char *)buf + adj_bytes;
- memcpy(dp, vv.v_ptr, dsize);
- vv.v_ptr = dp + adjust;
- bytes = adj_bytes + dsize;
- }
- *vp++ = vv;
- ok++;
- }
- *buflen = bytes;
- return ok;
- }
|