+
+ static void copy_data(u8 *dest, u8 *vaddr, size_t bufsize,
+ ParamInfoBlock *dpib, ParamInfoBlock *spib,
+ u32 fmask, u32 flags)
+ {
+ size_t copied = 0;
+
+ for (uint i = 0; i < spib->num_segments; i++) {
+ if ((spib->segments[i].flags & fmask) != flags)
+ continue;
+
+ size_t len = round_up(spib->segments[i].len, 3);
+
+ if (len + copied > bufsize || len + copied < copied)
+ throw_idl(InvalidArgument, 0, countarray("copy_data: bad size"));
+
+ dpib->segments[i].ptr = vaddr;
+ dpib->segments[i].len = len;
+ dpib->segments[i].reserved = 0;
+ Arch::copyin(spib->segments[i].ptr, dest, len);
+
+ copied += len;
+ dest += len;
+ vaddr += len;
+ }
+ }
+
+ typedef void (*KernEntry)(ParamInfoBlock *pib);
+
+ struct KernObject : public Object {
+ KernEntry entry;
+ };
+
+ typedef Util::RadixTree<KernObject, ID, 6> KIDTable;
+ KIDTable *kernobjs;
+
+ void copy_ids_to_kern(ParamInfoBlock *dpib, ParamInfoBlock *spib,
+ IDSpace *ids)
+ {
+ dpib->objlist_len = spib->objlist_len;
+
+ for (uint i = 0; i < spib->objlist_len; i++) {
+ Object *obj = ids->lookup(spib->objlist[i]);
+
+ if (!obj)
+ throw_idl(InvalidReference, i, nullarray);
+
+ dpib->objlist[i] = reinterpret_cast<uintptr_t>(obj);
+ }
+ }