Message ID | 1434616965-5157-6-git-send-email-patrik.jakobsson@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, 18 Jun 2015 10:42:45 +0200 Patrik Jakobsson <patrik.jakobsson@linux.intel.com> wrote: > This patch adds many of the DRM and KMS ioctls. The rest can be added as > needed. > > * drm.c: Decode DRM_IOCTL_VERSION > * drm.c: Decode DRM_IOCTL_GET_UNIQUE > * drm.c: Decode DRM_IOCTL_GET_MAGIC > * drm.c: Decode DRM_IOCTL_WAIT_VBLANK > * drm.c: Decode DRM_IOCTL_MODE_GETRESOURCES > * drm.c: Decode DRM_IOCTL_MODE_GETCRTC > * drm.c: Decode DRM_IOCTL_MODE_SETCRTC > * drm.c: Decode DRM_IOCTL_MODE_CURSOR > * drm.c: Decode DRM_IOCTL_MODE_CURSOR2 > * drm.c: Decode DRM_IOCTL_MODE_GETGAMMA > * drm.c: Decode DRM_IOCTL_MODE_SETGAMMA > * drm.c: Decode DRM_IOCTL_MODE_GETENCODER > * drm.c: Decode DRM_IOCTL_MODE_GETCONNECTOR > * drm.c: Decode DRM_IOCTL_MODE_GETPROPERTY > * drm.c: Decode DRM_IOCTL_MODE_SETPROPERTY > * drm.c: Decode DRM_IOCTL_MODE_GETPROPBLOB > * drm.c: Decode DRM_IOCTL_MODE_GETFB > * drm.c: Decode DRM_IOCTL_MODE_ADDFB > * drm.c: Decode DRM_IOCTL_MODE_RMFB > * drm.c: Decode DRM_IOCTL_MODE_PAGE_FLIP > * drm.c: Decode DRM_IOCTL_DIRTYFB > * drm.c: Decode DRM_IOCTL_CREATE_DUMB > * drm.c: Decode DRM_IOCTL_MAP_DUMB > * drm.c: Decode DRM_IOCTL_DESTROY_DUMB > * drm.c: Decode DRM_IOCTL_GEM_CLOSE > > Signed-off-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> > --- > drm.c | 510 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 510 insertions(+) > > diff --git a/drm.c b/drm.c > index 8e3f7d1..2e6d763 100644 > --- a/drm.c > +++ b/drm.c > @@ -104,6 +104,463 @@ int drm_decode_number(struct tcb *tcp, unsigned int arg) > return 0; > } > > +static int drm_version(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_version ver; > + > + if (umove(tcp, arg, &ver)) > + return 0; > + The umove() should be done only on exiting and if the ioctl succeded ? Same thing for most of the read only ioctl. > + if (exiting(tcp)) { > + tprintf(", {version_major=%d, version_minor=%d, version_patchlevel=%d, " > + "name_len=%lu, name=", ver.version_major, > + ver.version_minor, ver.version_patchlevel, > + ver.name_len); > + printstr(tcp, (long)ver.name, ver.name_len); > + tprintf(", date_len=%lu, date=", ver.date_len); > + printstr(tcp, (long)ver.date, ver.date_len); > + tprintf(", desc_len=%lu, desc=", ver.desc_len); > + printstr(tcp, (long)ver.desc, ver.desc_len); > + tprints("}"); > + } > + > + return 1; > +} > + > +static int drm_get_unique(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_unique unique; > + > + if (umove(tcp, arg, &unique)) > + return 0; > + > + if (exiting(tcp)) { > + tprintf(", {unique_len=%lu, unique=}", unique.unique_len); There is an extra '}' > + printstr(tcp, (long)unique.unique, unique.unique_len); > + tprints("}"); > + } > + > + return 1; > +} > + > +static int drm_get_magic(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_auth auth; > + > + if (umove(tcp, arg, &auth)) > + return 0; > + > + if (exiting(tcp)) > + tprintf(", {magic=%u}", auth.magic); > + > + return 1; > +} > + > +static int drm_wait_vblank(struct tcb *tcp, const unsigned int code, long arg) > +{ > + union drm_wait_vblank vblank; > + > + if (umove(tcp, arg, &vblank)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {request={type=%u, sequence=%u, signal=%lu}", > + vblank.request.type, vblank.request.sequence, > + vblank.request.signal); > + } else if (exiting(tcp)) { > + tprintf(", reply={type=%u, sequence=%u, tval_sec=%ld, tval_usec=%ld}}", > + vblank.reply.type, vblank.reply.sequence, > + vblank.reply.tval_sec, vblank.reply.tval_usec); > + } > + > + return 1; > +} > + > +static int drm_mode_get_resources(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_card_res res; > + > + if (umove(tcp, arg, &res)) > + return 0; > + > + if (exiting(tcp)) { > + tprintf(", {fb_id_ptr=%p, crtc_id_ptr=%p, connector_id_ptr=%p, " > + "encoder_id_ptr=%p, count_fbs=%u, count_crtcs=%u, " > + "count_connectors=%u, count_encoders=%u, min_width=%u, " > + "max_width=%u, min_height=%u, max_height=%u}", > + (void *)res.fb_id_ptr, (void *)res.crtc_id_ptr, > + (void *)res.connector_id_ptr, (void *)res.encoder_id_ptr, > + res.count_fbs, res.count_crtcs, res.count_connectors, > + res.count_encoders, res.min_width, res.max_width, > + res.min_height, res.max_height); > + } > + > + return 1; > +} > + > +static void drm_mode_print_modeinfo(struct drm_mode_modeinfo *info) > +{ > + tprintf("clock=%u, hdisplay=%hu, hsync_start=%hu, hsync_end=%hu, " > + "htotal=%hu, hskew=%hu, vdisplay=%hu, vsync_start=%hu, " > + "vsync_end=%hu, vtotal=%hu, vscan=%hu, vrefresh=%u, " > + "flags=0x%x, type=%u, name=%s", info->clock, info->hdisplay, > + info->hsync_start, info->hsync_end, info->htotal, info->hskew, > + info->vdisplay, info->vsync_start, info->vsync_end, > + info->vtotal, info->vscan, info->vrefresh, info->flags, > + info->type, info->name); > +} > + > +static int drm_mode_get_crtc(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_crtc crtc; > + > + if (umove(tcp, arg, &crtc)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {crtc_id=%u", crtc.crtc_id); > + } else if (exiting(tcp)) { > + tprintf(", set_connectors_ptr=%p, count_connectors=%u, " > + "fb_id=%u, x=%u, y=%u, gamma_size=%u, mode_valid=%u, " > + "mode={", (void *)crtc.set_connectors_ptr, > + crtc.count_connectors, crtc.fb_id, crtc.x, crtc.y, > + crtc.gamma_size, crtc.mode_valid); > + > + drm_mode_print_modeinfo(&crtc.mode); > + tprintf("}}"); > + } > + > + return 1; > +} > + > +static int drm_mode_set_crtc(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_crtc crtc; > + > + if (umove(tcp, arg, &crtc)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {set_connectors_ptr=%p, count_connectors=%u, " > + "crtc_id=%u, fb_id=%u, x=%u, y=%u, gamma_size=%u, " > + "mode_valid=%u, mode={", (void *)crtc.set_connectors_ptr, > + crtc.count_connectors, crtc.crtc_id, crtc.fb_id, crtc.x, > + crtc.y, crtc.gamma_size, crtc.mode_valid); > + > + drm_mode_print_modeinfo(&crtc.mode); > + tprintf("}}"); > + } > + > + return 1; > +} > + > +static int drm_mode_cursor(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_cursor cursor; > + > + if (umove(tcp, arg, &cursor)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {flags=0x%x, crtc_id=%u, x=%d, y=%d, width=%u, " > + "height=%u, handle=%u}", cursor.flags, cursor.crtc_id, > + cursor.x, cursor.y, cursor.width, cursor.height, > + cursor.handle); > + } > + > + return 1; > +} > + > +static int drm_mode_cursor2(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_cursor2 cursor; > + > + if (umove(tcp, arg, &cursor)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {flags=0x%x, crtc_id=%u, x=%d, y=%d, width=%u, " > + "height=%u, handle=%u, hot_x=%d, hot_y=%d}", > + cursor.flags, cursor.crtc_id, cursor.x, cursor.y, > + cursor.width, cursor.height, cursor.handle, > + cursor.hot_x, cursor.hot_y); > + } > + > + return 1; > +} > + > +static int drm_mode_get_gamma(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_crtc_lut lut; > + > + if (umove(tcp, arg, &lut)) > + return 0; > + > + if (entering(tcp)) { > + /* We don't print the entire table, just the pointers */ > + tprintf(", {crtc_id=%u, gamma_size=%u, red=%p, green=%p, " > + "blue=%p}", lut.crtc_id, lut.gamma_size, > + (void *)lut.red, (void *)lut.green, (void *)lut.blue); > + } > + > + return 1; > +} > + > +static int drm_mode_set_gamma(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_crtc_lut lut; > + > + if (umove(tcp, arg, &lut)) > + return 0; > + > + if (entering(tcp)) { > + /* We don't print the entire table, just the rgb pointers */ > + tprintf(", {crtc_id=%u, gamma_size=%u, red=%p, green=%p, " > + "blue=%p}", lut.crtc_id, lut.gamma_size, > + (void *)lut.red, (void *)lut.green, (void *)lut.blue); > + } > + > + return 1; > +} > + > +static int drm_mode_get_encoder(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_get_encoder enc; > + > + if (umove(tcp, arg, &enc)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {encoder_id=%u", enc.encoder_id); > + } else if (exiting(tcp)) { > + /* TODO: Print name of encoder type */ > + tprintf(", encoder_type=%u, crtc_id=%u, possible_crtcs=0x%x, " > + "possible_clones=0x%x}", enc.encoder_type, > + enc.crtc_id, enc.possible_crtcs, enc.possible_clones); > + } > + > + return 1; > +} > + > +static int drm_mode_get_connector(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_get_connector con; > + > + if (umove(tcp, arg, &con)) > + return 0; > + > + /* We could be very verbose here but keep is simple for now */ > + if (entering(tcp)) { > + tprintf(", {connector_id=%u", con.connector_id); > + } else if (exiting(tcp)) { > + tprintf(", encoders_ptr=%p, modes_ptr=%p, props_ptr=%p, " > + "prop_values_ptr=%p, count_modes=%u, count_props=%u, " > + "count_encoders=%u, encoder_id=%u, connector_type=%u, " > + "connector_type_id=%u, connection=%u, mm_width=%u, " > + "mm_height=%u, subpixel=%u}", (void *)con.encoders_ptr, > + (void *)con.modes_ptr, (void *)con.props_ptr, > + (void *)con.prop_values_ptr, con.count_modes, > + con.count_props, con.count_encoders, con.encoder_id, > + con.connector_type, con.connector_type_id, > + con.connection, con.mm_width, con.mm_height, > + con.subpixel); > + } > + > + return 1; > +} > + > +static int drm_mode_get_property(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_get_property prop; > + > + if (umove(tcp, arg, &prop)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {prop_id=%u", prop.prop_id); > + } else if (exiting(tcp)) { > + tprintf(", values_ptr=%p, enum_blob_ptr=%p, flags=0x%x, " > + "name=%s, count_values=%u, count_enum_blobs=%u}", > + (void *)prop.values_ptr, (void *)prop.enum_blob_ptr, > + prop.flags, prop.name, prop.count_values, > + prop.count_enum_blobs); > + } > + > + return 1; > +} > + > +static int drm_mode_set_property(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_connector_set_property prop; > + > + if (umove(tcp, arg, &prop)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {value=%Lu, prop_id=%u, connector_id=%u}", > + prop.value, prop.prop_id, prop.connector_id); > + } > + > + return 1; > +} > + > +static int drm_mode_get_prop_blob(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_get_blob blob; > + > + if (umove(tcp, arg, &blob)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {blob_id=%u", blob.blob_id); > + } else if (exiting(tcp)) { > + tprintf(", length=%u, data=%p}", blob.length, > + (void *)blob.data); > + } > + > + return 1; > +} > + > +static int drm_mode_add_fb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_fb_cmd cmd; > + > + if (umove(tcp, arg, &cmd)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {width=%u, height=%u, pitch=%u, bpp=%u, depth=%u, " > + "handle=%u", cmd.width, cmd.height, cmd.pitch, > + cmd.bpp, cmd.depth, cmd.handle); > + } else if (exiting(tcp)) { > + tprintf(", fb_id=%u}", cmd.fb_id); > + } > + > + return 1; > +} > + > +static int drm_mode_get_fb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_fb_cmd cmd; > + > + if (umove(tcp, arg, &cmd)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {fb_id=%u", cmd.fb_id); > + } else { > + tprintf(", width=%u, height=%u, pitch=%u, bpp=%u, depth=%u, " > + "handle=%u}", cmd.width, cmd.height, cmd.pitch, > + cmd.bpp, cmd.depth, cmd.handle); > + } > + > + return 1; > +} > + > +static int drm_mode_rm_fb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + unsigned int handle; > + > + if (umove(tcp, arg, &handle)) > + return 0; > + > + if (entering(tcp)) > + tprintf(", %u", handle); > + > + return 1; > +} > + > +static int drm_mode_page_flip(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_crtc_page_flip flip; > + > + if (umove(tcp, arg, &flip)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {crtc_id=%u, fb_id=%u, flags=0x%x, user_data=0x%Lx}", > + flip.crtc_id, flip.fb_id, flip.flags, flip.user_data); > + } > + > + return 1; > +} > + > +static int drm_mode_dirty_fb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_fb_dirty_cmd cmd; > + > + if (umove(tcp, arg, &cmd)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {fb_id=%u, flags=0x%x, color=0x%x, num_clips=%u, " > + "clips_ptr=%p}", cmd.fb_id, cmd.flags, cmd.color, > + cmd.num_clips, (void *)cmd.clips_ptr); > + } > + > + return 1; > +} > + > +static int drm_mode_create_dumb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_create_dumb dumb; > + > + if (umove(tcp, arg, &dumb)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {width=%u, height=%u, bpp=%u, flags=0x%x", > + dumb.width, dumb.height, dumb.bpp, dumb.flags); > + } else if (exiting(tcp)) { > + tprintf(", handle=%u, pitch=%u, size=%Lu}", dumb.handle, > + dumb.pitch, dumb.size); > + } > + > + return 1; > +} > + > +static int drm_mode_map_dumb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_map_dumb dumb; > + > + if (umove(tcp, arg, &dumb)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {handle=%u", dumb.handle); > + } else if (exiting(tcp)) { > + tprintf(", offset=%Lu}", dumb.offset); > + } > + > + return 1; > +} > + > +static int drm_mode_destroy_dumb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_destroy_dumb dumb; > + > + if (umove(tcp, arg, &dumb)) > + return 0; > + > + if (entering(tcp)) > + tprintf(", {handle=%u}", dumb.handle); > + > + return 1; > +} > + > +static int drm_gem_close(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_gem_close close; > + > + if (umove(tcp, arg, &close)) > + return 0; > + > + if (entering(tcp)) > + tprintf(", {handle=%u}", close.handle); > + > + return 1; > +} > + > int drm_ioctl(struct tcb *tcp, const unsigned int code, long arg) > { > /* Check for device specific ioctls */ > @@ -112,6 +569,59 @@ int drm_ioctl(struct tcb *tcp, const unsigned int code, long arg) > return drm_i915_ioctl(tcp, code, arg); > } > > + switch (code) { > + case DRM_IOCTL_VERSION: > + return drm_version(tcp, code, arg); > + case DRM_IOCTL_GET_UNIQUE: > + return drm_get_unique(tcp, code, arg); > + case DRM_IOCTL_GET_MAGIC: > + return drm_get_magic(tcp, code, arg); > + case DRM_IOCTL_WAIT_VBLANK: > + return drm_wait_vblank(tcp, code, arg); > + case DRM_IOCTL_MODE_GETRESOURCES: > + return drm_mode_get_resources(tcp, code, arg); > + case DRM_IOCTL_MODE_GETCRTC: > + return drm_mode_get_crtc(tcp, code, arg); > + case DRM_IOCTL_MODE_SETCRTC: > + return drm_mode_set_crtc(tcp, code, arg); > + case DRM_IOCTL_MODE_CURSOR: > + return drm_mode_cursor(tcp, code, arg); > + case DRM_IOCTL_MODE_CURSOR2: > + return drm_mode_cursor2(tcp, code, arg); > + case DRM_IOCTL_MODE_GETGAMMA: > + return drm_mode_get_gamma(tcp, code, arg); > + case DRM_IOCTL_MODE_SETGAMMA: > + return drm_mode_set_gamma(tcp, code, arg); > + case DRM_IOCTL_MODE_GETENCODER: > + return drm_mode_get_encoder(tcp, code, arg); > + case DRM_IOCTL_MODE_GETCONNECTOR: > + return drm_mode_get_connector(tcp, code, arg); > + case DRM_IOCTL_MODE_GETPROPERTY: > + return drm_mode_get_property(tcp, code, arg); > + case DRM_IOCTL_MODE_SETPROPERTY: > + return drm_mode_set_property(tcp, code, arg); > + case DRM_IOCTL_MODE_GETPROPBLOB: > + return drm_mode_get_prop_blob(tcp, code, arg); > + case DRM_IOCTL_MODE_GETFB: > + return drm_mode_get_fb(tcp, code, arg); > + case DRM_IOCTL_MODE_ADDFB: > + return drm_mode_add_fb(tcp, code, arg); > + case DRM_IOCTL_MODE_RMFB: > + return drm_mode_rm_fb(tcp, code, arg); > + case DRM_IOCTL_MODE_PAGE_FLIP: > + return drm_mode_page_flip(tcp, code, arg); > + case DRM_IOCTL_MODE_DIRTYFB: > + return drm_mode_dirty_fb(tcp, code, arg); > + case DRM_IOCTL_MODE_CREATE_DUMB: > + return drm_mode_create_dumb(tcp, code, arg); > + case DRM_IOCTL_MODE_MAP_DUMB: > + return drm_mode_map_dumb(tcp, code, arg); > + case DRM_IOCTL_MODE_DESTROY_DUMB: > + return drm_mode_destroy_dumb(tcp, code, arg); > + case DRM_IOCTL_GEM_CLOSE: > + return drm_gem_close(tcp, code, arg); > + } > + > /* Free any allocated private data */ > if (exiting(tcp) && tcp->priv_data != NULL) { > free(tcp->priv_data);
On Mon, Jun 29, 2015 at 07:35:00PM +0200, Gabriel Laskar wrote: > On Thu, 18 Jun 2015 10:42:45 +0200 > Patrik Jakobsson <patrik.jakobsson@linux.intel.com> wrote: > > > This patch adds many of the DRM and KMS ioctls. The rest can be added as > > needed. > > > > * drm.c: Decode DRM_IOCTL_VERSION > > * drm.c: Decode DRM_IOCTL_GET_UNIQUE > > * drm.c: Decode DRM_IOCTL_GET_MAGIC > > * drm.c: Decode DRM_IOCTL_WAIT_VBLANK > > * drm.c: Decode DRM_IOCTL_MODE_GETRESOURCES > > * drm.c: Decode DRM_IOCTL_MODE_GETCRTC > > * drm.c: Decode DRM_IOCTL_MODE_SETCRTC > > * drm.c: Decode DRM_IOCTL_MODE_CURSOR > > * drm.c: Decode DRM_IOCTL_MODE_CURSOR2 > > * drm.c: Decode DRM_IOCTL_MODE_GETGAMMA > > * drm.c: Decode DRM_IOCTL_MODE_SETGAMMA > > * drm.c: Decode DRM_IOCTL_MODE_GETENCODER > > * drm.c: Decode DRM_IOCTL_MODE_GETCONNECTOR > > * drm.c: Decode DRM_IOCTL_MODE_GETPROPERTY > > * drm.c: Decode DRM_IOCTL_MODE_SETPROPERTY > > * drm.c: Decode DRM_IOCTL_MODE_GETPROPBLOB > > * drm.c: Decode DRM_IOCTL_MODE_GETFB > > * drm.c: Decode DRM_IOCTL_MODE_ADDFB > > * drm.c: Decode DRM_IOCTL_MODE_RMFB > > * drm.c: Decode DRM_IOCTL_MODE_PAGE_FLIP > > * drm.c: Decode DRM_IOCTL_DIRTYFB > > * drm.c: Decode DRM_IOCTL_CREATE_DUMB > > * drm.c: Decode DRM_IOCTL_MAP_DUMB > > * drm.c: Decode DRM_IOCTL_DESTROY_DUMB > > * drm.c: Decode DRM_IOCTL_GEM_CLOSE > > > > Signed-off-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> > > --- > > drm.c | 510 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 510 insertions(+) > > > > diff --git a/drm.c b/drm.c > > index 8e3f7d1..2e6d763 100644 > > --- a/drm.c > > +++ b/drm.c > > @@ -104,6 +104,463 @@ int drm_decode_number(struct tcb *tcp, unsigned int arg) > > return 0; > > } > > > > +static int drm_version(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_version ver; > > + > > + if (umove(tcp, arg, &ver)) > > + return 0; > > + > > The umove() should be done only on exiting and if the ioctl succeded ? > > Same thing for most of the read only ioctl. > Yes, that could be moved into exiting. Will fix for all "single phase" ioctls. > > + if (exiting(tcp)) { > > + tprintf(", {version_major=%d, version_minor=%d, version_patchlevel=%d, " > > + "name_len=%lu, name=", ver.version_major, > > + ver.version_minor, ver.version_patchlevel, > > + ver.name_len); > > + printstr(tcp, (long)ver.name, ver.name_len); > > + tprintf(", date_len=%lu, date=", ver.date_len); > > + printstr(tcp, (long)ver.date, ver.date_len); > > + tprintf(", desc_len=%lu, desc=", ver.desc_len); > > + printstr(tcp, (long)ver.desc, ver.desc_len); > > + tprints("}"); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_get_unique(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_unique unique; > > + > > + if (umove(tcp, arg, &unique)) > > + return 0; > > + > > + if (exiting(tcp)) { > > + tprintf(", {unique_len=%lu, unique=}", unique.unique_len); > > There is an extra '}' > Oops > > + printstr(tcp, (long)unique.unique, unique.unique_len); > > + tprints("}"); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_get_magic(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_auth auth; > > + > > + if (umove(tcp, arg, &auth)) > > + return 0; > > + > > + if (exiting(tcp)) > > + tprintf(", {magic=%u}", auth.magic); > > + > > + return 1; > > +} > > + > > +static int drm_wait_vblank(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + union drm_wait_vblank vblank; > > + > > + if (umove(tcp, arg, &vblank)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {request={type=%u, sequence=%u, signal=%lu}", > > + vblank.request.type, vblank.request.sequence, > > + vblank.request.signal); > > + } else if (exiting(tcp)) { > > + tprintf(", reply={type=%u, sequence=%u, tval_sec=%ld, tval_usec=%ld}}", > > + vblank.reply.type, vblank.reply.sequence, > > + vblank.reply.tval_sec, vblank.reply.tval_usec); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_resources(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_card_res res; > > + > > + if (umove(tcp, arg, &res)) > > + return 0; > > + > > + if (exiting(tcp)) { > > + tprintf(", {fb_id_ptr=%p, crtc_id_ptr=%p, connector_id_ptr=%p, " > > + "encoder_id_ptr=%p, count_fbs=%u, count_crtcs=%u, " > > + "count_connectors=%u, count_encoders=%u, min_width=%u, " > > + "max_width=%u, min_height=%u, max_height=%u}", > > + (void *)res.fb_id_ptr, (void *)res.crtc_id_ptr, > > + (void *)res.connector_id_ptr, (void *)res.encoder_id_ptr, > > + res.count_fbs, res.count_crtcs, res.count_connectors, > > + res.count_encoders, res.min_width, res.max_width, > > + res.min_height, res.max_height); > > + } > > + > > + return 1; > > +} > > + > > +static void drm_mode_print_modeinfo(struct drm_mode_modeinfo *info) > > +{ > > + tprintf("clock=%u, hdisplay=%hu, hsync_start=%hu, hsync_end=%hu, " > > + "htotal=%hu, hskew=%hu, vdisplay=%hu, vsync_start=%hu, " > > + "vsync_end=%hu, vtotal=%hu, vscan=%hu, vrefresh=%u, " > > + "flags=0x%x, type=%u, name=%s", info->clock, info->hdisplay, > > + info->hsync_start, info->hsync_end, info->htotal, info->hskew, > > + info->vdisplay, info->vsync_start, info->vsync_end, > > + info->vtotal, info->vscan, info->vrefresh, info->flags, > > + info->type, info->name); > > +} > > + > > +static int drm_mode_get_crtc(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_crtc crtc; > > + > > + if (umove(tcp, arg, &crtc)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {crtc_id=%u", crtc.crtc_id); > > + } else if (exiting(tcp)) { > > + tprintf(", set_connectors_ptr=%p, count_connectors=%u, " > > + "fb_id=%u, x=%u, y=%u, gamma_size=%u, mode_valid=%u, " > > + "mode={", (void *)crtc.set_connectors_ptr, > > + crtc.count_connectors, crtc.fb_id, crtc.x, crtc.y, > > + crtc.gamma_size, crtc.mode_valid); > > + > > + drm_mode_print_modeinfo(&crtc.mode); > > + tprintf("}}"); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_set_crtc(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_crtc crtc; > > + > > + if (umove(tcp, arg, &crtc)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {set_connectors_ptr=%p, count_connectors=%u, " > > + "crtc_id=%u, fb_id=%u, x=%u, y=%u, gamma_size=%u, " > > + "mode_valid=%u, mode={", (void *)crtc.set_connectors_ptr, > > + crtc.count_connectors, crtc.crtc_id, crtc.fb_id, crtc.x, > > + crtc.y, crtc.gamma_size, crtc.mode_valid); > > + > > + drm_mode_print_modeinfo(&crtc.mode); > > + tprintf("}}"); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_cursor(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_cursor cursor; > > + > > + if (umove(tcp, arg, &cursor)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {flags=0x%x, crtc_id=%u, x=%d, y=%d, width=%u, " > > + "height=%u, handle=%u}", cursor.flags, cursor.crtc_id, > > + cursor.x, cursor.y, cursor.width, cursor.height, > > + cursor.handle); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_cursor2(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_cursor2 cursor; > > + > > + if (umove(tcp, arg, &cursor)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {flags=0x%x, crtc_id=%u, x=%d, y=%d, width=%u, " > > + "height=%u, handle=%u, hot_x=%d, hot_y=%d}", > > + cursor.flags, cursor.crtc_id, cursor.x, cursor.y, > > + cursor.width, cursor.height, cursor.handle, > > + cursor.hot_x, cursor.hot_y); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_gamma(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_crtc_lut lut; > > + > > + if (umove(tcp, arg, &lut)) > > + return 0; > > + > > + if (entering(tcp)) { > > + /* We don't print the entire table, just the pointers */ > > + tprintf(", {crtc_id=%u, gamma_size=%u, red=%p, green=%p, " > > + "blue=%p}", lut.crtc_id, lut.gamma_size, > > + (void *)lut.red, (void *)lut.green, (void *)lut.blue); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_set_gamma(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_crtc_lut lut; > > + > > + if (umove(tcp, arg, &lut)) > > + return 0; > > + > > + if (entering(tcp)) { > > + /* We don't print the entire table, just the rgb pointers */ > > + tprintf(", {crtc_id=%u, gamma_size=%u, red=%p, green=%p, " > > + "blue=%p}", lut.crtc_id, lut.gamma_size, > > + (void *)lut.red, (void *)lut.green, (void *)lut.blue); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_encoder(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_get_encoder enc; > > + > > + if (umove(tcp, arg, &enc)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {encoder_id=%u", enc.encoder_id); > > + } else if (exiting(tcp)) { > > + /* TODO: Print name of encoder type */ > > + tprintf(", encoder_type=%u, crtc_id=%u, possible_crtcs=0x%x, " > > + "possible_clones=0x%x}", enc.encoder_type, > > + enc.crtc_id, enc.possible_crtcs, enc.possible_clones); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_connector(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_get_connector con; > > + > > + if (umove(tcp, arg, &con)) > > + return 0; > > + > > + /* We could be very verbose here but keep is simple for now */ > > + if (entering(tcp)) { > > + tprintf(", {connector_id=%u", con.connector_id); > > + } else if (exiting(tcp)) { > > + tprintf(", encoders_ptr=%p, modes_ptr=%p, props_ptr=%p, " > > + "prop_values_ptr=%p, count_modes=%u, count_props=%u, " > > + "count_encoders=%u, encoder_id=%u, connector_type=%u, " > > + "connector_type_id=%u, connection=%u, mm_width=%u, " > > + "mm_height=%u, subpixel=%u}", (void *)con.encoders_ptr, > > + (void *)con.modes_ptr, (void *)con.props_ptr, > > + (void *)con.prop_values_ptr, con.count_modes, > > + con.count_props, con.count_encoders, con.encoder_id, > > + con.connector_type, con.connector_type_id, > > + con.connection, con.mm_width, con.mm_height, > > + con.subpixel); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_property(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_get_property prop; > > + > > + if (umove(tcp, arg, &prop)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {prop_id=%u", prop.prop_id); > > + } else if (exiting(tcp)) { > > + tprintf(", values_ptr=%p, enum_blob_ptr=%p, flags=0x%x, " > > + "name=%s, count_values=%u, count_enum_blobs=%u}", > > + (void *)prop.values_ptr, (void *)prop.enum_blob_ptr, > > + prop.flags, prop.name, prop.count_values, > > + prop.count_enum_blobs); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_set_property(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_connector_set_property prop; > > + > > + if (umove(tcp, arg, &prop)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {value=%Lu, prop_id=%u, connector_id=%u}", > > + prop.value, prop.prop_id, prop.connector_id); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_prop_blob(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_get_blob blob; > > + > > + if (umove(tcp, arg, &blob)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {blob_id=%u", blob.blob_id); > > + } else if (exiting(tcp)) { > > + tprintf(", length=%u, data=%p}", blob.length, > > + (void *)blob.data); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_add_fb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_fb_cmd cmd; > > + > > + if (umove(tcp, arg, &cmd)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {width=%u, height=%u, pitch=%u, bpp=%u, depth=%u, " > > + "handle=%u", cmd.width, cmd.height, cmd.pitch, > > + cmd.bpp, cmd.depth, cmd.handle); > > + } else if (exiting(tcp)) { > > + tprintf(", fb_id=%u}", cmd.fb_id); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_get_fb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_fb_cmd cmd; > > + > > + if (umove(tcp, arg, &cmd)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {fb_id=%u", cmd.fb_id); > > + } else { > > + tprintf(", width=%u, height=%u, pitch=%u, bpp=%u, depth=%u, " > > + "handle=%u}", cmd.width, cmd.height, cmd.pitch, > > + cmd.bpp, cmd.depth, cmd.handle); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_rm_fb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + unsigned int handle; > > + > > + if (umove(tcp, arg, &handle)) > > + return 0; > > + > > + if (entering(tcp)) > > + tprintf(", %u", handle); > > + > > + return 1; > > +} > > + > > +static int drm_mode_page_flip(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_crtc_page_flip flip; > > + > > + if (umove(tcp, arg, &flip)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {crtc_id=%u, fb_id=%u, flags=0x%x, user_data=0x%Lx}", > > + flip.crtc_id, flip.fb_id, flip.flags, flip.user_data); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_dirty_fb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_fb_dirty_cmd cmd; > > + > > + if (umove(tcp, arg, &cmd)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {fb_id=%u, flags=0x%x, color=0x%x, num_clips=%u, " > > + "clips_ptr=%p}", cmd.fb_id, cmd.flags, cmd.color, > > + cmd.num_clips, (void *)cmd.clips_ptr); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_create_dumb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_create_dumb dumb; > > + > > + if (umove(tcp, arg, &dumb)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {width=%u, height=%u, bpp=%u, flags=0x%x", > > + dumb.width, dumb.height, dumb.bpp, dumb.flags); > > + } else if (exiting(tcp)) { > > + tprintf(", handle=%u, pitch=%u, size=%Lu}", dumb.handle, > > + dumb.pitch, dumb.size); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_map_dumb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_map_dumb dumb; > > + > > + if (umove(tcp, arg, &dumb)) > > + return 0; > > + > > + if (entering(tcp)) { > > + tprintf(", {handle=%u", dumb.handle); > > + } else if (exiting(tcp)) { > > + tprintf(", offset=%Lu}", dumb.offset); > > + } > > + > > + return 1; > > +} > > + > > +static int drm_mode_destroy_dumb(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_mode_destroy_dumb dumb; > > + > > + if (umove(tcp, arg, &dumb)) > > + return 0; > > + > > + if (entering(tcp)) > > + tprintf(", {handle=%u}", dumb.handle); > > + > > + return 1; > > +} > > + > > +static int drm_gem_close(struct tcb *tcp, const unsigned int code, long arg) > > +{ > > + struct drm_gem_close close; > > + > > + if (umove(tcp, arg, &close)) > > + return 0; > > + > > + if (entering(tcp)) > > + tprintf(", {handle=%u}", close.handle); > > + > > + return 1; > > +} > > + > > int drm_ioctl(struct tcb *tcp, const unsigned int code, long arg) > > { > > /* Check for device specific ioctls */ > > @@ -112,6 +569,59 @@ int drm_ioctl(struct tcb *tcp, const unsigned int code, long arg) > > return drm_i915_ioctl(tcp, code, arg); > > } > > > > + switch (code) { > > + case DRM_IOCTL_VERSION: > > + return drm_version(tcp, code, arg); > > + case DRM_IOCTL_GET_UNIQUE: > > + return drm_get_unique(tcp, code, arg); > > + case DRM_IOCTL_GET_MAGIC: > > + return drm_get_magic(tcp, code, arg); > > + case DRM_IOCTL_WAIT_VBLANK: > > + return drm_wait_vblank(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETRESOURCES: > > + return drm_mode_get_resources(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETCRTC: > > + return drm_mode_get_crtc(tcp, code, arg); > > + case DRM_IOCTL_MODE_SETCRTC: > > + return drm_mode_set_crtc(tcp, code, arg); > > + case DRM_IOCTL_MODE_CURSOR: > > + return drm_mode_cursor(tcp, code, arg); > > + case DRM_IOCTL_MODE_CURSOR2: > > + return drm_mode_cursor2(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETGAMMA: > > + return drm_mode_get_gamma(tcp, code, arg); > > + case DRM_IOCTL_MODE_SETGAMMA: > > + return drm_mode_set_gamma(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETENCODER: > > + return drm_mode_get_encoder(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETCONNECTOR: > > + return drm_mode_get_connector(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETPROPERTY: > > + return drm_mode_get_property(tcp, code, arg); > > + case DRM_IOCTL_MODE_SETPROPERTY: > > + return drm_mode_set_property(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETPROPBLOB: > > + return drm_mode_get_prop_blob(tcp, code, arg); > > + case DRM_IOCTL_MODE_GETFB: > > + return drm_mode_get_fb(tcp, code, arg); > > + case DRM_IOCTL_MODE_ADDFB: > > + return drm_mode_add_fb(tcp, code, arg); > > + case DRM_IOCTL_MODE_RMFB: > > + return drm_mode_rm_fb(tcp, code, arg); > > + case DRM_IOCTL_MODE_PAGE_FLIP: > > + return drm_mode_page_flip(tcp, code, arg); > > + case DRM_IOCTL_MODE_DIRTYFB: > > + return drm_mode_dirty_fb(tcp, code, arg); > > + case DRM_IOCTL_MODE_CREATE_DUMB: > > + return drm_mode_create_dumb(tcp, code, arg); > > + case DRM_IOCTL_MODE_MAP_DUMB: > > + return drm_mode_map_dumb(tcp, code, arg); > > + case DRM_IOCTL_MODE_DESTROY_DUMB: > > + return drm_mode_destroy_dumb(tcp, code, arg); > > + case DRM_IOCTL_GEM_CLOSE: > > + return drm_gem_close(tcp, code, arg); > > + } > > + > > /* Free any allocated private data */ > > if (exiting(tcp) && tcp->priv_data != NULL) { > > free(tcp->priv_data); > > > > -- > Gabriel Laskar
On Thu, Jun 18, 2015 at 10:42:45AM +0200, Patrik Jakobsson wrote: > This patch adds many of the DRM and KMS ioctls. The rest can be added as > needed. > > * drm.c: Decode DRM_IOCTL_VERSION > * drm.c: Decode DRM_IOCTL_GET_UNIQUE > * drm.c: Decode DRM_IOCTL_GET_MAGIC > * drm.c: Decode DRM_IOCTL_WAIT_VBLANK > * drm.c: Decode DRM_IOCTL_MODE_GETRESOURCES > * drm.c: Decode DRM_IOCTL_MODE_GETCRTC > * drm.c: Decode DRM_IOCTL_MODE_SETCRTC > * drm.c: Decode DRM_IOCTL_MODE_CURSOR > * drm.c: Decode DRM_IOCTL_MODE_CURSOR2 > * drm.c: Decode DRM_IOCTL_MODE_GETGAMMA > * drm.c: Decode DRM_IOCTL_MODE_SETGAMMA > * drm.c: Decode DRM_IOCTL_MODE_GETENCODER > * drm.c: Decode DRM_IOCTL_MODE_GETCONNECTOR > * drm.c: Decode DRM_IOCTL_MODE_GETPROPERTY > * drm.c: Decode DRM_IOCTL_MODE_SETPROPERTY > * drm.c: Decode DRM_IOCTL_MODE_GETPROPBLOB > * drm.c: Decode DRM_IOCTL_MODE_GETFB > * drm.c: Decode DRM_IOCTL_MODE_ADDFB > * drm.c: Decode DRM_IOCTL_MODE_RMFB > * drm.c: Decode DRM_IOCTL_MODE_PAGE_FLIP > * drm.c: Decode DRM_IOCTL_DIRTYFB > * drm.c: Decode DRM_IOCTL_CREATE_DUMB > * drm.c: Decode DRM_IOCTL_MAP_DUMB > * drm.c: Decode DRM_IOCTL_DESTROY_DUMB > * drm.c: Decode DRM_IOCTL_GEM_CLOSE > > Signed-off-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> > --- > drm.c | 510 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 510 insertions(+) > > diff --git a/drm.c b/drm.c > index 8e3f7d1..2e6d763 100644 > --- a/drm.c > +++ b/drm.c > @@ -104,6 +104,463 @@ int drm_decode_number(struct tcb *tcp, unsigned int arg) > return 0; > } > > +static int drm_version(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_version ver; > + > + if (umove(tcp, arg, &ver)) > + return 0; > + > + if (exiting(tcp)) { > + tprintf(", {version_major=%d, version_minor=%d, version_patchlevel=%d, " > + "name_len=%lu, name=", ver.version_major, > + ver.version_minor, ver.version_patchlevel, > + ver.name_len); > + printstr(tcp, (long)ver.name, ver.name_len); > + tprintf(", date_len=%lu, date=", ver.date_len); > + printstr(tcp, (long)ver.date, ver.date_len); > + tprintf(", desc_len=%lu, desc=", ver.desc_len); > + printstr(tcp, (long)ver.desc, ver.desc_len); > + tprints("}"); > + } > + > + return 1; > +} > + > +static int drm_get_unique(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_unique unique; > + > + if (umove(tcp, arg, &unique)) > + return 0; > + > + if (exiting(tcp)) { > + tprintf(", {unique_len=%lu, unique=}", unique.unique_len); > + printstr(tcp, (long)unique.unique, unique.unique_len); > + tprints("}"); > + } > + > + return 1; > +} > + > +static int drm_get_magic(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_auth auth; > + > + if (umove(tcp, arg, &auth)) > + return 0; > + > + if (exiting(tcp)) > + tprintf(", {magic=%u}", auth.magic); > + > + return 1; > +} > + > +static int drm_wait_vblank(struct tcb *tcp, const unsigned int code, long arg) > +{ > + union drm_wait_vblank vblank; > + > + if (umove(tcp, arg, &vblank)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {request={type=%u, sequence=%u, signal=%lu}", > + vblank.request.type, vblank.request.sequence, > + vblank.request.signal); > + } else if (exiting(tcp)) { > + tprintf(", reply={type=%u, sequence=%u, tval_sec=%ld, tval_usec=%ld}}", > + vblank.reply.type, vblank.reply.sequence, > + vblank.reply.tval_sec, vblank.reply.tval_usec); > + } > + > + return 1; > +} > + > +static int drm_mode_get_resources(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_card_res res; > + > + if (umove(tcp, arg, &res)) > + return 0; > + > + if (exiting(tcp)) { > + tprintf(", {fb_id_ptr=%p, crtc_id_ptr=%p, connector_id_ptr=%p, " > + "encoder_id_ptr=%p, count_fbs=%u, count_crtcs=%u, " > + "count_connectors=%u, count_encoders=%u, min_width=%u, " > + "max_width=%u, min_height=%u, max_height=%u}", > + (void *)res.fb_id_ptr, (void *)res.crtc_id_ptr, > + (void *)res.connector_id_ptr, (void *)res.encoder_id_ptr, > + res.count_fbs, res.count_crtcs, res.count_connectors, > + res.count_encoders, res.min_width, res.max_width, > + res.min_height, res.max_height); > + } > + > + return 1; > +} > + > +static void drm_mode_print_modeinfo(struct drm_mode_modeinfo *info) > +{ > + tprintf("clock=%u, hdisplay=%hu, hsync_start=%hu, hsync_end=%hu, " > + "htotal=%hu, hskew=%hu, vdisplay=%hu, vsync_start=%hu, " > + "vsync_end=%hu, vtotal=%hu, vscan=%hu, vrefresh=%u, " > + "flags=0x%x, type=%u, name=%s", info->clock, info->hdisplay, > + info->hsync_start, info->hsync_end, info->htotal, info->hskew, > + info->vdisplay, info->vsync_start, info->vsync_end, > + info->vtotal, info->vscan, info->vrefresh, info->flags, > + info->type, info->name); > +} > + > +static int drm_mode_get_crtc(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_crtc crtc; > + > + if (umove(tcp, arg, &crtc)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {crtc_id=%u", crtc.crtc_id); > + } else if (exiting(tcp)) { > + tprintf(", set_connectors_ptr=%p, count_connectors=%u, " > + "fb_id=%u, x=%u, y=%u, gamma_size=%u, mode_valid=%u, " > + "mode={", (void *)crtc.set_connectors_ptr, > + crtc.count_connectors, crtc.fb_id, crtc.x, crtc.y, > + crtc.gamma_size, crtc.mode_valid); > + > + drm_mode_print_modeinfo(&crtc.mode); > + tprintf("}}"); > + } > + > + return 1; > +} > + > +static int drm_mode_set_crtc(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_crtc crtc; > + > + if (umove(tcp, arg, &crtc)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {set_connectors_ptr=%p, count_connectors=%u, " > + "crtc_id=%u, fb_id=%u, x=%u, y=%u, gamma_size=%u, " > + "mode_valid=%u, mode={", (void *)crtc.set_connectors_ptr, > + crtc.count_connectors, crtc.crtc_id, crtc.fb_id, crtc.x, > + crtc.y, crtc.gamma_size, crtc.mode_valid); > + > + drm_mode_print_modeinfo(&crtc.mode); > + tprintf("}}"); > + } > + > + return 1; > +} > + > +static int drm_mode_cursor(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_cursor cursor; > + > + if (umove(tcp, arg, &cursor)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {flags=0x%x, crtc_id=%u, x=%d, y=%d, width=%u, " > + "height=%u, handle=%u}", cursor.flags, cursor.crtc_id, > + cursor.x, cursor.y, cursor.width, cursor.height, > + cursor.handle); > + } > + > + return 1; > +} > + > +static int drm_mode_cursor2(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_cursor2 cursor; > + > + if (umove(tcp, arg, &cursor)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {flags=0x%x, crtc_id=%u, x=%d, y=%d, width=%u, " > + "height=%u, handle=%u, hot_x=%d, hot_y=%d}", > + cursor.flags, cursor.crtc_id, cursor.x, cursor.y, > + cursor.width, cursor.height, cursor.handle, > + cursor.hot_x, cursor.hot_y); > + } > + > + return 1; > +} > + > +static int drm_mode_get_gamma(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_crtc_lut lut; > + > + if (umove(tcp, arg, &lut)) > + return 0; > + > + if (entering(tcp)) { > + /* We don't print the entire table, just the pointers */ > + tprintf(", {crtc_id=%u, gamma_size=%u, red=%p, green=%p, " > + "blue=%p}", lut.crtc_id, lut.gamma_size, > + (void *)lut.red, (void *)lut.green, (void *)lut.blue); > + } > + > + return 1; > +} > + > +static int drm_mode_set_gamma(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_crtc_lut lut; > + > + if (umove(tcp, arg, &lut)) > + return 0; > + > + if (entering(tcp)) { > + /* We don't print the entire table, just the rgb pointers */ > + tprintf(", {crtc_id=%u, gamma_size=%u, red=%p, green=%p, " > + "blue=%p}", lut.crtc_id, lut.gamma_size, > + (void *)lut.red, (void *)lut.green, (void *)lut.blue); > + } > + > + return 1; > +} > + > +static int drm_mode_get_encoder(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_get_encoder enc; > + > + if (umove(tcp, arg, &enc)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {encoder_id=%u", enc.encoder_id); > + } else if (exiting(tcp)) { > + /* TODO: Print name of encoder type */ > + tprintf(", encoder_type=%u, crtc_id=%u, possible_crtcs=0x%x, " > + "possible_clones=0x%x}", enc.encoder_type, > + enc.crtc_id, enc.possible_crtcs, enc.possible_clones); > + } > + > + return 1; > +} > + > +static int drm_mode_get_connector(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_get_connector con; > + > + if (umove(tcp, arg, &con)) > + return 0; > + > + /* We could be very verbose here but keep is simple for now */ > + if (entering(tcp)) { > + tprintf(", {connector_id=%u", con.connector_id); > + } else if (exiting(tcp)) { > + tprintf(", encoders_ptr=%p, modes_ptr=%p, props_ptr=%p, " > + "prop_values_ptr=%p, count_modes=%u, count_props=%u, " > + "count_encoders=%u, encoder_id=%u, connector_type=%u, " > + "connector_type_id=%u, connection=%u, mm_width=%u, " > + "mm_height=%u, subpixel=%u}", (void *)con.encoders_ptr, > + (void *)con.modes_ptr, (void *)con.props_ptr, > + (void *)con.prop_values_ptr, con.count_modes, > + con.count_props, con.count_encoders, con.encoder_id, > + con.connector_type, con.connector_type_id, > + con.connection, con.mm_width, con.mm_height, > + con.subpixel); > + } > + > + return 1; > +} > + > +static int drm_mode_get_property(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_get_property prop; > + > + if (umove(tcp, arg, &prop)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {prop_id=%u", prop.prop_id); > + } else if (exiting(tcp)) { > + tprintf(", values_ptr=%p, enum_blob_ptr=%p, flags=0x%x, " > + "name=%s, count_values=%u, count_enum_blobs=%u}", > + (void *)prop.values_ptr, (void *)prop.enum_blob_ptr, > + prop.flags, prop.name, prop.count_values, > + prop.count_enum_blobs); > + } > + > + return 1; > +} > + > +static int drm_mode_set_property(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_connector_set_property prop; > + > + if (umove(tcp, arg, &prop)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {value=%Lu, prop_id=%u, connector_id=%u}", > + prop.value, prop.prop_id, prop.connector_id); > + } > + > + return 1; > +} > + > +static int drm_mode_get_prop_blob(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_get_blob blob; > + > + if (umove(tcp, arg, &blob)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {blob_id=%u", blob.blob_id); > + } else if (exiting(tcp)) { > + tprintf(", length=%u, data=%p}", blob.length, > + (void *)blob.data); > + } > + > + return 1; > +} > + > +static int drm_mode_add_fb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_fb_cmd cmd; > + > + if (umove(tcp, arg, &cmd)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {width=%u, height=%u, pitch=%u, bpp=%u, depth=%u, " > + "handle=%u", cmd.width, cmd.height, cmd.pitch, > + cmd.bpp, cmd.depth, cmd.handle); > + } else if (exiting(tcp)) { > + tprintf(", fb_id=%u}", cmd.fb_id); > + } > + > + return 1; > +} > + > +static int drm_mode_get_fb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_fb_cmd cmd; > + > + if (umove(tcp, arg, &cmd)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {fb_id=%u", cmd.fb_id); > + } else { > + tprintf(", width=%u, height=%u, pitch=%u, bpp=%u, depth=%u, " > + "handle=%u}", cmd.width, cmd.height, cmd.pitch, > + cmd.bpp, cmd.depth, cmd.handle); > + } > + > + return 1; > +} > + > +static int drm_mode_rm_fb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + unsigned int handle; > + > + if (umove(tcp, arg, &handle)) > + return 0; > + > + if (entering(tcp)) > + tprintf(", %u", handle); > + > + return 1; > +} > + > +static int drm_mode_page_flip(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_crtc_page_flip flip; > + > + if (umove(tcp, arg, &flip)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {crtc_id=%u, fb_id=%u, flags=0x%x, user_data=0x%Lx}", > + flip.crtc_id, flip.fb_id, flip.flags, flip.user_data); > + } > + > + return 1; > +} > + > +static int drm_mode_dirty_fb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_fb_dirty_cmd cmd; > + > + if (umove(tcp, arg, &cmd)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {fb_id=%u, flags=0x%x, color=0x%x, num_clips=%u, " > + "clips_ptr=%p}", cmd.fb_id, cmd.flags, cmd.color, > + cmd.num_clips, (void *)cmd.clips_ptr); > + } > + > + return 1; > +} > + > +static int drm_mode_create_dumb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_create_dumb dumb; > + > + if (umove(tcp, arg, &dumb)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {width=%u, height=%u, bpp=%u, flags=0x%x", > + dumb.width, dumb.height, dumb.bpp, dumb.flags); > + } else if (exiting(tcp)) { > + tprintf(", handle=%u, pitch=%u, size=%Lu}", dumb.handle, > + dumb.pitch, dumb.size); > + } > + > + return 1; > +} > + > +static int drm_mode_map_dumb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_map_dumb dumb; > + > + if (umove(tcp, arg, &dumb)) > + return 0; > + > + if (entering(tcp)) { > + tprintf(", {handle=%u", dumb.handle); > + } else if (exiting(tcp)) { > + tprintf(", offset=%Lu}", dumb.offset); > + } > + > + return 1; > +} > + > +static int drm_mode_destroy_dumb(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_mode_destroy_dumb dumb; > + > + if (umove(tcp, arg, &dumb)) > + return 0; > + > + if (entering(tcp)) > + tprintf(", {handle=%u}", dumb.handle); > + > + return 1; > +} > + > +static int drm_gem_close(struct tcb *tcp, const unsigned int code, long arg) > +{ > + struct drm_gem_close close; > + > + if (umove(tcp, arg, &close)) > + return 0; > + > + if (entering(tcp)) > + tprintf(", {handle=%u}", close.handle); > + > + return 1; > +} > + > int drm_ioctl(struct tcb *tcp, const unsigned int code, long arg) > { > /* Check for device specific ioctls */ > @@ -112,6 +569,59 @@ int drm_ioctl(struct tcb *tcp, const unsigned int code, long arg) > return drm_i915_ioctl(tcp, code, arg); > } > > + switch (code) { > + case DRM_IOCTL_VERSION: > + return drm_version(tcp, code, arg); > + case DRM_IOCTL_GET_UNIQUE: > + return drm_get_unique(tcp, code, arg); > + case DRM_IOCTL_GET_MAGIC: > + return drm_get_magic(tcp, code, arg); > + case DRM_IOCTL_WAIT_VBLANK: > + return drm_wait_vblank(tcp, code, arg); > + case DRM_IOCTL_MODE_GETRESOURCES: > + return drm_mode_get_resources(tcp, code, arg); > + case DRM_IOCTL_MODE_GETCRTC: > + return drm_mode_get_crtc(tcp, code, arg); > + case DRM_IOCTL_MODE_SETCRTC: > + return drm_mode_set_crtc(tcp, code, arg); > + case DRM_IOCTL_MODE_CURSOR: > + return drm_mode_cursor(tcp, code, arg); > + case DRM_IOCTL_MODE_CURSOR2: > + return drm_mode_cursor2(tcp, code, arg); > + case DRM_IOCTL_MODE_GETGAMMA: > + return drm_mode_get_gamma(tcp, code, arg); > + case DRM_IOCTL_MODE_SETGAMMA: > + return drm_mode_set_gamma(tcp, code, arg); > + case DRM_IOCTL_MODE_GETENCODER: > + return drm_mode_get_encoder(tcp, code, arg); > + case DRM_IOCTL_MODE_GETCONNECTOR: > + return drm_mode_get_connector(tcp, code, arg); > + case DRM_IOCTL_MODE_GETPROPERTY: > + return drm_mode_get_property(tcp, code, arg); > + case DRM_IOCTL_MODE_SETPROPERTY: > + return drm_mode_set_property(tcp, code, arg); > + case DRM_IOCTL_MODE_GETPROPBLOB: > + return drm_mode_get_prop_blob(tcp, code, arg); > + case DRM_IOCTL_MODE_GETFB: > + return drm_mode_get_fb(tcp, code, arg); > + case DRM_IOCTL_MODE_ADDFB: > + return drm_mode_add_fb(tcp, code, arg); > + case DRM_IOCTL_MODE_RMFB: > + return drm_mode_rm_fb(tcp, code, arg); > + case DRM_IOCTL_MODE_PAGE_FLIP: > + return drm_mode_page_flip(tcp, code, arg); > + case DRM_IOCTL_MODE_DIRTYFB: > + return drm_mode_dirty_fb(tcp, code, arg); > + case DRM_IOCTL_MODE_CREATE_DUMB: > + return drm_mode_create_dumb(tcp, code, arg); > + case DRM_IOCTL_MODE_MAP_DUMB: > + return drm_mode_map_dumb(tcp, code, arg); > + case DRM_IOCTL_MODE_DESTROY_DUMB: > + return drm_mode_destroy_dumb(tcp, code, arg); > + case DRM_IOCTL_GEM_CLOSE: > + return drm_gem_close(tcp, code, arg); > + } > + Just realized I'm leaking memory here because of those returns. Will take care of that. > /* Free any allocated private data */ > if (exiting(tcp) && tcp->priv_data != NULL) { > free(tcp->priv_data); > -- > 2.1.4 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff --git a/drm.c b/drm.c index 8e3f7d1..2e6d763 100644 --- a/drm.c +++ b/drm.c @@ -104,6 +104,463 @@ int drm_decode_number(struct tcb *tcp, unsigned int arg) return 0; } +static int drm_version(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_version ver; + + if (umove(tcp, arg, &ver)) + return 0; + + if (exiting(tcp)) { + tprintf(", {version_major=%d, version_minor=%d, version_patchlevel=%d, " + "name_len=%lu, name=", ver.version_major, + ver.version_minor, ver.version_patchlevel, + ver.name_len); + printstr(tcp, (long)ver.name, ver.name_len); + tprintf(", date_len=%lu, date=", ver.date_len); + printstr(tcp, (long)ver.date, ver.date_len); + tprintf(", desc_len=%lu, desc=", ver.desc_len); + printstr(tcp, (long)ver.desc, ver.desc_len); + tprints("}"); + } + + return 1; +} + +static int drm_get_unique(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_unique unique; + + if (umove(tcp, arg, &unique)) + return 0; + + if (exiting(tcp)) { + tprintf(", {unique_len=%lu, unique=}", unique.unique_len); + printstr(tcp, (long)unique.unique, unique.unique_len); + tprints("}"); + } + + return 1; +} + +static int drm_get_magic(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_auth auth; + + if (umove(tcp, arg, &auth)) + return 0; + + if (exiting(tcp)) + tprintf(", {magic=%u}", auth.magic); + + return 1; +} + +static int drm_wait_vblank(struct tcb *tcp, const unsigned int code, long arg) +{ + union drm_wait_vblank vblank; + + if (umove(tcp, arg, &vblank)) + return 0; + + if (entering(tcp)) { + tprintf(", {request={type=%u, sequence=%u, signal=%lu}", + vblank.request.type, vblank.request.sequence, + vblank.request.signal); + } else if (exiting(tcp)) { + tprintf(", reply={type=%u, sequence=%u, tval_sec=%ld, tval_usec=%ld}}", + vblank.reply.type, vblank.reply.sequence, + vblank.reply.tval_sec, vblank.reply.tval_usec); + } + + return 1; +} + +static int drm_mode_get_resources(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_card_res res; + + if (umove(tcp, arg, &res)) + return 0; + + if (exiting(tcp)) { + tprintf(", {fb_id_ptr=%p, crtc_id_ptr=%p, connector_id_ptr=%p, " + "encoder_id_ptr=%p, count_fbs=%u, count_crtcs=%u, " + "count_connectors=%u, count_encoders=%u, min_width=%u, " + "max_width=%u, min_height=%u, max_height=%u}", + (void *)res.fb_id_ptr, (void *)res.crtc_id_ptr, + (void *)res.connector_id_ptr, (void *)res.encoder_id_ptr, + res.count_fbs, res.count_crtcs, res.count_connectors, + res.count_encoders, res.min_width, res.max_width, + res.min_height, res.max_height); + } + + return 1; +} + +static void drm_mode_print_modeinfo(struct drm_mode_modeinfo *info) +{ + tprintf("clock=%u, hdisplay=%hu, hsync_start=%hu, hsync_end=%hu, " + "htotal=%hu, hskew=%hu, vdisplay=%hu, vsync_start=%hu, " + "vsync_end=%hu, vtotal=%hu, vscan=%hu, vrefresh=%u, " + "flags=0x%x, type=%u, name=%s", info->clock, info->hdisplay, + info->hsync_start, info->hsync_end, info->htotal, info->hskew, + info->vdisplay, info->vsync_start, info->vsync_end, + info->vtotal, info->vscan, info->vrefresh, info->flags, + info->type, info->name); +} + +static int drm_mode_get_crtc(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_crtc crtc; + + if (umove(tcp, arg, &crtc)) + return 0; + + if (entering(tcp)) { + tprintf(", {crtc_id=%u", crtc.crtc_id); + } else if (exiting(tcp)) { + tprintf(", set_connectors_ptr=%p, count_connectors=%u, " + "fb_id=%u, x=%u, y=%u, gamma_size=%u, mode_valid=%u, " + "mode={", (void *)crtc.set_connectors_ptr, + crtc.count_connectors, crtc.fb_id, crtc.x, crtc.y, + crtc.gamma_size, crtc.mode_valid); + + drm_mode_print_modeinfo(&crtc.mode); + tprintf("}}"); + } + + return 1; +} + +static int drm_mode_set_crtc(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_crtc crtc; + + if (umove(tcp, arg, &crtc)) + return 0; + + if (entering(tcp)) { + tprintf(", {set_connectors_ptr=%p, count_connectors=%u, " + "crtc_id=%u, fb_id=%u, x=%u, y=%u, gamma_size=%u, " + "mode_valid=%u, mode={", (void *)crtc.set_connectors_ptr, + crtc.count_connectors, crtc.crtc_id, crtc.fb_id, crtc.x, + crtc.y, crtc.gamma_size, crtc.mode_valid); + + drm_mode_print_modeinfo(&crtc.mode); + tprintf("}}"); + } + + return 1; +} + +static int drm_mode_cursor(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_cursor cursor; + + if (umove(tcp, arg, &cursor)) + return 0; + + if (entering(tcp)) { + tprintf(", {flags=0x%x, crtc_id=%u, x=%d, y=%d, width=%u, " + "height=%u, handle=%u}", cursor.flags, cursor.crtc_id, + cursor.x, cursor.y, cursor.width, cursor.height, + cursor.handle); + } + + return 1; +} + +static int drm_mode_cursor2(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_cursor2 cursor; + + if (umove(tcp, arg, &cursor)) + return 0; + + if (entering(tcp)) { + tprintf(", {flags=0x%x, crtc_id=%u, x=%d, y=%d, width=%u, " + "height=%u, handle=%u, hot_x=%d, hot_y=%d}", + cursor.flags, cursor.crtc_id, cursor.x, cursor.y, + cursor.width, cursor.height, cursor.handle, + cursor.hot_x, cursor.hot_y); + } + + return 1; +} + +static int drm_mode_get_gamma(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_crtc_lut lut; + + if (umove(tcp, arg, &lut)) + return 0; + + if (entering(tcp)) { + /* We don't print the entire table, just the pointers */ + tprintf(", {crtc_id=%u, gamma_size=%u, red=%p, green=%p, " + "blue=%p}", lut.crtc_id, lut.gamma_size, + (void *)lut.red, (void *)lut.green, (void *)lut.blue); + } + + return 1; +} + +static int drm_mode_set_gamma(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_crtc_lut lut; + + if (umove(tcp, arg, &lut)) + return 0; + + if (entering(tcp)) { + /* We don't print the entire table, just the rgb pointers */ + tprintf(", {crtc_id=%u, gamma_size=%u, red=%p, green=%p, " + "blue=%p}", lut.crtc_id, lut.gamma_size, + (void *)lut.red, (void *)lut.green, (void *)lut.blue); + } + + return 1; +} + +static int drm_mode_get_encoder(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_get_encoder enc; + + if (umove(tcp, arg, &enc)) + return 0; + + if (entering(tcp)) { + tprintf(", {encoder_id=%u", enc.encoder_id); + } else if (exiting(tcp)) { + /* TODO: Print name of encoder type */ + tprintf(", encoder_type=%u, crtc_id=%u, possible_crtcs=0x%x, " + "possible_clones=0x%x}", enc.encoder_type, + enc.crtc_id, enc.possible_crtcs, enc.possible_clones); + } + + return 1; +} + +static int drm_mode_get_connector(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_get_connector con; + + if (umove(tcp, arg, &con)) + return 0; + + /* We could be very verbose here but keep is simple for now */ + if (entering(tcp)) { + tprintf(", {connector_id=%u", con.connector_id); + } else if (exiting(tcp)) { + tprintf(", encoders_ptr=%p, modes_ptr=%p, props_ptr=%p, " + "prop_values_ptr=%p, count_modes=%u, count_props=%u, " + "count_encoders=%u, encoder_id=%u, connector_type=%u, " + "connector_type_id=%u, connection=%u, mm_width=%u, " + "mm_height=%u, subpixel=%u}", (void *)con.encoders_ptr, + (void *)con.modes_ptr, (void *)con.props_ptr, + (void *)con.prop_values_ptr, con.count_modes, + con.count_props, con.count_encoders, con.encoder_id, + con.connector_type, con.connector_type_id, + con.connection, con.mm_width, con.mm_height, + con.subpixel); + } + + return 1; +} + +static int drm_mode_get_property(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_get_property prop; + + if (umove(tcp, arg, &prop)) + return 0; + + if (entering(tcp)) { + tprintf(", {prop_id=%u", prop.prop_id); + } else if (exiting(tcp)) { + tprintf(", values_ptr=%p, enum_blob_ptr=%p, flags=0x%x, " + "name=%s, count_values=%u, count_enum_blobs=%u}", + (void *)prop.values_ptr, (void *)prop.enum_blob_ptr, + prop.flags, prop.name, prop.count_values, + prop.count_enum_blobs); + } + + return 1; +} + +static int drm_mode_set_property(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_connector_set_property prop; + + if (umove(tcp, arg, &prop)) + return 0; + + if (entering(tcp)) { + tprintf(", {value=%Lu, prop_id=%u, connector_id=%u}", + prop.value, prop.prop_id, prop.connector_id); + } + + return 1; +} + +static int drm_mode_get_prop_blob(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_get_blob blob; + + if (umove(tcp, arg, &blob)) + return 0; + + if (entering(tcp)) { + tprintf(", {blob_id=%u", blob.blob_id); + } else if (exiting(tcp)) { + tprintf(", length=%u, data=%p}", blob.length, + (void *)blob.data); + } + + return 1; +} + +static int drm_mode_add_fb(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_fb_cmd cmd; + + if (umove(tcp, arg, &cmd)) + return 0; + + if (entering(tcp)) { + tprintf(", {width=%u, height=%u, pitch=%u, bpp=%u, depth=%u, " + "handle=%u", cmd.width, cmd.height, cmd.pitch, + cmd.bpp, cmd.depth, cmd.handle); + } else if (exiting(tcp)) { + tprintf(", fb_id=%u}", cmd.fb_id); + } + + return 1; +} + +static int drm_mode_get_fb(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_fb_cmd cmd; + + if (umove(tcp, arg, &cmd)) + return 0; + + if (entering(tcp)) { + tprintf(", {fb_id=%u", cmd.fb_id); + } else { + tprintf(", width=%u, height=%u, pitch=%u, bpp=%u, depth=%u, " + "handle=%u}", cmd.width, cmd.height, cmd.pitch, + cmd.bpp, cmd.depth, cmd.handle); + } + + return 1; +} + +static int drm_mode_rm_fb(struct tcb *tcp, const unsigned int code, long arg) +{ + unsigned int handle; + + if (umove(tcp, arg, &handle)) + return 0; + + if (entering(tcp)) + tprintf(", %u", handle); + + return 1; +} + +static int drm_mode_page_flip(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_crtc_page_flip flip; + + if (umove(tcp, arg, &flip)) + return 0; + + if (entering(tcp)) { + tprintf(", {crtc_id=%u, fb_id=%u, flags=0x%x, user_data=0x%Lx}", + flip.crtc_id, flip.fb_id, flip.flags, flip.user_data); + } + + return 1; +} + +static int drm_mode_dirty_fb(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_fb_dirty_cmd cmd; + + if (umove(tcp, arg, &cmd)) + return 0; + + if (entering(tcp)) { + tprintf(", {fb_id=%u, flags=0x%x, color=0x%x, num_clips=%u, " + "clips_ptr=%p}", cmd.fb_id, cmd.flags, cmd.color, + cmd.num_clips, (void *)cmd.clips_ptr); + } + + return 1; +} + +static int drm_mode_create_dumb(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_create_dumb dumb; + + if (umove(tcp, arg, &dumb)) + return 0; + + if (entering(tcp)) { + tprintf(", {width=%u, height=%u, bpp=%u, flags=0x%x", + dumb.width, dumb.height, dumb.bpp, dumb.flags); + } else if (exiting(tcp)) { + tprintf(", handle=%u, pitch=%u, size=%Lu}", dumb.handle, + dumb.pitch, dumb.size); + } + + return 1; +} + +static int drm_mode_map_dumb(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_map_dumb dumb; + + if (umove(tcp, arg, &dumb)) + return 0; + + if (entering(tcp)) { + tprintf(", {handle=%u", dumb.handle); + } else if (exiting(tcp)) { + tprintf(", offset=%Lu}", dumb.offset); + } + + return 1; +} + +static int drm_mode_destroy_dumb(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_mode_destroy_dumb dumb; + + if (umove(tcp, arg, &dumb)) + return 0; + + if (entering(tcp)) + tprintf(", {handle=%u}", dumb.handle); + + return 1; +} + +static int drm_gem_close(struct tcb *tcp, const unsigned int code, long arg) +{ + struct drm_gem_close close; + + if (umove(tcp, arg, &close)) + return 0; + + if (entering(tcp)) + tprintf(", {handle=%u}", close.handle); + + return 1; +} + int drm_ioctl(struct tcb *tcp, const unsigned int code, long arg) { /* Check for device specific ioctls */ @@ -112,6 +569,59 @@ int drm_ioctl(struct tcb *tcp, const unsigned int code, long arg) return drm_i915_ioctl(tcp, code, arg); } + switch (code) { + case DRM_IOCTL_VERSION: + return drm_version(tcp, code, arg); + case DRM_IOCTL_GET_UNIQUE: + return drm_get_unique(tcp, code, arg); + case DRM_IOCTL_GET_MAGIC: + return drm_get_magic(tcp, code, arg); + case DRM_IOCTL_WAIT_VBLANK: + return drm_wait_vblank(tcp, code, arg); + case DRM_IOCTL_MODE_GETRESOURCES: + return drm_mode_get_resources(tcp, code, arg); + case DRM_IOCTL_MODE_GETCRTC: + return drm_mode_get_crtc(tcp, code, arg); + case DRM_IOCTL_MODE_SETCRTC: + return drm_mode_set_crtc(tcp, code, arg); + case DRM_IOCTL_MODE_CURSOR: + return drm_mode_cursor(tcp, code, arg); + case DRM_IOCTL_MODE_CURSOR2: + return drm_mode_cursor2(tcp, code, arg); + case DRM_IOCTL_MODE_GETGAMMA: + return drm_mode_get_gamma(tcp, code, arg); + case DRM_IOCTL_MODE_SETGAMMA: + return drm_mode_set_gamma(tcp, code, arg); + case DRM_IOCTL_MODE_GETENCODER: + return drm_mode_get_encoder(tcp, code, arg); + case DRM_IOCTL_MODE_GETCONNECTOR: + return drm_mode_get_connector(tcp, code, arg); + case DRM_IOCTL_MODE_GETPROPERTY: + return drm_mode_get_property(tcp, code, arg); + case DRM_IOCTL_MODE_SETPROPERTY: + return drm_mode_set_property(tcp, code, arg); + case DRM_IOCTL_MODE_GETPROPBLOB: + return drm_mode_get_prop_blob(tcp, code, arg); + case DRM_IOCTL_MODE_GETFB: + return drm_mode_get_fb(tcp, code, arg); + case DRM_IOCTL_MODE_ADDFB: + return drm_mode_add_fb(tcp, code, arg); + case DRM_IOCTL_MODE_RMFB: + return drm_mode_rm_fb(tcp, code, arg); + case DRM_IOCTL_MODE_PAGE_FLIP: + return drm_mode_page_flip(tcp, code, arg); + case DRM_IOCTL_MODE_DIRTYFB: + return drm_mode_dirty_fb(tcp, code, arg); + case DRM_IOCTL_MODE_CREATE_DUMB: + return drm_mode_create_dumb(tcp, code, arg); + case DRM_IOCTL_MODE_MAP_DUMB: + return drm_mode_map_dumb(tcp, code, arg); + case DRM_IOCTL_MODE_DESTROY_DUMB: + return drm_mode_destroy_dumb(tcp, code, arg); + case DRM_IOCTL_GEM_CLOSE: + return drm_gem_close(tcp, code, arg); + } + /* Free any allocated private data */ if (exiting(tcp) && tcp->priv_data != NULL) { free(tcp->priv_data);
This patch adds many of the DRM and KMS ioctls. The rest can be added as needed. * drm.c: Decode DRM_IOCTL_VERSION * drm.c: Decode DRM_IOCTL_GET_UNIQUE * drm.c: Decode DRM_IOCTL_GET_MAGIC * drm.c: Decode DRM_IOCTL_WAIT_VBLANK * drm.c: Decode DRM_IOCTL_MODE_GETRESOURCES * drm.c: Decode DRM_IOCTL_MODE_GETCRTC * drm.c: Decode DRM_IOCTL_MODE_SETCRTC * drm.c: Decode DRM_IOCTL_MODE_CURSOR * drm.c: Decode DRM_IOCTL_MODE_CURSOR2 * drm.c: Decode DRM_IOCTL_MODE_GETGAMMA * drm.c: Decode DRM_IOCTL_MODE_SETGAMMA * drm.c: Decode DRM_IOCTL_MODE_GETENCODER * drm.c: Decode DRM_IOCTL_MODE_GETCONNECTOR * drm.c: Decode DRM_IOCTL_MODE_GETPROPERTY * drm.c: Decode DRM_IOCTL_MODE_SETPROPERTY * drm.c: Decode DRM_IOCTL_MODE_GETPROPBLOB * drm.c: Decode DRM_IOCTL_MODE_GETFB * drm.c: Decode DRM_IOCTL_MODE_ADDFB * drm.c: Decode DRM_IOCTL_MODE_RMFB * drm.c: Decode DRM_IOCTL_MODE_PAGE_FLIP * drm.c: Decode DRM_IOCTL_DIRTYFB * drm.c: Decode DRM_IOCTL_CREATE_DUMB * drm.c: Decode DRM_IOCTL_MAP_DUMB * drm.c: Decode DRM_IOCTL_DESTROY_DUMB * drm.c: Decode DRM_IOCTL_GEM_CLOSE Signed-off-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com> --- drm.c | 510 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 510 insertions(+)