diff --git a/repos/base/run/platform_drv.inc b/repos/base/run/platform_drv.inc index ffd9792e8..5d35ceee0 100644 --- a/repos/base/run/platform_drv.inc +++ b/repos/base/run/platform_drv.inc @@ -38,7 +38,12 @@ proc platform_drv_policy {} { - } + + + + + + } } else { return {} } diff --git a/repos/dde_linux/intel_fb.list b/repos/dde_linux/intel_fb.list index 011cfa1f0..d74d9ac37 100644 --- a/repos/dde_linux/intel_fb.list +++ b/repos/dde_linux/intel_fb.list @@ -6,9 +6,14 @@ linux-3.14.5/drivers/char/agp/backend.c linux-3.14.5/drivers/i2c/i2c-core.c linux-3.14.5/drivers/i2c/i2c-core.h linux-3.14.5/drivers/i2c/i2c-boardinfo.c +linux-3.14.5/drivers/i2c/algos/i2c-algo-bit.c linux-3.14.5/drivers/gpu/drm/drm_mm.c linux-3.14.5/drivers/gpu/drm/drm_crtc.c +linux-3.14.5/drivers/gpu/drm/drm_crtc_helper.c linux-3.14.5/drivers/gpu/drm/drm_edid.c +linux-3.14.5/drivers/gpu/drm/drm_modes.c +linux-3.14.5/drivers/gpu/drm/drm_dp_helper.c +linux-3.14.5/drivers/gpu/drm/drm_fb_helper.c linux-3.14.5/drivers/gpu/drm/i915/i915_dma.c linux-3.14.5/drivers/gpu/drm/i915/i915_drv.c linux-3.14.5/drivers/gpu/drm/i915/i915_drv.h @@ -18,15 +23,26 @@ linux-3.14.5/drivers/gpu/drm/i915/i915_reg.h linux-3.14.5/drivers/gpu/drm/i915/i915_gem_gtt.c linux-3.14.5/drivers/gpu/drm/i915/i915_irq.c linux-3.14.5/drivers/gpu/drm/i915/intel_bios.h +linux-3.14.5/drivers/gpu/drm/i915/intel_bios.c +linux-3.14.5/drivers/gpu/drm/i915/intel_crt.c linux-3.14.5/drivers/gpu/drm/i915/intel_ddi.c linux-3.14.5/drivers/gpu/drm/i915/intel_dp.c linux-3.14.5/drivers/gpu/drm/i915/intel_drv.h +linux-3.14.5/drivers/gpu/drm/i915/intel_fbdev.c +linux-3.14.5/drivers/gpu/drm/i915/intel_hdmi.c linux-3.14.5/drivers/gpu/drm/i915/intel_ringbuffer.h linux-3.14.5/drivers/gpu/drm/i915/intel_display.c linux-3.14.5/drivers/gpu/drm/i915/intel_panel.c linux-3.14.5/drivers/gpu/drm/i915/intel_uncore.c linux-3.14.5/drivers/gpu/drm/i915/intel_lvds.c linux-3.14.5/drivers/gpu/drm/i915/intel_i2c.c +linux-3.14.5/drivers/gpu/drm/i915/intel_overlay.c +linux-3.14.5/drivers/gpu/drm/i915/intel_pm.c +linux-3.14.5/drivers/gpu/drm/i915/intel_modes.c +linux-3.14.5/drivers/gpu/drm/i915/intel_sideband.c +linux-3.14.5/drivers/gpu/drm/i915/intel_sdvo.c +linux-3.14.5/drivers/gpu/drm/i915/intel_sdvo_regs.h +linux-3.14.5/drivers/video/fbcmap.c linux-3.14.5/include/asm-generic/atomic64.h linux-3.14.5/include/asm-generic/ioctl.h linux-3.14.5/include/asm-generic/getorder.h @@ -38,14 +54,18 @@ linux-3.14.5/include/asm-generic/bitops/fls64.h linux-3.14.5/include/asm-generic/bitops/non-atomic.h linux-3.14.5/include/linux/agp_backend.h linux-3.14.5/include/linux/list.h +linux-3.14.5/include/linux/list_sort.h linux-3.14.5/include/linux/log2.h linux-3.14.5/include/linux/pci_ids.h +linux-3.14.5/include/linux/hdmi.h linux-3.14.5/include/linux/i2c-algo-bit.h linux-3.14.5/include/linux/i2c.h +linux-3.14.5/include/linux/pm_runtime.h linux-3.14.5/include/drm/intel-gtt.h linux-3.14.5/include/drm/i915_pciids.h linux-3.14.5/include/drm/i915_drm.h linux-3.14.5/include/drm/drm_dp_helper.h +linux-3.14.5/include/drm/drm_fb_helper.h linux-3.14.5/include/drm/drm_mm.h linux-3.14.5/include/drm/drm_crtc.h linux-3.14.5/include/drm/drm_crtc_helper.h @@ -59,5 +79,6 @@ linux-3.14.5/include/uapi/drm/drm_fourcc.h linux-3.14.5/include/uapi/drm/drm_mode.h linux-3.14.5/include/uapi/linux/byteorder/little_endian.h linux-3.14.5/include/uapi/linux/swab.h +linux-3.14.5/include/uapi/linux/fb.h linux-3.14.5/arch/x86/include/asm/agp.h - +linux-3.14.5/lib/list_sort.c diff --git a/repos/dde_linux/lib/mk/intel_fb_drv.mk b/repos/dde_linux/lib/mk/intel_fb_drv.mk index d5a5fd05d..f1df2b8f4 100644 --- a/repos/dde_linux/lib/mk/intel_fb_drv.mk +++ b/repos/dde_linux/lib/mk/intel_fb_drv.mk @@ -6,20 +6,24 @@ LIBS += intel_fb_include SRC_C := SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/char/agp/*.c)) SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/i2c/*.c)) +SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/i2c/algos/*.c)) SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/gpu/drm/*.c)) SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/gpu/drm/i915/*.c)) - -#SRC_C := $(filter-out intel_dp.c,$(SRC_C)) -#SRC_C := intel_panel.c +SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/drivers/video/*.c)) +SRC_C += $(notdir $(wildcard $(LX_CONTRIB_DIR)/lib/*.c)) # # Reduce build noise of compiling contrib code # CC_WARN = -Wall -Wno-uninitialized -Wno-unused-but-set-variable \ - -Wno-unused-variable -Wno-unused-function + -Wno-unused-variable -Wno-unused-function \ + -Wno-pointer-arith -Wno-pointer-sign vpath %.c $(LX_CONTRIB_DIR)/drivers/char/agp vpath %.c $(LX_CONTRIB_DIR)/drivers/i2c +vpath %.c $(LX_CONTRIB_DIR)/drivers/i2c/algos vpath %.c $(LX_CONTRIB_DIR)/drivers/gpu/drm/i915 vpath %.c $(LX_CONTRIB_DIR)/drivers/gpu/drm +vpath %.c $(LX_CONTRIB_DIR)/drivers/video +vpath %.c $(LX_CONTRIB_DIR)/lib diff --git a/repos/dde_linux/patches/intel_fb_16bit.patch b/repos/dde_linux/patches/intel_fb_16bit.patch new file mode 100644 index 000000000..1f88d92f4 --- /dev/null +++ b/repos/dde_linux/patches/intel_fb_16bit.patch @@ -0,0 +1,13 @@ +diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c +index 39eac99..3e67601 100644 +--- a/drivers/gpu/drm/i915/intel_fbdev.c ++++ b/drivers/gpu/drm/i915/intel_fbdev.c +@@ -293,7 +293,7 @@ void intel_fbdev_initial_config(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + + /* Due to peculiar init order wrt to hpd handling this is separate. */ +- drm_fb_helper_initial_config(&dev_priv->fbdev->helper, 32); ++ drm_fb_helper_initial_config(&dev_priv->fbdev->helper, 16); + } + + void intel_fbdev_fini(struct drm_device *dev) diff --git a/repos/dde_linux/patches/intel_fb_edp.patch b/repos/dde_linux/patches/intel_fb_edp.patch new file mode 100644 index 000000000..6198136de --- /dev/null +++ b/repos/dde_linux/patches/intel_fb_edp.patch @@ -0,0 +1,55 @@ +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 2688f6d..ca178a2 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -811,7 +811,9 @@ intel_dp_compute_config(struct intel_encoder *encoder, + struct intel_crtc *intel_crtc = encoder->new_crtc; + struct intel_connector *intel_connector = intel_dp->attached_connector; + int lane_count, clock; ++ int min_lane_count = 1; + int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd); ++ int min_clock = 0; + int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; + int bpp, mode_rate; + static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; +@@ -844,19 +846,33 @@ intel_dp_compute_config(struct intel_encoder *encoder, + /* Walk through all bpp values. Luckily they're all nicely spaced with 2 + * bpc in between. */ + bpp = pipe_config->pipe_bpp; +- if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp && +- dev_priv->vbt.edp_bpp < bpp) { +- DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n", +- dev_priv->vbt.edp_bpp); +- bpp = dev_priv->vbt.edp_bpp; ++ if (is_edp(intel_dp)) { ++ if (dev_priv->vbt.edp_bpp && dev_priv->vbt.edp_bpp < bpp) { ++ DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n", ++ dev_priv->vbt.edp_bpp); ++ bpp = dev_priv->vbt.edp_bpp; ++ } ++ ++ if (dev_priv->vbt.edp_lanes) { ++ min_lane_count = min(dev_priv->vbt.edp_lanes, ++ max_lane_count); ++ DRM_DEBUG_KMS("using min %u lanes per VBT\n", ++ min_lane_count); ++ } ++ ++ if (dev_priv->vbt.edp_rate) { ++ min_clock = min(dev_priv->vbt.edp_rate >> 3, max_clock); ++ DRM_DEBUG_KMS("using min %02x link bw per VBT\n", ++ bws[min_clock]); ++ } + } + + for (; bpp >= 6*3; bpp -= 2*3) { + mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, + bpp); + +- for (clock = 0; clock <= max_clock; clock++) { +- for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { ++ for (lane_count = min_lane_count; lane_count <= max_lane_count; lane_count <<= 1) { ++ for (clock = min_clock; clock <= max_clock; clock++) { + link_clock = drm_dp_bw_code_to_link_rate(bws[clock]); + link_avail = intel_dp_max_data_rate(link_clock, + lane_count); diff --git a/repos/dde_linux/patches/intel_fb_report.patch b/repos/dde_linux/patches/intel_fb_report.patch new file mode 100644 index 000000000..0231c82c0 --- /dev/null +++ b/repos/dde_linux/patches/intel_fb_report.patch @@ -0,0 +1,12 @@ +diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c +index 98a0363..b00c6b7 100644 +--- a/drivers/gpu/drm/drm_fb_helper.c ++++ b/drivers/gpu/drm/drm_fb_helper.c +@@ -1505,6 +1505,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) + modeset->mode = NULL; + } + } ++ update_genode_report(); + out: + kfree(crtcs); + kfree(modes); diff --git a/repos/dde_linux/patches/intel_fb_update.patch b/repos/dde_linux/patches/intel_fb_update.patch new file mode 100644 index 000000000..a73f5af9c --- /dev/null +++ b/repos/dde_linux/patches/intel_fb_update.patch @@ -0,0 +1,29 @@ +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 963639d..f926f21 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9867,6 +9867,11 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set, + config->mode_changed = true; + } + ++ /** ++ * Adaption made for Genode context: ensure connector always uses a new fb ++ */ ++ config->fb_changed = true; ++ + DRM_DEBUG_KMS("computed changes for [CRTC:%d], mode_changed=%d, fb_changed=%d\n", + set->crtc->base.id, config->mode_changed, config->fb_changed); + } +diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c +index 3b7d32d..637f713 100644 +--- a/drivers/gpu/drm/drm_crtc.c ++++ b/drivers/gpu/drm/drm_crtc.c +@@ -487,7 +487,7 @@ static void drm_framebuffer_free_bug(struct kref *kref) + static void __drm_framebuffer_unreference(struct drm_framebuffer *fb) + { + DRM_DEBUG("FB ID: %d\n", fb->base.id); +- kref_put(&fb->refcount, drm_framebuffer_free_bug); ++ /*kref_put(&fb->refcount, drm_framebuffer_free_bug);*/ + } + + /* dev->mode_config.fb_lock must be held! */ diff --git a/repos/dde_linux/patches/intel_fb_x201.patch b/repos/dde_linux/patches/intel_fb_x201.patch new file mode 100644 index 000000000..c5b44d3a3 --- /dev/null +++ b/repos/dde_linux/patches/intel_fb_x201.patch @@ -0,0 +1,15 @@ ++++ a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -1034,7 +1034,11 @@ + unsigned int num_entries, + bool unused) + { +- intel_gtt_clear_range(first_entry, num_entries); ++ if (!unused) ++ intel_gtt_clear_range(first_entry, num_entries); ++ else ++ /* Fixes DMA issues on Lenovo X201 */ ++ printk("Disable %s for Genode\n", __func__); + } + + diff --git a/repos/dde_linux/ports/dde_linux.hash b/repos/dde_linux/ports/dde_linux.hash index d5ac0c7df..41a9e1172 100644 --- a/repos/dde_linux/ports/dde_linux.hash +++ b/repos/dde_linux/ports/dde_linux.hash @@ -1 +1 @@ -630e489f7f95892f1f70144ab363024e01dd7851 +e98972035a5cb6cb8651d9ec0f7a30de50713a69 diff --git a/repos/dde_linux/ports/dde_linux.port b/repos/dde_linux/ports/dde_linux.port index 4f9f0847f..50f36fc01 100644 --- a/repos/dde_linux/ports/dde_linux.port +++ b/repos/dde_linux/ports/dde_linux.port @@ -4,9 +4,6 @@ DOWNLOADS := dwc_otg.git usb.archive lxip.archive intel_fb.archive wifi.archiv libnl.archive wpa_supplicant.archive \ fw_6000.archive fw_6205a.archive fw_6205b.archive fw_7260.archive fw_7265.archive -# XXX disable all parts except for intel_fb -DOWNLOADS := intel_fb.archive - # # Tools # @@ -175,7 +172,11 @@ PATCH_OPT(patches/libnl.patch) := -p1 -d ${DIR(libnl)} # WPA supplicant PATCH_OPT(patches/wpa_supplicant.patch) := -p1 -d ${DIR(wpa_supplicant)} -# XXX disable all patches of non-intel_fb subsystems -PATCHES := +# Intel fb +PATCH_OPT(patches/intel_fb_16bit.patch) := -p1 -d ${DIR(intel_fb)} +PATCH_OPT(patches/intel_fb_edp.patch) := -p1 -d ${DIR(intel_fb)} +PATCH_OPT(patches/intel_fb_update.patch) := -p1 -d ${DIR(intel_fb)} +PATCH_OPT(patches/intel_fb_x201.patch) := -p1 -d ${DIR(intel_fb)} +PATCH_OPT(patches/intel_fb_report.patch) := -p1 -d ${DIR(intel_fb)} # vi: set ft=make : diff --git a/repos/dde_linux/run/intel_fb.run b/repos/dde_linux/run/intel_fb.run index 21e339bbc..352f04091 100644 --- a/repos/dde_linux/run/intel_fb.run +++ b/repos/dde_linux/run/intel_fb.run @@ -6,6 +6,8 @@ set build_components { core init drivers/timer drivers/framebuffer/intel + test/framebuffer + server/report_rom } source ${genode_dir}/repos/base/run/platform_drv.inc @@ -15,22 +17,12 @@ build $build_components create_boot_directory -proc platform_drv_policy {} { - return { - - - - - - } -} - # # Generate config # append config { - + @@ -55,9 +47,21 @@ append config { + + + + + + + + + + + + + - } @@ -70,6 +74,7 @@ install_config $config # generic modules set boot_modules { core init timer intel_fb_drv + test-framebuffer report_rom } append_platform_drv_boot_modules diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/README b/repos/dde_linux/src/drivers/framebuffer/intel/README new file mode 100644 index 000000000..87b079138 --- /dev/null +++ b/repos/dde_linux/src/drivers/framebuffer/intel/README @@ -0,0 +1,55 @@ +This driver is for Intel i915 compatible graphic cards. + +Default behaviour +~~~~~~~~~~~~~~~~~ +When no configuration is provided to the driver, it will switch on all devices +the graphic card is initially connected to. It will use the best resolution as +provided by the BIOS or EDID information from the display devices for each +connector. The virtual resolution delivered to the client is the maximum in +width and height of the different connectors. The framebuffer memory is +directly exported to the client of the driver. When newly connected devices are +detected by the hardware, the new connectors are enabled, probed, and again the +'best' resolution will be chosen for the device. Nevertheless, it won't have an +effect on the virtual resolution. + +Configuration +~~~~~~~~~~~~~ +Each of the connector can be configured explicitly in terms of resolution and +whether it should be enabled or not. This looks like the following: + +! +! +! + +When the configuration changes during run-time, the driver will adapt to it. In +this case it will also change the current virtual resolution to the maximum of +the configured resolutions in width and height, and it will inform its client +about the change in resolution. + +It is possible to run the driver in 'buffered' mode, which means it does not +export the framebuffer memory directly to the client, but provides a simple RAM +dataspace instead. The copying from the RAM dataspace to the framebuffer memory +is done by the framebuffer driver when triggered by a refresh operation. This +option can alleviate tearing effects, and has to be enabled via the +configuration like this: + +! + +To present all available connectors and their possible resolutions to the user +the driver is able to export a corresponding report ROM. This has to be +configured too, like in the following: + +! +! +! + +The exported report has the following format: + +! +! +! +! ... +! +! ... +! + diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/dummies.cc b/repos/dde_linux/src/drivers/framebuffer/intel/dummies.cc index 6efed3db1..4c58a9ea9 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/dummies.cc +++ b/repos/dde_linux/src/drivers/framebuffer/intel/dummies.cc @@ -42,41 +42,12 @@ struct timespec ns_to_timespec(const s64 nsec) return { 0, 0 }; } -void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize, char *linebuf, size_t linebuflen, bool ascii) -{ - TRACE_AND_STOP; -} - -bool mod_delayed_work(struct workqueue_struct *, struct delayed_work *, unsigned long) -{ - TRACE_AND_STOP; - return false; -} - bool capable(int cap) { TRACE_AND_STOP; return false; } -int drm_dp_bw_code_to_link_rate(u8 link_bw) -{ - TRACE_AND_STOP; - return -1; -} - -bool intel_fbc_enabled(struct drm_device *dev) -{ - TRACE_AND_STOP; - return false; -} - -int i2c_dp_aux_add_bus(struct i2c_adapter *adapter) -{ - TRACE_AND_STOP; - return -1; -} - int i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { TRACE_AND_STOP; @@ -101,18 +72,6 @@ int i915_gem_get_tiling(struct drm_device *dev, void *data, struct drm_file *fil return -1; } -int intel_overlay_put_image(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - TRACE_AND_STOP; - return -1; -} - -int intel_overlay_attrs(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - TRACE_AND_STOP; - return -1; -} - bool flush_delayed_work(struct delayed_work *dwork) { TRACE_AND_STOP; @@ -135,5 +94,49 @@ void device_unregister(struct device *dev) TRACE_AND_STOP; } +int i2c_algo_bit_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) +{ + TRACE_AND_STOP; + return -1; +} + +u32 i2c_algo_bit_func(struct i2c_adapter *adap) +{ + TRACE_AND_STOP; + return 0; +} + +void i915_setup_sysfs(struct drm_device *dev_priv) +{ + TRACE; +} + +int acpi_video_register(void) +{ + TRACE; + return 0; +} + +void ips_link_to_i915_driver(void) +{ + TRACE; +} + +void spin_lock(spinlock_t *lock) +{ + TRACE; +} + +void drm_sysfs_hotplug_event(struct drm_device *dev) +{ + TRACE; +} + +const char *acpi_dev_name(struct acpi_device *) +{ + TRACE_AND_STOP; + return 0; +} } /* extern "C" */ + diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/gen_dummies.h b/repos/dde_linux/src/drivers/framebuffer/intel/gen_dummies.h index 3cfcdc371..feabb4819 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/gen_dummies.h +++ b/repos/dde_linux/src/drivers/framebuffer/intel/gen_dummies.h @@ -4,12 +4,6 @@ bool access_ok(int access, void *addr, size_t size) return -1; } -int acpi_video_register(void) -{ - TRACE_AND_STOP; - return -1; -} - void acpi_video_unregister(void) { TRACE_AND_STOP; @@ -20,28 +14,11 @@ void add_wait_queue(wait_queue_head_t *, wait_queue_t *) TRACE_AND_STOP; } -void assert_spin_locked(spinlock_t *lock) -{ - TRACE_AND_STOP; -} - void atomic_set_mask(unsigned int mask, atomic_t *v) { TRACE_AND_STOP; } -bool cancel_delayed_work_sync(struct delayed_work *work) -{ - TRACE_AND_STOP; - return -1; -} - -bool cancel_work_sync(struct work_struct *work) -{ - TRACE_AND_STOP; - return -1; -} - void console_lock(void) { TRACE_AND_STOP; @@ -70,11 +47,6 @@ size_t copy_to_user(void *dst, void const *src, size_t len) return -1; } -void cpu_relax(void) -{ - TRACE_AND_STOP; -} - void destroy_timer_on_stack(struct timer_list *timer) { TRACE_AND_STOP; @@ -102,11 +74,6 @@ void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, e TRACE_AND_STOP; } -void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode) -{ - TRACE_AND_STOP; -} - int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, int *max_error, struct timeval *vblank_time, unsigned flags, const struct drm_crtc *refcrtc, const struct drm_display_mode *mode) { TRACE_AND_STOP; @@ -128,40 +95,6 @@ void drm_clflush_virt_range(char *addr, unsigned long length) TRACE_AND_STOP; } -bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE], int lane_count) -{ - TRACE_AND_STOP; - return -1; -} - -bool drm_dp_clock_recovery_ok(const u8 link_status[DP_LINK_STATUS_SIZE], int lane_count) -{ - TRACE_AND_STOP; - return -1; -} - -u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE], int lane) -{ - TRACE_AND_STOP; - return -1; -} - -u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE], int lane) -{ - TRACE_AND_STOP; - return -1; -} - -void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) -{ - TRACE_AND_STOP; -} - -void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) -{ - TRACE_AND_STOP; -} - int drm_gem_create_mmap_offset(struct drm_gem_object *obj) { TRACE_AND_STOP; @@ -218,11 +151,6 @@ void drm_gem_object_unreference(struct drm_gem_object *obj) TRACE_AND_STOP; } -void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) -{ - TRACE_AND_STOP; -} - int drm_gem_prime_fd_to_handle(struct drm_device *dev, struct drm_file *file_priv, int prime_fd, uint32_t *handle) { TRACE_AND_STOP; @@ -257,29 +185,6 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) return -1; } -bool drm_helper_hpd_irq_event(struct drm_device *dev) -{ - TRACE_AND_STOP; - return -1; -} - -int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, struct drm_mode_fb_cmd2 *mode_cmd) -{ - TRACE_AND_STOP; - return -1; -} - -void drm_helper_move_panel_connectors_to_head(struct drm_device *) -{ - TRACE_AND_STOP; -} - -int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY) -{ - TRACE_AND_STOP; - return -1; -} - long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { TRACE_AND_STOP; @@ -292,58 +197,6 @@ int drm_irq_uninstall(struct drm_device *dev) return -1; } -void drm_kms_helper_hotplug_event(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - -void drm_kms_helper_poll_disable(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - -void drm_kms_helper_poll_enable(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - -void drm_kms_helper_poll_fini(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - -void drm_kms_helper_poll_init(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - -void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src) -{ - TRACE_AND_STOP; -} - -void drm_mode_debug_printmodeline(const struct drm_display_mode *mode) -{ - TRACE_AND_STOP; -} - -struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, const struct drm_display_mode *mode) -{ - TRACE_AND_STOP; - return NULL; -} - -bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2) -{ - TRACE_AND_STOP; - return -1; -} - -void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) -{ - TRACE_AND_STOP; -} - int drm_noop(struct drm_device *dev, void *data, struct drm_file *file_priv) { TRACE_AND_STOP; @@ -400,17 +253,6 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc, struct drm_pending_ TRACE_AND_STOP; } -int drm_sysfs_connector_add(struct drm_connector *connector) -{ - TRACE_AND_STOP; - return -1; -} - -void drm_sysfs_connector_remove(struct drm_connector *connector) -{ - TRACE_AND_STOP; -} - void drm_vblank_cleanup(struct drm_device *dev) { TRACE_AND_STOP; @@ -422,21 +264,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc) return -1; } -void drm_vblank_off(struct drm_device *dev, int crtc) -{ - TRACE_AND_STOP; -} - -void drm_vblank_post_modeset(struct drm_device *dev, int crtc) -{ - TRACE_AND_STOP; -} - -void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) -{ - TRACE_AND_STOP; -} - void drm_vblank_put(struct drm_device *dev, int crtc) { TRACE_AND_STOP; @@ -459,12 +286,6 @@ void drm_vma_node_unmap(struct drm_vma_offset_node *node, struct address_space * TRACE_AND_STOP; } -struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) -{ - TRACE_AND_STOP; - return NULL; -} - int fault_in_multipages_readable(const char __user *uaddr, int size) { TRACE_AND_STOP; @@ -503,37 +324,12 @@ void free_pages(unsigned long addr, unsigned int order) TRACE_AND_STOP; } -void gen6_rps_boost(struct drm_i915_private *dev_priv) -{ - TRACE_AND_STOP; -} - -void gen6_rps_idle(struct drm_i915_private *dev_priv) -{ - TRACE_AND_STOP; -} - -void gen6_set_rps(struct drm_device *dev, u8 val) -{ - TRACE_AND_STOP; -} - -void gen6_update_ring_freq(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order) { TRACE_AND_STOP; return -1; } -void getrawmonotonic(struct timespec *ts) -{ - TRACE_AND_STOP; -} - unsigned long get_seconds(void) { TRACE_AND_STOP; @@ -577,12 +373,6 @@ void i915_gem_context_free(struct kref *ctx_ref) TRACE_AND_STOP; } -int __must_check i915_gem_context_init(struct drm_device *dev) -{ - TRACE_AND_STOP; - return -1; -} - int i915_gem_evict_everything(struct drm_device *dev) { TRACE_AND_STOP; @@ -634,11 +424,6 @@ int i915_save_state(struct drm_device *dev) return -1; } -void i915_setup_sysfs(struct drm_device *dev_priv) -{ - TRACE_AND_STOP; -} - int i915_switch_context(struct intel_ring_buffer *ring, struct drm_file *file, int to_id) { TRACE_AND_STOP; @@ -650,84 +435,11 @@ void i915_teardown_sysfs(struct drm_device *dev_priv) TRACE_AND_STOP; } -void i915_update_gfx_val(struct drm_i915_private *dev_priv) -{ - TRACE_AND_STOP; -} - -void ilk_wm_get_hw_state(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - -void intel_attach_broadcast_rgb_property(struct drm_connector *connector) -{ - TRACE_AND_STOP; -} - -void intel_attach_force_audio_property(struct drm_connector *connector) -{ - TRACE_AND_STOP; -} - -void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv) -{ - TRACE_AND_STOP; -} - -void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv) -{ - TRACE_AND_STOP; -} - -void intel_cleanup_overlay(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) { TRACE_AND_STOP; } -int intel_connector_update_modes(struct drm_connector *connector, struct edid *edid) -{ - TRACE_AND_STOP; - return -1; -} - -void intel_crt_init(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - -int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter) -{ - TRACE_AND_STOP; - return -1; -} - -void intel_disable_fbc(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - -bool intel_display_power_enabled(struct drm_device *dev, enum intel_display_power_domain domain) -{ - TRACE_AND_STOP; - return -1; -} - -void intel_display_power_get(struct drm_device *dev, enum intel_display_power_domain domain) -{ - TRACE_AND_STOP; -} - -void intel_display_power_put(struct drm_device *dev, enum intel_display_power_domain domain) -{ - TRACE_AND_STOP; -} - bool intel_dsi_init(struct drm_device *dev) { TRACE_AND_STOP; @@ -739,82 +451,6 @@ void intel_dvo_init(struct drm_device *dev) TRACE_AND_STOP; } -void intel_enable_gt_powersave(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - -void intel_fini_runtime_pm(struct drm_i915_private *dev_priv) -{ - TRACE_AND_STOP; -} - -void intel_gpu_ips_init(struct drm_i915_private *dev_priv) -{ - TRACE_AND_STOP; -} - -void intel_gpu_ips_teardown(void) -{ - TRACE_AND_STOP; -} - -bool intel_hdmi_compute_config(struct intel_encoder *encoder, struct intel_crtc_config *pipe_config) -{ - TRACE_AND_STOP; - return -1; -} - -void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) -{ - TRACE_AND_STOP; -} - -void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, struct intel_connector *intel_connector) -{ - TRACE_AND_STOP; -} - -int intel_init_blt_ring_buffer(struct drm_device *dev) -{ - TRACE_AND_STOP; - return -1; -} - -int intel_init_bsd_ring_buffer(struct drm_device *dev) -{ - TRACE_AND_STOP; - return -1; -} - -void intel_init_clock_gating(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - -int intel_init_render_ring_buffer(struct drm_device *dev) -{ - TRACE_AND_STOP; - return -1; -} - -void intel_init_runtime_pm(struct drm_i915_private *dev_priv) -{ - TRACE_AND_STOP; -} - -int intel_init_vebox_ring_buffer(struct drm_device *dev) -{ - TRACE_AND_STOP; - return -1; -} - -int intel_overlay_switch_off(struct intel_overlay *overlay) -{ - TRACE_AND_STOP; - return -1; -} - void intel_plane_disable(struct drm_plane *plane) { TRACE_AND_STOP; @@ -825,11 +461,6 @@ void intel_plane_restore(struct drm_plane *plane) TRACE_AND_STOP; } -void intel_power_domains_remove(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) { TRACE_AND_STOP; @@ -881,38 +512,6 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) TRACE_AND_STOP; } -void intel_runtime_pm_get(struct drm_i915_private *dev_priv) -{ - TRACE_AND_STOP; -} - -void intel_runtime_pm_put(struct drm_i915_private *dev_priv) -{ - TRACE_AND_STOP; -} - -u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, enum intel_sbi_destination destination) -{ - TRACE_AND_STOP; - return -1; -} - -void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value, enum intel_sbi_destination destination) -{ - TRACE_AND_STOP; -} - -bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) -{ - TRACE_AND_STOP; - return -1; -} - -void intel_setup_overlay(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - int intel_sprite_get_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv) { TRACE_AND_STOP; @@ -925,26 +524,11 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data, struct drm_fil return -1; } -void intel_suspend_hw(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - void intel_tv_init(struct drm_device *dev) { TRACE_AND_STOP; } -void intel_update_fbc(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - -void intel_update_watermarks(struct drm_crtc *crtc) -{ - TRACE_AND_STOP; -} - void io_mapping_free(struct io_mapping *mapping) { TRACE_AND_STOP; @@ -966,50 +550,17 @@ void io_schedule(void) TRACE_AND_STOP; } -void iounmap(volatile void *addr) -{ - TRACE_AND_STOP; -} - -bool ironlake_set_drps(struct drm_device *dev, u8 val) -{ - TRACE_AND_STOP; - return -1; -} - -void ironlake_teardown_rc6(struct drm_device *dev) -{ - TRACE_AND_STOP; -} - void kmem_cache_destroy(struct kmem_cache *) { TRACE_AND_STOP; } -void *kmem_cache_zalloc(struct kmem_cache *k, gfp_t flags) -{ - TRACE_AND_STOP; - return NULL; -} - int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, char *envp[]) { TRACE_AND_STOP; return -1; } -void kref_get(struct kref *kref) -{ - TRACE_AND_STOP; -} - -int kref_put(struct kref *kref, void (*release) (struct kref *kref)) -{ - TRACE_AND_STOP; - return -1; -} - gfp_t mapping_gfp_mask(struct address_space * mapping) { TRACE_AND_STOP; @@ -1026,18 +577,6 @@ void mark_page_accessed(struct page *) TRACE_AND_STOP; } -int memcmp(const void *, const void *, size_t) -{ - TRACE_AND_STOP; - return -1; -} - -void *memset_io(void *s, int c, size_t n) -{ - TRACE_AND_STOP; - return NULL; -} - loff_t noop_llseek(struct file *file, loff_t offset, int whence) { TRACE_AND_STOP; @@ -1066,12 +605,6 @@ void pci_disable_msi(struct pci_dev *dev) TRACE_AND_STOP; } -int pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr) -{ - TRACE_AND_STOP; - return -1; -} - int pci_enable_device(struct pci_dev *dev) { TRACE_AND_STOP; @@ -1095,12 +628,6 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *p) TRACE_AND_STOP; } -dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, unsigned long offset, size_t size, int direction) -{ - TRACE_AND_STOP; - return -1; -} - int pci_save_state(struct pci_dev *dev) { TRACE_AND_STOP; @@ -1123,22 +650,11 @@ void pm_qos_remove_request(struct pm_qos_request *req) TRACE_AND_STOP; } -void pm_qos_update_request(struct pm_qos_request *req, s32 new_value) -{ - TRACE_AND_STOP; -} - void put_page(struct page *page) { TRACE_AND_STOP; } -bool queue_delayed_work(struct workqueue_struct *, struct delayed_work *, unsigned long) -{ - TRACE_AND_STOP; - return -1; -} - bool queue_work(struct workqueue_struct *wq, struct work_struct *work) { TRACE_AND_STOP; @@ -1168,30 +684,6 @@ unsigned long round_jiffies_up(unsigned long j) return -1; } -unsigned long round_jiffies_up_relative(unsigned long j) -{ - TRACE_AND_STOP; - return -1; -} - -int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) -{ - TRACE_AND_STOP; - return -1; -} - -int schedule_delayed_work(struct delayed_work *work, unsigned long delay) -{ - TRACE_AND_STOP; - return -1; -} - -int schedule_work(struct work_struct *work) -{ - TRACE_AND_STOP; - return -1; -} - void __set_current_state(int state) { TRACE_AND_STOP; @@ -1214,51 +706,17 @@ int set_pages_wb(struct page *page, int numpages) return -1; } -int sg_alloc_table(struct sg_table *, unsigned int, gfp_t) -{ - TRACE_AND_STOP; - return -1; -} - void sg_free_table(struct sg_table *) { TRACE_AND_STOP; } -void sg_mark_end(struct scatterlist *sg) -{ - TRACE_AND_STOP; -} - -struct scatterlist *sg_next(struct scatterlist *) -{ - TRACE_AND_STOP; - return NULL; -} - -dma_addr_t sg_page_iter_dma_address(struct sg_page_iter *piter) -{ - TRACE_AND_STOP; - return -1; -} - -bool __sg_page_iter_next(struct sg_page_iter *piter) -{ - TRACE_AND_STOP; - return -1; -} - struct page *sg_page_iter_page(struct sg_page_iter *piter) { TRACE_AND_STOP; return NULL; } -void __sg_page_iter_start(struct sg_page_iter *piter, struct scatterlist *sglist, unsigned int nents, unsigned long pgoffset) -{ - TRACE_AND_STOP; -} - void sg_set_page(struct scatterlist *sg, struct page *page, unsigned int len, unsigned int offset) { TRACE_AND_STOP; @@ -1287,21 +745,6 @@ int signal_pending(struct task_struct *p) return -1; } -void spin_lock(spinlock_t *lock) -{ - TRACE_AND_STOP; -} - -void spin_lock_irq(spinlock_t *lock) -{ - TRACE_AND_STOP; -} - -void spin_unlock_irq(spinlock_t *lock) -{ - TRACE_AND_STOP; -} - unsigned long timespec_to_jiffies(const struct timespec *value) { TRACE_AND_STOP; @@ -1325,16 +768,6 @@ void unregister_shrinker(struct shrinker *) TRACE_AND_STOP; } -void usleep_range(unsigned long min, unsigned long max) -{ - TRACE_AND_STOP; -} - -void valleyview_set_rps(struct drm_device *dev, u8 val) -{ - TRACE_AND_STOP; -} - int vga_switcheroo_process_delayed_switch(void) { TRACE_AND_STOP; @@ -1352,50 +785,6 @@ phys_addr_t virt_to_phys(volatile void *address) return -1; } -u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg) -{ - TRACE_AND_STOP; - return -1; -} - -void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) -{ - TRACE_AND_STOP; -} - -u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg) -{ - TRACE_AND_STOP; - return -1; -} - -void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) -{ - TRACE_AND_STOP; -} - -u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg) -{ - TRACE_AND_STOP; - return -1; -} - -void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val) -{ - TRACE_AND_STOP; -} - -u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr) -{ - TRACE_AND_STOP; - return -1; -} - -void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) -{ - TRACE_AND_STOP; -} - int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) { TRACE_AND_STOP; @@ -1419,32 +808,11 @@ void wbinvd_on_all_cpus() TRACE_AND_STOP; } -void ida_remove(struct ida *ida, int id) -{ - TRACE_AND_STOP; -} - void idr_destroy(struct idr *idp) { TRACE_AND_STOP; } -void *idr_find(struct idr *idr, int id) -{ - TRACE_AND_STOP; - return NULL; -} - -void idr_remove(struct idr *idp, int id) -{ - TRACE_AND_STOP; -} - -void kref_init(struct kref *kref) -{ - TRACE_AND_STOP; -} - int acpi_lid_notifier_unregister(struct notifier_block *nb) { TRACE_AND_STOP; @@ -1457,52 +825,6 @@ int acpi_lid_open(void) return -1; } -void drm_mode_set_name(struct drm_display_mode *mode) -{ - TRACE_AND_STOP; -} - -int acpi_lid_notifier_register(struct notifier_block *nb) -{ - TRACE_AND_STOP; - return -1; -} -struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, bool reduced, bool interlaced, bool margins) -{ - TRACE_AND_STOP; - return NULL; -} - -struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, bool interlaced, int margins) -{ - TRACE_AND_STOP; - return NULL; -} - -struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, bool interlaced, int margins, int GTF_M, int GTF_2C, int GTF_K, int GTF_2J) -{ - TRACE_AND_STOP; - return NULL; -} - -bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2) -{ - TRACE_AND_STOP; - return -1; -} - -int drm_mode_hsync(const struct drm_display_mode *mode) -{ - TRACE_AND_STOP; - return -1; -} - -int drm_mode_vrefresh(const struct drm_display_mode *mode) -{ - TRACE_AND_STOP; - return -1; -} - void *memchr_inv(const void *s, int c, size_t n) { TRACE_AND_STOP; @@ -1514,12 +836,6 @@ void print_hex_dump(const char *level, const char *prefix_str, int prefix_type, TRACE_AND_STOP; } -int strncmp(const char *cs, const char *ct, size_t count) -{ - TRACE_AND_STOP; - return -1; -} - int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *) { TRACE_AND_STOP; @@ -1549,12 +865,6 @@ int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) return -1; } -int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, void *data, int (*fn)(struct device_driver *, void *)) -{ - TRACE_AND_STOP; - return -1; -} - bool device_can_wakeup(struct device *dev) { TRACE_AND_STOP; @@ -1607,18 +917,6 @@ void gpio_set_value(unsigned int gpio, int value) TRACE_AND_STOP; } -bool in_atomic() -{ - TRACE_AND_STOP; - return -1; -} - -bool irqs_disabled() -{ - TRACE_AND_STOP; - return -1; -} - void ndelay(unsigned long) { TRACE_AND_STOP; @@ -1636,22 +934,6 @@ int of_driver_match_device(struct device *dev, const struct device_driver *drv) return -1; } -void rt_mutex_lock(struct rt_mutex *lock) -{ - TRACE_AND_STOP; -} - -int rt_mutex_trylock(struct rt_mutex *lock) -{ - TRACE_AND_STOP; - return -1; -} - -void rt_mutex_unlock(struct rt_mutex *lock) -{ - TRACE_AND_STOP; -} - int strcmp(const char *s1, const char *s2) { TRACE_AND_STOP; @@ -1669,14 +951,79 @@ void up_read(struct rw_semaphore *sem) TRACE_AND_STOP; } -void wait_for_completion(struct completion *work) -{ - TRACE_AND_STOP; -} - void bus_unregister(struct bus_type *bus) { TRACE_AND_STOP; } +void yield(void) +{ + TRACE_AND_STOP; +} + +int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame) +{ + TRACE_AND_STOP; + return -1; +} + +int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame) +{ + TRACE_AND_STOP; + return -1; +} + +int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame, const char *vendor, const char *product) +{ + TRACE_AND_STOP; + return -1; +} + +ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size) +{ + TRACE_AND_STOP; + return -1; +} + +void io_mapping_unmap(void __iomem *vaddr) +{ + TRACE_AND_STOP; +} + +void memcpy_toio(volatile void __iomem *dst, const void *src, size_t count) +{ + TRACE_AND_STOP; +} + +void __iomem * io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) +{ + TRACE_AND_STOP; + return NULL; +} + +void cpufreq_cpu_put(struct cpufreq_policy *policy) +{ + TRACE_AND_STOP; +} + +void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) +{ + TRACE_AND_STOP; +} + +void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) +{ + TRACE_AND_STOP; +} + +void cfb_imageblit(struct fb_info *info, const struct fb_image *image) +{ + TRACE_AND_STOP; +} + +void fb_set_suspend(struct fb_info *info, int state) +{ + TRACE_AND_STOP; +} + diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/i2c-algo-bit.c b/repos/dde_linux/src/drivers/framebuffer/intel/i2c-algo-bit.c deleted file mode 100644 index 58e373e00..000000000 --- a/repos/dde_linux/src/drivers/framebuffer/intel/i2c-algo-bit.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * \brief Definition of the global 'i2c_bit_algo' struct - * \author Norman Feske - * \date 2015-09-11 - * - * The 'i2c_bit_algo' struct must be defined in a C file because we cannot - * use C-style struct initializers in C++ code. - */ - -#include - -int i2c_algo_bit_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) -{ - lx_printf("i2c_algo_bit_xfer called - not implemented\n"); - for (;;); - return -1; -} - - -u32 i2c_algo_bit_func(struct i2c_adapter *adap) -{ - lx_printf("i2c_algo_bit_func called - not implemented\n"); - return 0; -} - - -const struct i2c_algorithm i2c_bit_algo = { - .master_xfer = i2c_algo_bit_xfer, - .functionality = i2c_algo_bit_func, -}; - diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/include/component.h b/repos/dde_linux/src/drivers/framebuffer/intel/include/component.h new file mode 100644 index 000000000..7f695ce6a --- /dev/null +++ b/repos/dde_linux/src/drivers/framebuffer/intel/include/component.h @@ -0,0 +1,157 @@ +/* + * \brief Intel framebuffer driver session component + * \author Stefan Kalkowski + * \date 2015-10-16 + */ + +/* + * Copyright (C) 2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef __COMPONENT_H__ +#define __COMPONENT_H__ + +/* Genode includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Framebuffer { + class Session_component; + class Root; + + extern Root * root; + Genode::Dataspace_capability framebuffer_dataspace(); +} + + +class Framebuffer::Session_component : public Genode::Rpc_object +{ + private: + + template using Lazy = Genode::Lazy_volatile_object; + + int _height; + int _width; + Genode::Signal_context_capability _mode_sigh; + Timer::Connection _timer; + bool const _buffered; + Lazy _fb_ds; + Lazy _bb_ds; + bool _in_update = false; + static constexpr unsigned _bytes_per_pixel = 2; + + void _refresh_buffered(int x, int y, int w, int h) + { + using namespace Genode; + /* clip specified coordinates against screen boundaries */ + int x2 = min(x + w - 1, (int)_width - 1), + y2 = min(y + h - 1, (int)_height - 1); + int x1 = max(x, 0), + y1 = max(y, 0); + if (x1 > x2 || y1 > y2) return; + + int const bpp = _bytes_per_pixel; + + /* copy pixels from back buffer to physical frame buffer */ + char *src = _bb_ds->local_addr() + bpp*(_width*y1 + x1), + *dst = _fb_ds->local_addr() + bpp*(_width*y1 + x1); + + blit(src, bpp*_width, dst, bpp*_width, + bpp*(x2 - x1 + 1), y2 - y1 + 1); + } + + public: + + Session_component(bool buffered) + : _height(0), _width(0), _buffered(buffered) {} + + void update(int height, int width) + { + _in_update = true; + _height = height; + _width = width; + + if (_mode_sigh.valid()) + Genode::Signal_transmitter(_mode_sigh).submit(); + } + + + /*********************************** + ** Framebuffer session interface ** + ***********************************/ + + Genode::Dataspace_capability dataspace() override + { + _in_update = false; + + if (_fb_ds.is_constructed()) + _fb_ds.destruct(); + + _fb_ds.construct(framebuffer_dataspace()); + if (!_fb_ds.is_constructed()) + PERR("framebuffer dataspace not initialized"); + + if (_buffered) { + _bb_ds.construct(Genode::env()->ram_session(), + _width * _height * _bytes_per_pixel); + if (!_bb_ds.is_constructed()) { + PERR("buffered mode enabled, but buffer not initialized"); + return Genode::Dataspace_capability(); + } + return _bb_ds->cap(); + } + + return _fb_ds->cap(); + } + + Mode mode() const override { + return Mode(_width, _height, Mode::RGB565); } + + void mode_sigh(Genode::Signal_context_capability sigh) override { + _mode_sigh = sigh; } + + void sync_sigh(Genode::Signal_context_capability sigh) override + { + _timer.sigh(sigh); + _timer.trigger_periodic(10*1000); + } + + void refresh(int x, int y, int w, int h) override { + if (_buffered && !_in_update) _refresh_buffered(x, y, w, h); } +}; + + +class Framebuffer::Root +: public Genode::Root_component +{ + private: + + Session_component _single_session; + + Session_component *_create_session(const char *args) override { + return &_single_session; } + + public: + + Root(Genode::Rpc_entrypoint *session_ep, Genode::Allocator *md_alloc, + bool buffered) + : Genode::Root_component(session_ep, md_alloc), + _single_session(buffered) { } + + void update(int height, int width) { + _single_session.update(height, width); } +}; + +#endif /* __COMPONENT_H__ */ diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/include/drm/drmP.h b/repos/dde_linux/src/drivers/framebuffer/intel/include/drm/drmP.h index 79086b835..1a50d693d 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/include/drm/drmP.h +++ b/repos/dde_linux/src/drivers/framebuffer/intel/include/drm/drmP.h @@ -111,7 +111,7 @@ enum { DRM_CALLED_FROM_VBLIRQ = 1 }; ///* // * Debug macros // */ -#define DRM_VERBOSE 1 +#define DRM_VERBOSE 0 #if DRM_VERBOSE #define DRM_INFO(fmt, arg...) do { \ @@ -158,6 +158,7 @@ struct drm_display_mode; struct drm_connector; struct drm_mode_create_dumb; struct drm_mode_fb_cmd2; +struct drm_cmdline_mode; /** @@ -286,6 +287,10 @@ struct drm_driver { struct drm_i915_private; +struct drm_vblank_crtc { + u32 last; +}; + struct drm_device { // int pci_device; struct pci_dev *pdev; @@ -316,6 +321,9 @@ struct drm_device { int switch_power_state; spinlock_t event_lock; struct device *dev; /* i915_gem_stolen.c */ + struct drm_vblank_crtc *vblank; /* needed by intel_pm.c */ + spinlock_t vbl_lock; /* needed by intel_pm.c */ + struct timer_list vblank_disable_timer; }; // @@ -424,6 +432,9 @@ struct drm_file { int event_space; }; // + +#define DRM_MINOR_LEGACY 1 + ///* // * needed for drm_agpsupport.c // */ @@ -467,9 +478,6 @@ struct drm_minor { struct drm_pending_vblank_event; -struct drm_fb_helper { int dummy; }; - - #include @@ -494,6 +502,26 @@ struct drm_pending_vblank_event { }; +/*************************** + ** drm/drm_crtc_helper.h ** + ***************************/ + +struct drm_cmdline_mode +{ + bool specified; + bool refresh_specified; + bool bpp_specified; + int xres, yres; + int bpp; + int refresh; + bool rb; + bool interlace; + bool cvt; + bool margins; + enum drm_connector_force force; +}; + + /****************** ** Misc helpers ** ******************/ @@ -674,8 +702,9 @@ extern const char *drm_get_connector_status_name(enum drm_connector_status statu extern void drm_kms_helper_hotplug_event(struct drm_device *dev); extern bool drm_handle_vblank(struct drm_device *dev, int crtc); extern void drm_gem_private_object_init(struct drm_device *dev, struct drm_gem_object *obj, size_t size); - - +extern void drm_sysfs_hotplug_event(struct drm_device *dev); +extern bool drm_mode_parse_command_line_for_connector(const char *mode_option, struct drm_connector *connector, struct drm_cmdline_mode *mode); +extern struct drm_display_mode * drm_mode_create_from_cmdline_mode(struct drm_device *dev, struct drm_cmdline_mode *cmd); #ifdef __cplusplus } diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/include/lx_emul.h b/repos/dde_linux/src/drivers/framebuffer/intel/include/lx_emul.h index 7c6e8b79f..9c1789cb9 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/include/lx_emul.h +++ b/repos/dde_linux/src/drivers/framebuffer/intel/include/lx_emul.h @@ -22,6 +22,7 @@ enum { HZ = 100UL }; +#define DEBUG_LINUX_PRINTK 1 #include #include @@ -36,6 +37,7 @@ void atomic_set_mask(unsigned int mask, atomic_t *v); #include typedef unsigned long kernel_ulong_t; +typedef unsigned int u_int; /************************ @@ -61,6 +63,8 @@ void print_hex_dump(const char *level, const char *prefix_str, int prefix_type, int rowsize, int groupsize, const void *buf, size_t len, bool ascii); +#define printk_once(fmt, ...) ({}) + /********************* ** uapi/linux/fb.h ** @@ -89,7 +93,6 @@ void print_hex_dump(const char *level, const char *prefix_str, #define PAGE_SIZE 4096UL #define PAGE_MASK (~(PAGE_SIZE-1)) -dma_addr_t page_to_phys(void *page); enum { PAGE_SHIFT = 12, @@ -100,19 +103,31 @@ struct page // unsigned long flags; // int pfmemalloc; // int mapping; - atomic_t _count; - void *addr; - unsigned long private; + atomic_t _count; + void *addr; + dma_addr_t paddr; } __attribute((packed)); /* needed for agp/generic.c */ struct page *virt_to_page(void *addr); +dma_addr_t page_to_phys(struct page *page); #include unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size); +#define __const_hweight8(w) \ + ( (!!((w) & (1ULL << 0))) + \ + (!!((w) & (1ULL << 1))) + \ + (!!((w) & (1ULL << 2))) + \ + (!!((w) & (1ULL << 3))) + \ + (!!((w) & (1ULL << 4))) + \ + (!!((w) & (1ULL << 5))) + \ + (!!((w) & (1ULL << 6))) + \ + (!!((w) & (1ULL << 7))) ) +#define hweight16(w) (__const_hweight8(w) + __const_hweight8((w) >> 8 )) + #include @@ -128,14 +143,15 @@ void *memchr_inv(const void *s, int c, size_t n); #include #include +extern long simple_strtol(const char *,char **,unsigned int); typedef __kernel_time_t time_t; extern int oops_in_progress; -#define pr_debug(fmt, ...) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) -#define pr_info(fmt, ...) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) -#define pr_err(fmt, ...) printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) -#define pr_warn(fmt, ...) printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) +#define pr_debug(fmt, ...) printk(KERN_INFO fmt, ##__VA_ARGS__) +#define pr_info(fmt, ...) printk(KERN_INFO fmt, ##__VA_ARGS__) +#define pr_err(fmt, ...) printk(KERN_ERR fmt, ##__VA_ARGS__) +#define pr_warn(fmt, ...) printk(KERN_ERR fmt, ##__VA_ARGS__) #define pr_info_once(fmt, ...) printk(KERN_INFO fmt, ##__VA_ARGS__) int sprintf(char *buf, const char *fmt, ...); @@ -151,6 +167,18 @@ enum { SPRINTF_STR_LEN = 64 }; buf; \ }) +#define DIV_ROUND_UP_ULL(ll,d) \ + ({ unsigned long long _tmp = (ll)+(d)-1; do_div(_tmp, d); _tmp; }) + +#define mult_frac(x, numer, denom) ({ \ + typeof(x) quot = (x) / (denom); \ + typeof(x) rem = (x) % (denom); \ + (quot * (numer)) + ((rem * (numer)) / (denom)); \ + }) + +extern int panic_timeout; +extern struct atomic_notifier_head panic_notifier_list; + /* linux/i2c.h */ #define __deprecated @@ -182,6 +210,9 @@ extern void hex_dump_to_buffer(const void *buf, size_t len, /* i2c-core.c */ #define postcore_initcall(fn) void postcore_##fn(void) { fn(); } +#define symbol_get(x) ({ extern typeof(x) x __attribute__((weak)); &(x); }) +#define symbol_put(x) do { } while (0) + /************************** ** linux/preempt_mask.h ** @@ -231,13 +262,11 @@ void mutex_lock_nest_lock(struct mutex *, struct mutex *); ** linux/rtmutex.h ** *********************/ -struct rt_mutex { int dummy; }; - -void rt_mutex_lock(struct rt_mutex *lock); -int rt_mutex_trylock(struct rt_mutex *lock); -void rt_mutex_unlock(struct rt_mutex *lock); - -#define rt_mutex_init(mutex) +#define rt_mutex mutex +#define rt_mutex_init(m) mutex_init(m) +#define rt_mutex_lock(m) mutex_lock(m) +#define rt_mutex_trylock(m) mutex_trylock(m) +#define rt_mutex_unlock(m) mutex_unlock(m) /****************** @@ -305,6 +334,8 @@ int on_each_cpu(void (*func) (void *info), void *info, int wait); /* normally defined in asm/current.h, included by sched.h */ extern struct task_struct *current; +void yield(void); + /************************ ** linux/completion.h ** @@ -315,6 +346,7 @@ struct completion { unsigned done; }; void __wait_completion(struct completion *work); void complete(struct completion *); /* i2c-core.c */ void init_completion(struct completion *x); +void wait_for_completion(struct completion *); /********************* @@ -744,6 +776,13 @@ enum { #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) +enum rpm_status { + RPM_ACTIVE = 0, + RPM_RESUMING, + RPM_SUSPENDED, + RPM_SUSPENDING, +}; + /******************** ** linux/device.h ** @@ -885,6 +924,8 @@ void iounmap(volatile void *addr); void __iomem *ioremap(phys_addr_t offset, unsigned long size); +#define mmiowb() barrier() + /** * Map I/O memory write combined */ @@ -892,13 +933,15 @@ void *ioremap_wc(resource_size_t phys_addr, unsigned long size); #define ioremap_nocache ioremap_wc -void *memset_io(void *s, int c, size_t n); - int arch_phys_wc_add(unsigned long base, unsigned long size); static inline void arch_phys_wc_del(int handle) { } phys_addr_t virt_to_phys(volatile void *address); +void memset_io(void *s, int c, size_t n); +void memcpy_toio(volatile void __iomem *dst, const void *src, size_t count); +void memcpy_fromio(void *dst, const volatile void __iomem *src, size_t count); + /********************* ** linux/uaccess.h ** @@ -942,6 +985,9 @@ void io_mapping_unmap_atomic(void *vaddr); struct io_mapping *io_mapping_create_wc(resource_size_t base, unsigned long size); void io_mapping_free(struct io_mapping *mapping); +void __iomem * io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset); +void io_mapping_unmap(void __iomem *vaddr); + #include @@ -958,14 +1004,6 @@ int request_resource(struct resource *root, struct resource *); /* intel-gtt.c * int release_resource(struct resource *r); /* i915_dma.c */ -/************************ - ** linux/pm_runtime.h ** - ************************/ - -int pm_generic_runtime_suspend(struct device *dev); -int pm_generic_runtime_resume(struct device *dev); - - /***************** ** linux/pci.h ** *****************/ @@ -1045,6 +1083,9 @@ static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar) struct pci_dev *pci_dev_get(struct pci_dev *dev); +void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); +void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); + /********************************** ** asm-generic/pci-dma-compat.h ** @@ -1081,63 +1122,6 @@ bool capable(int cap); #define CAP_SYS_ADMIN 21 -/****************** - ** linux/hdmi.h ** - ******************/ - -#define HDMI_IEEE_OUI 0x000c03 - -enum hdmi_infoframe_type { HDMI_INFOFRAME_TYPE_DUMMY }; - -enum hdmi_picture_aspect { - HDMI_PICTURE_ASPECT_NONE, - HDMI_PICTURE_ASPECT_4_3, - HDMI_PICTURE_ASPECT_16_9, -}; - -enum hdmi_active_aspect { - HDMI_ACTIVE_ASPECT_16_9_TOP = 2, - HDMI_ACTIVE_ASPECT_14_9_TOP = 3, - HDMI_ACTIVE_ASPECT_16_9_CENTER = 4, - HDMI_ACTIVE_ASPECT_PICTURE = 8, - HDMI_ACTIVE_ASPECT_4_3 = 9, - HDMI_ACTIVE_ASPECT_16_9 = 10, - HDMI_ACTIVE_ASPECT_14_9 = 11, - HDMI_ACTIVE_ASPECT_4_3_SP_14_9 = 13, - HDMI_ACTIVE_ASPECT_16_9_SP_14_9 = 14, - HDMI_ACTIVE_ASPECT_16_9_SP_4_3 = 15, -}; - -enum hdmi_3d_structure { - HDMI_3D_STRUCTURE_INVALID = -1, - HDMI_3D_STRUCTURE_FRAME_PACKING = 0, - HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE, - HDMI_3D_STRUCTURE_LINE_ALTERNATIVE, - HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL, - HDMI_3D_STRUCTURE_L_DEPTH, - HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH, - HDMI_3D_STRUCTURE_TOP_AND_BOTTOM, - HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF = 8, -}; - -struct hdmi_avi_infoframe { - int dummy; - enum hdmi_picture_aspect picture_aspect; - enum hdmi_active_aspect active_aspect; - unsigned char video_code; - unsigned char pixel_repeat; -}; - -struct hdmi_vendor_infoframe { - enum hdmi_infoframe_type type; - u8 vic; - enum hdmi_3d_structure s3d_struct; -}; - -int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame); -int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame); - - /************************* ** linux/agp_backend.h ** *************************/ @@ -1183,6 +1167,11 @@ struct notifier_block { notifier_fn_t notifier_call; }; enum { NOTIFY_OK = 0x0001 }; +struct atomic_notifier_head { unsigned dummy; }; + +extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, struct notifier_block *nb); +extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh, struct notifier_block *nb); + /******************* ** acpi/button.h ** @@ -1242,11 +1231,6 @@ void console_unlock(void); int console_trylock(void); -/**************** - ** linux/fb.h ** - ****************/ - -enum { FBINFO_STATE_RUNNING = 0, FBINFO_STATE_SUSPENDED = 1 }; /**************** @@ -1452,6 +1436,165 @@ void gpio_free(unsigned gpio); bool gpio_is_valid(int number); +/* needed by drivers/gpu/drm/drm_modes.c */ +#include + + +/********************* + ** linux/cpufreq.h ** + *********************/ + +struct cpufreq_cpuinfo { + unsigned int max_freq; + unsigned int min_freq; +}; + +struct cpufreq_policy { + struct cpufreq_cpuinfo cpuinfo; +}; + +struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu); +void cpufreq_cpu_put(struct cpufreq_policy *policy); + + +/******************************** + ** arch/x86/include/asm/tsc.h ** + ********************************/ + +extern unsigned int tsc_khz; + + +/************************************** + ** drivers/platform/x86/intel_ips.h ** + **************************************/ + +void ips_link_to_i915_driver(void); + + +/****************** + ** linux/kgdb.h ** + ******************/ + +#define in_dbg_master() (0) + + +/************************* + ** asm-generic/div64.h ** + *************************/ + +#define do_div(n,base) ({ \ + unsigned long __base = (base); \ + unsigned long __rem; \ + __rem = ((uint64_t)(n)) % __base; \ + (n) = ((uint64_t)(n)) / __base; \ + __rem; \ +}) + + +/************************************** + ** definitions needed by intel_pm.c ** + **************************************/ + +void trace_intel_gpu_freq_change(int); + + +/**************** + ** linux/fb.h ** + ****************/ + +#include + +enum { + FBINFO_STATE_RUNNING = 0, + FBINFO_STATE_SUSPENDED = 1, + FBINFO_CAN_FORCE_OUTPUT = 0x200000, + FBINFO_DEFAULT = 0, +}; + +struct fb_cmap_user { + __u32 start; + __u32 len; + __u16 __user *red; + __u16 __user *green; + __u16 __user *blue; + __u16 __user *transp; +}; + +struct aperture { + resource_size_t base; + resource_size_t size; +}; + +struct apertures_struct { + unsigned int count; + struct aperture ranges[0]; +}; + +struct fb_info { + int node; + int flags; + struct fb_var_screeninfo var; /* Current var */ + struct fb_fix_screeninfo fix; /* Current fix */ + struct fb_cmap cmap; + struct fb_ops *fbops; + char __iomem *screen_base; + unsigned long screen_size; + void *pseudo_palette; + void * par; + struct apertures_struct *apertures; + bool skip_vt_switch; +}; + +struct fb_ops { + struct module *owner; + int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info); + int (*fb_set_par)(struct fb_info *info); + int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, struct fb_info *info); + int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info); + int (*fb_blank)(int blank, struct fb_info *info); + int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info); + void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect); + void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region); + void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image); + int (*fb_debug_enter)(struct fb_info *info); + int (*fb_debug_leave)(struct fb_info *info); +}; + +extern int fb_get_options(const char *name, char **option); +extern int register_framebuffer(struct fb_info *fb_info); +extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); +extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); +extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image); +extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev); +extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp); +extern struct apertures_struct *alloc_apertures(unsigned int max_num); +extern int unregister_framebuffer(struct fb_info *fb_info); +extern void fb_dealloc_cmap(struct fb_cmap *cmap); +extern void framebuffer_release(struct fb_info *info); +extern void fb_set_suspend(struct fb_info *info, int state); +extern int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to); +extern const struct fb_cmap *fb_default_cmap(int len); +extern int lock_fb_info(struct fb_info *info); +extern void unlock_fb_info(struct fb_info *info); + +/*************************** + ** linux vgaswitcheroo.h ** + ***************************/ + +void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info); + + +/******************* + ** linux/sysrq.h ** + *******************/ + +struct sysrq_key_op { unsigned dummy; }; + +int register_sysrq_key(int key, struct sysrq_key_op *op); +int unregister_sysrq_key(int key, struct sysrq_key_op *op); + + /******************* ** Configuration ** *******************/ @@ -1459,6 +1602,9 @@ bool gpio_is_valid(int number); /* evaluated in i915_drv.c */ enum { CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT = 1 }; +#define CONFIG_DRM_I915_FBDEV 1 + +void update_genode_report(); /************************** ** Dummy trace funtions ** @@ -1485,7 +1631,6 @@ enum { CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT = 1 }; #define trace_i915_reg_rw(...) #define trace_i915_gem_request_complete(...) - #include #endif /* _LX_EMUL_H_ */ diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc index 81a550ae0..63ea4ab26 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc +++ b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc @@ -4,11 +4,15 @@ * \date 2015-08-19 */ -/* local includes */ -#include "lx_emul_private.h" - /* Genode includes */ #include +#include +#include +#include + +/* local includes */ +#include +#include "lx_emul_private.h" /* DRM-specific includes */ extern "C" { @@ -51,6 +55,37 @@ char *strncpy(char *dst, const char* src, size_t n) return Genode::strncpy(dst, src, n); } +int strncmp(const char *cs, const char *ct, size_t count) +{ + return Genode::strcmp(cs, ct, count); +} + +int memcmp(const void *cs, const void *ct, size_t count) +{ + /* original implementation from lib/string.c */ + const unsigned char *su1, *su2; + int res = 0; + + for (su1 = (unsigned char*)cs, su2 = (unsigned char*)ct; + 0 < count; ++su1, ++su2, count--) + if ((res = *su1 - *su2) != 0) + break; + return res; +} + +size_t strlen(const char *s) +{ + return Genode::strlen(s); +} + +long simple_strtol(const char *cp, char **endp, unsigned int base) +{ + unsigned long result = 0; + size_t ret = Genode::ascii_to_unsigned(cp, result, base); + if (endp) *endp = (char*)cp + ret; + return result; +} + /***************** ** linux/dmi.h ** @@ -73,6 +108,18 @@ int dmi_check_system(const struct dmi_system_id *list) #include +/******************************* + ** kernel/time/timekeeping.c ** + *******************************/ + +void getrawmonotonic(struct timespec *ts) +{ + unsigned long ms = _delay_timer.elapsed_ms(); + ts->tv_sec = ms / 1000; + ts->tv_nsec = (ms - ts->tv_sec*1000) * 1000000; +} + + /********************** ** Global variables ** **********************/ @@ -91,14 +138,14 @@ struct boot_cpu_data boot_cpu_data; #include -dma_addr_t page_to_phys(void *p) +dma_addr_t page_to_phys(struct page *page) { - struct page *page = (struct page *)p; + return page->paddr; +} - dma_addr_t const phys = Lx::Malloc::dma().phys_addr(page->addr); - - PDBG("virt=0x%lx -> phys=0x%lx", (long)page->addr, phys); - return phys; +void *kmem_cache_zalloc(struct kmem_cache *k, gfp_t flags) +{ + return kmem_cache_alloc(k, flags | __GFP_ZERO); } @@ -108,30 +155,58 @@ dma_addr_t page_to_phys(void *p) void idr_init(struct idr *idp) { - TRACE; + Genode::memset(idp, 0, sizeof(struct idr)); } +static Genode::Bit_allocator<1024> id_allocator; int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask) { - TRACE; - /* - * Called from i915_gem_context.c: create_hw_context() - */ - return 0; + int max = end > 0 ? end - 1 : ((int)(~0U>>1)); /* inclusive upper limit */ + int id; + + /* sanity checks */ + if (start < 0) return -EINVAL; + if (max < start) return -ENOSPC; + + /* allocate id */ + id = id_allocator.alloc(); + if (id > max) return -ENOSPC; + + ASSERT(id >= start); + return id; } int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, gfp_t gfp_mask) { - /* - * Called by drm_crtc.c: drm_connector_init to allocate a connector_type_id - */ - TRACE; - return 0; + int max = end > 0 ? end - 1 : ((int)(~0U>>1)); + int id = id_allocator.alloc(); + if (id > max) return -ENOSPC; + + ASSERT((unsigned int)id >= start); + return id; } +void ida_remove(struct ida *ida, int id) +{ + id_allocator.free(id); +} + + +void idr_remove(struct idr *idp, int id) +{ + id_allocator.free(id); +} + + +void *idr_find(struct idr *idr, int id) +{ + TRACE; + return NULL; +} + /********************** ** asm/cacheflush.h ** @@ -281,6 +356,18 @@ int pci_enable_msi(struct pci_dev *dev) } +dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, + unsigned long offset, size_t size, int direction) { + return page->paddr + offset; +} + + +int pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr) +{ + TRACE; + return 0; +} + struct io_mapping { @@ -319,6 +406,13 @@ struct io_mapping *io_mapping_create_wc(resource_size_t base, unsigned long size } +void iounmap(volatile void *addr) +{ + /* do not unmap here, but when client requests new dataspace */ + TRACE; +} + + /**************** ** linux/io.h ** ****************/ @@ -336,6 +430,16 @@ int arch_phys_wc_add(unsigned long base, unsigned long size) } +/******************************* + ** arch/x86/include/asm/io.h ** + *******************************/ + +void memset_io(void *addr, int val, size_t count) +{ + memset((void __force *)addr, val, count); +} + + /******************** ** linux/device.h ** ********************/ @@ -359,9 +463,17 @@ int bus_register(struct bus_type *bus) } +/** + * Assuming that driver_register is only called for i2c device driver + * registration, we can store its pointer here + */ +static struct device_driver *i2c_device_driver = nullptr; + int driver_register(struct device_driver *drv) { TRACE; + ASSERT(!i2c_device_driver); + i2c_device_driver = drv; return 0; } @@ -395,10 +507,28 @@ int device_register(struct device *dev) } +int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, + void *data, int (*fn)(struct device_driver *, void *)) +{ + TRACE; + return fn(i2c_device_driver, data); +} + + /*********************** ** linux/workqueue.h ** ***********************/ +struct workqueue_struct *system_wq; + +/** needed by workqueue backend implementation **/ +struct tasklet_struct { + void (*func)(unsigned long); + unsigned long data; +}; + +#include + struct workqueue_struct *create_singlethread_workqueue(char const *) { workqueue_struct *wq = (workqueue_struct *)kzalloc(sizeof(workqueue_struct), 0); @@ -440,10 +570,39 @@ void mutex_lock_nest_lock(struct mutex *lock, struct mutex *) } +bool in_atomic() +{ + TRACE; + return false; +} + + +bool irqs_disabled() +{ + TRACE; + return false; +} + + +void usleep_range(unsigned long min, unsigned long max) +{ + udelay(min); +} + + +unsigned long round_jiffies_up_relative(unsigned long j) +{ + j += jiffies; + return j - (j%HZ) + HZ; +} + + /************************ ** DRM implementation ** ************************/ +#include + unsigned int drm_debug = 1; @@ -478,6 +637,39 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver, struct device *paren } +static void drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) +{ + // int minor_id = drm_minor_get_id(dev, type); + + struct drm_minor *new_minor = (struct drm_minor*) + kzalloc(sizeof(struct drm_minor), GFP_KERNEL); + ASSERT(new_minor); + new_minor->type = type; + //new_minor->device = MKDEV(DRM_MAJOR, minor_id); + new_minor->dev = dev; + //new_minor->index = minor_id; + //INIT_LIST_HEAD(&new_minor->master_list); + *minor = new_minor; +} + +static struct drm_device * singleton_drm_device = nullptr; + +static void drm_dev_register(struct drm_device *dev, unsigned long flags) +{ + //if (drm_core_check_feature(dev, DRIVER_MODESET)) + // drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); + + //if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) + // drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER); + + drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); + + ASSERT(!singleton_drm_device); + singleton_drm_device = dev; + ASSERT(!dev->driver->load(dev, flags)); +} + + /* * Called indirectly when 'pci_register_driver' has found a matching * device. @@ -503,7 +695,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, * In the Linux DRM code, this happens indirectly via the call of * 'drm_dev_register'. */ - driver->load(dev, ent->driver_data); + drm_dev_register(dev, ent->driver_data); DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, @@ -513,19 +705,416 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, } +static void vblank_disable_fn(unsigned long arg) +{ + struct drm_device *dev = (struct drm_device *)arg; + unsigned long irqflags; + int i = 0; + + if (!dev->vblank_disable_allowed) + return; + + //for (i = 0; i < dev->num_crtcs; i++) { + spin_lock_irqsave(&dev->vbl_lock, irqflags); + // if (atomic_read(&dev->vblank_refcount[i]) == 0 && + // dev->vblank_enabled[i]) { + // DRM_DEBUG("disabling vblank on crtc %d\n", i); + // dev->last_vblank[i] = + // dev->driver->get_vblank_counter(dev, i); + dev->driver->disable_vblank(dev, i); + //dev->vblank_enabled[i] = 0; + // } + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); + //} +} + /** * Called from 'i915_driver_load' */ int drm_vblank_init(struct drm_device *dev, int num_crtcs) +{ + setup_timer(&dev->vblank_disable_timer, vblank_disable_fn, + (unsigned long)dev); + spin_lock_init(&dev->vbl_lock); + dev->vblank = (drm_vblank_crtc*) kzalloc(num_crtcs * sizeof(*dev->vblank), GFP_KERNEL); + dev->vblank_disable_allowed = 0; + return 0; +} + + +void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) +{ + /* Enable vblank irqs under vblank_time_lock protection. + * All vblank count & timestamp updates are held off + * until we are done reinitializing master counter and + * timestamps. Filtercode in drm_handle_vblank() will + * prevent double-accounting of same vblank interval. + */ + int ret = dev->driver->enable_vblank(dev, crtc); + DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", + crtc, ret); + //drm_update_vblank_count(dev, crtc); +} + + +void drm_vblank_post_modeset(struct drm_device *dev, int crtc) +{ + dev->vblank_disable_allowed = true; + + //if (drm_vblank_offdelay > 0) + if (dev->vblank_disable_timer.function == 0) PERR("NO TIMER FUNC"); + mod_timer(&dev->vblank_disable_timer, + jiffies + ((5000/*drm_vblank_offdelay*/ * HZ)/1000)); +} + + +int drm_irq_install(struct drm_device *dev) +{ + if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) + return -EINVAL; + + if (dev->irq_enabled) + return -EBUSY; + + dev->irq_enabled = true; + + if (dev->driver->irq_preinstall) + dev->driver->irq_preinstall(dev); + + /* enable IRQ */ + Lx::Pci_dev * pci_dev = (Lx::Pci_dev*) dev->pdev->bus; + Lx::Irq::irq().request_irq(pci_dev->client(), dev->driver->irq_handler, (void*)dev); + + /* After installing handler */ + int ret = 0; + if (dev->driver->irq_postinstall) + ret = dev->driver->irq_postinstall(dev); + + return ret; +} + + +void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode) +{ + int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0; + int dotclock = mode->crtc_clock; + + /* Valid dotclock? */ + if (dotclock > 0) { + int frame_size = mode->crtc_htotal * mode->crtc_vtotal; + + /* + * Convert scanline length in pixels and video + * dot clock to line duration, frame duration + * and pixel duration in nanoseconds: + */ + pixeldur_ns = 1000000 / dotclock; + linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, dotclock); + framedur_ns = div_u64((u64) frame_size * 1000000, dotclock); + + /* + * Fields of interlaced scanout modes are only half a frame duration. + */ + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + framedur_ns /= 2; + } else + DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n", + crtc->base.id); + + crtc->pixeldur_ns = pixeldur_ns; + crtc->linedur_ns = linedur_ns; + crtc->framedur_ns = framedur_ns; + + DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n", + crtc->base.id, mode->crtc_htotal, + mode->crtc_vtotal, mode->crtc_vdisplay); + DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n", + crtc->base.id, dotclock, framedur_ns, + linedur_ns, pixeldur_ns); + TRACE; +} + + +void drm_gem_private_object_init(struct drm_device *dev, struct drm_gem_object *obj, size_t size) +{ + obj->dev = dev; + obj->filp = NULL; + + //kref_init(&obj->refcount); + //obj->handle_count = 0; + obj->size = size; + //drm_vma_node_reset(&obj->vma_node); +} + + +/*************************** + ** arch/x86/kernel/tsc.c ** + ***************************/ + +unsigned int tsc_khz; + + +/************************************** + ** arch/x86/include/asm/processor.h ** + **************************************/ + +void cpu_relax(void) +{ + Lx::timer_update_jiffies(); + asm volatile("rep; nop" ::: "memory"); +} + + +/*********************** + ** linux/workqueue.h ** + ***********************/ + +bool mod_delayed_work(struct workqueue_struct *, struct delayed_work *, unsigned long) +{ + TRACE; + return false; +} + + +/******************** + ** kernel/panic.c ** + ********************/ + +struct atomic_notifier_head panic_notifier_list; +int panic_timeout; + + +/*********************** + ** drivers/pci/rom.c ** + ***********************/ + +void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size) +{ + enum { VIDEO_ROM_BASE = 0xC0000, VIDEO_ROM_SIZE = 0x20000 }; + + static Genode::Attached_io_mem_dataspace vrom(VIDEO_ROM_BASE, VIDEO_ROM_SIZE); + *size = VIDEO_ROM_SIZE; + return vrom.local_addr(); +} + +void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) {} + + +/*********************** + ** lib/scatterlist.c ** + ***********************/ + +void sg_mark_end(struct scatterlist *sg) +{ + sg->page_link |= 0x02; + sg->page_link &= ~0x01; +} + + +int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask) +{ + enum { MAX_ENTS = 4096 / sizeof(struct scatterlist) }; + + ASSERT(nents <= MAX_ENTS); + + Genode::memset(table, 0, sizeof(*table)); + + struct scatterlist *sg = (scatterlist*) + kmalloc(nents * sizeof(struct scatterlist), gfp_mask); + if (!sg) return -ENOMEM; + + Genode::memset(sg, 0, sizeof(*sg) * nents); + table->nents = nents; + table->sgl = sg; + sg_mark_end(&sg[nents - 1]); + return 0; +} + +static inline bool sg_is_chain(struct scatterlist* sg) { + return ((sg)->page_link & 0x01); } + + static inline bool sg_is_last(struct scatterlist* sg) { + return ((sg)->page_link & 0x02); } + + static inline struct scatterlist* sg_chain_ptr(struct scatterlist* sg) { + return (struct scatterlist *) ((sg)->page_link & ~0x03); } + +struct scatterlist *sg_next(struct scatterlist * sg) +{ + if (sg_is_last(sg)) + return NULL; + + sg++; + if (unlikely(sg_is_chain(sg))) + sg = sg_chain_ptr(sg); + + return sg; +} + +void __sg_page_iter_start(struct sg_page_iter *piter, struct scatterlist *sglist, unsigned int nents, unsigned long pgoffset) +{ + piter->__pg_advance = 0; + piter->__nents = nents; + piter->sg = sglist; + piter->sg_pgoffset = pgoffset; +} + +static int sg_page_count(struct scatterlist *sg) { + return Genode::align_addr(sg->offset + sg->length, 12) >> PAGE_SHIFT; } + +bool __sg_page_iter_next(struct sg_page_iter *piter) +{ + if (!piter->__nents || !piter->sg) + return false; + + piter->sg_pgoffset += piter->__pg_advance; + piter->__pg_advance = 1; + + while (piter->sg_pgoffset >= (unsigned long)sg_page_count(piter->sg)) { + piter->sg_pgoffset -= sg_page_count(piter->sg); + piter->sg = sg_next(piter->sg); + if (!--piter->__nents || !piter->sg) + return false; + } + + return true; +} + + +dma_addr_t sg_page_iter_dma_address(struct sg_page_iter *piter) +{ + return sg_dma_address(piter->sg) + (piter->sg_pgoffset << PAGE_SHIFT); +} + + +/****************** + ** linux/kref.h ** + ******************/ + +void kref_init(struct kref *kref) { + kref->refcount.counter = 1; } + +void kref_get(struct kref *kref) { + kref->refcount.counter++; } + +int kref_put(struct kref *kref, void (*release) (struct kref *kref)) +{ + kref->refcount.counter--; + if (kref->refcount.counter == 0) { + release(kref); + return 1; + } + return 0; +} + + +/***************************** + ** drivers/video/fbsysfs.c ** + *****************************/ + +struct fb_info *framebuffer_alloc(size_t size, struct device *dev) +{ + static constexpr int BYTES_PER_LONG = BITS_PER_LONG / 8; + static constexpr int PADDING = + BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG); + + int fb_info_size = sizeof(struct fb_info); + struct fb_info *info; + char *p; + + if (size) + fb_info_size += PADDING; + + p = (char*)kzalloc(fb_info_size + size, GFP_KERNEL); + + if (!p) + return NULL; + + info = (struct fb_info *) p; + + if (size) + info->par = p + fb_info_size; + + //info->device = dev; + + return info; +} + +void framebuffer_release(struct fb_info *info) +{ + kfree(info); +} + + +/**************** + ** linux/fb.h ** + ****************/ + +struct apertures_struct *alloc_apertures(unsigned int max_num) +{ + struct apertures_struct *a = (struct apertures_struct*) + kzalloc(sizeof(struct apertures_struct) + + max_num * sizeof(struct aperture), GFP_KERNEL); + if (!a) + return NULL; + a->count = max_num; + return a; +} + +extern "C" void update_framebuffer_config() +{ + struct drm_i915_private *dev_priv = (struct drm_i915_private*)singleton_drm_device->dev_private; + struct intel_framebuffer * ifb = &dev_priv->fbdev->ifb; + + struct drm_connector *connector; + list_for_each_entry(connector, &singleton_drm_device->mode_config.connector_list, head) + connector->force = DRM_FORCE_UNSPECIFIED; + intel_fbdev_fini(singleton_drm_device); + i915_gem_object_release_stolen(ifb->obj); + drm_mode_config_reset(singleton_drm_device); + intel_fbdev_init(singleton_drm_device); + intel_fbdev_initial_config(singleton_drm_device); +} + +static Genode::addr_t new_fb_ds_base = 0; +static Genode::addr_t cur_fb_ds_base = 0; +static Genode::size_t cur_fb_ds_size = 0; + +Genode::Dataspace_capability Framebuffer::framebuffer_dataspace() +{ + if (cur_fb_ds_base) + Lx::iounmap((void*)cur_fb_ds_base); + cur_fb_ds_base = new_fb_ds_base; + return Lx::ioremap_lookup(cur_fb_ds_base, cur_fb_ds_size); +} + +int register_framebuffer(struct fb_info *fb_info) +{ + using namespace Genode; + + fb_info->fbops->fb_set_par(fb_info); + new_fb_ds_base = (addr_t)fb_info->screen_base; + cur_fb_ds_size = (size_t)fb_info->screen_size; + Framebuffer::root->update(fb_info->var.yres_virtual, fb_info->fix.line_length / 2); + return 0; +} + +int unregister_framebuffer(struct fb_info *fb_info) { TRACE; return 0; } -int drm_irq_install(struct drm_device *dev) +/********************************************* + ** drivers/gpu/drm/i915/intel_ringbuffer.c ** + *********************************************/ + +int intel_init_render_ring_buffer(struct drm_device *dev) { - TRACE; + drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring = &dev_priv->ring[0]; + ring->dev = dev; return 0; } @@ -534,48 +1123,16 @@ int drm_irq_install(struct drm_device *dev) ** Stubs for non-ported driver code ** **************************************/ -void intel_pm_setup(struct drm_device *dev) -{ - TRACE; -} - -void intel_init_pm(struct drm_device *dev) -{ - TRACE; -} - -int intel_power_domains_init(struct drm_device *dev) -{ - TRACE; - return 0; -} - -void intel_power_domains_init_hw(struct drm_device *dev) -{ - TRACE; -} - void pm_qos_add_request(struct pm_qos_request *req, int pm_qos_class, s32 value) { TRACE; } -void intel_disable_gt_powersave(struct drm_device *dev) +void pm_qos_update_request(struct pm_qos_request *req, s32 new_value) { TRACE; } -void intel_setup_bios(struct drm_device *dev) -{ - TRACE; -} - -int intel_parse_bios(struct drm_device *dev) -{ - TRACE; - return -1; -} - void i915_gem_detect_bit_6_swizzle(struct drm_device *dev) { TRACE; @@ -623,5 +1180,212 @@ struct resource * devm_request_mem_region(struct device *dev, resource_size_t st return &dummy; } +int acpi_lid_notifier_register(struct notifier_block *nb) +{ + TRACE; + return 0; +} + +void update_genode_report() +{ + static Genode::Reporter reporter("connectors"); + + try { + Genode::config()->reload(); + reporter.enabled(Genode::config()->xml_node().sub_node("report") + .attribute_value(reporter.name().string(), false)); + } catch (...) { + reporter.enabled(false); + } + + if (!reporter.is_enabled()) return; + + try { + + Genode::Reporter::Xml_generator xml(reporter, [&] () + { + struct drm_device *dev = singleton_drm_device; + struct drm_connector *connector; + struct list_head panel_list; + + INIT_LIST_HEAD(&panel_list); + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + xml.node("connector", [&] () + { + bool connected = connector->status == connector_status_connected; + xml.attribute("name", drm_get_connector_name(connector)); + xml.attribute("connected", connected); + + struct drm_display_mode *mode; + struct list_head mode_list; + INIT_LIST_HEAD(&mode_list); + list_for_each_entry(mode, &connector->modes, head) { + xml.node("mode", [&] () + { + xml.attribute("width", mode->hdisplay); + xml.attribute("height", mode->vdisplay); + xml.attribute("hz", mode->vrefresh); + }); + } + INIT_LIST_HEAD(&mode_list); + list_for_each_entry(mode, &connector->probed_modes, head) { + xml.node("mode", [&] () + { + xml.attribute("width", mode->hdisplay); + xml.attribute("height", mode->vdisplay); + xml.attribute("hz", mode->vrefresh); + }); + } + }); + } + }); + } catch (...) { + PWRN("Failed to generate report"); + } +} + +int drm_sysfs_connector_add(struct drm_connector *connector) +{ + TRACE; + return 0; +} + +void drm_sysfs_connector_remove(struct drm_connector *connector) +{ + TRACE; +} + +void assert_spin_locked(spinlock_t *lock) +{ + TRACE; +} + +int intel_init_bsd_ring_buffer(struct drm_device *dev) +{ + TRACE; + return 0; +} + +int intel_init_blt_ring_buffer(struct drm_device *dev) +{ + TRACE; + return 0; +} + +int intel_init_vebox_ring_buffer(struct drm_device *dev) +{ + TRACE; + return 0; +} + +int __must_check i915_gem_context_init(struct drm_device *dev) +{ + TRACE; + return 0; +} + +void spin_lock_irq(spinlock_t *lock) +{ + TRACE; +} + +void spin_unlock_irq(spinlock_t *lock) +{ + TRACE; +} + +int fb_get_options(const char *name, char **option) +{ + using namespace Genode; + + String<64> con_to_scan(name); + + /* try to read custom user config */ + try { + config()->reload(); + Xml_node node = config()->xml_node(); + Xml_node xn = node.sub_node(); + for (unsigned i = 0; i < node.num_sub_nodes(); xn = xn.next()) { + if (!xn.has_type("connector")) continue; + + String<64> con_policy; + xn.attribute("name").value(&con_policy); + if (!(con_policy == con_to_scan)) continue; + + bool enabled = xn.attribute_value("enabled", true); + if (!enabled) { + *option = (char*)"d"; + return 0; + } + + unsigned width, height; + xn.attribute("width").value(&width); + xn.attribute("height").value(&height); + + *option = (char*)kmalloc(64, GFP_KERNEL); + Genode::snprintf(*option, 64, "%ux%u", width, height); + PLOG("set connector %s to %ux%u", con_policy.string(), width, height); + } + } catch (...) { } + return 0; +} + +void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) +{ + TRACE; +} + + +int atomic_notifier_chain_register(struct atomic_notifier_head *nh, struct notifier_block *nb) +{ + TRACE; + return 0; +} + +int register_sysrq_key(int key, struct sysrq_key_op *op) +{ + TRACE; + return 0; +} + +void drm_vblank_off(struct drm_device *dev, int crtc) +{ + TRACE; +} + + +void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize, char *linebuf, size_t linebuflen, bool ascii) +{ + TRACE; +} + +void trace_intel_gpu_freq_change(int) +{ + TRACE; +} + +struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) +{ + TRACE; + return NULL; +} + +int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, struct notifier_block *nb) +{ + TRACE; + return 0; +} + +int unregister_sysrq_key(int key, struct sysrq_key_op *op) +{ + TRACE; + return 0; +} + +void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) +{ + TRACE; +} DEFINE_SPINLOCK(mchdev_lock); diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_private.h b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_private.h index c47c5b028..73a575e0c 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_private.h +++ b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_private.h @@ -14,10 +14,14 @@ /* Linux kernel API */ #include +#if 0 #define TRACE \ do { \ PLOG("%s not implemented", __func__); \ } while (0) +#else +#define TRACE do { ; } while (0) +#endif #define TRACE_AND_STOP \ do { \ @@ -25,4 +29,12 @@ Genode::sleep_forever(); \ } while (0) +#define ASSERT(x) \ + do { \ + if (!(x)) { \ + PWRN("%s:%u assertion failed", __func__, __LINE__); \ + Genode::sleep_forever(); \ + } \ + } while (0) + #endif /* _LX_EMUL_PRIVATE_H_ */ diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/main.cc b/repos/dde_linux/src/drivers/framebuffer/intel/main.cc index c35960c3d..93c425aea 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/main.cc +++ b/repos/dde_linux/src/drivers/framebuffer/intel/main.cc @@ -14,11 +14,15 @@ /* Genode includes */ #include #include +#include + +#include /* Linux emulation environment includes */ #include #include #include +#include #include #include @@ -39,6 +43,13 @@ Lx::Timer & Lx::timer(Server::Entrypoint *ep, unsigned long *jiffies) } +Lx::Irq & Lx::Irq::irq(Server::Entrypoint *ep) +{ + static Lx::Irq irq(*ep); + return irq; +} + + Platform::Connection *Lx::pci() { static Platform::Connection _pci; @@ -58,23 +69,15 @@ namespace Lx { }; +Framebuffer::Root * Framebuffer::root = nullptr; + + extern "C" int postcore_i2c_init(); /* i2c-core.c */ extern "C" int module_i915_init(); /* i915_drv.c */ +extern "C" void update_framebuffer_config(); -static void run_linux(void *) -{ - PDBG("postcore_i915_init"); - postcore_i2c_init(); - - PDBG("module_i915_init"); - module_i915_init(); - - while (1) { - Lx::scheduler().current()->block_and_schedule(); - } -} - +static void run_linux(void * m); unsigned long jiffies; @@ -83,25 +86,74 @@ struct Server::Main { Entrypoint &ep; + bool _buffered_from_config() + { + try { + config()->reload(); + return Genode::config()->xml_node().attribute_value("buffered", + false); + } catch (...) { return false; } + } + + Framebuffer::Root root_component { &ep.rpc_ep(), Genode::env()->heap(), + _buffered_from_config() }; + /* init singleton Lx::Timer */ Lx::Timer &timer = Lx::timer(&ep, &jiffies); + /* init singleton Lx::Irq */ + Lx::Irq &irq = Lx::Irq::irq(&ep); + /* Linux task that handles the initialization */ - Lx::Task linux { run_linux, nullptr, "linux", + Lx::Task linux { run_linux, reinterpret_cast(this), "linux", Lx::Task::PRIORITY_0, Lx::scheduler() }; Main(Entrypoint &ep) : ep(ep) { Genode::printf("--- intel framebuffer driver ---\n"); + Framebuffer::root = &root_component; + /* give all task a first kick before returning */ Lx::scheduler().schedule(); - - PDBG("returning from main"); } }; +struct Policy_agent +{ + Server::Main &main; + Genode::Signal_rpc_member sd; + + void handle(unsigned) + { + main.linux.unblock(); + Lx::scheduler().schedule(); + } + + Policy_agent(Server::Main &m) + : main(m), sd(main.ep, *this, &Policy_agent::handle) {} +}; + + +static void run_linux(void * m) +{ + Server::Main * main = reinterpret_cast(m); + + postcore_i2c_init(); + module_i915_init(); + + Genode::env()->parent()->announce(main->ep.manage(*Framebuffer::root)); + + static Policy_agent pa(*main); + Genode::config()->sigh(pa.sd); + + while (1) { + Lx::scheduler().current()->block_and_schedule(); + update_framebuffer_config(); + } +} + namespace Server { char const *name() { return "intel_fb_ep"; } diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/target.mk b/repos/dde_linux/src/drivers/framebuffer/intel/target.mk index a92f5c836..99e83e74c 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/target.mk +++ b/repos/dde_linux/src/drivers/framebuffer/intel/target.mk @@ -1,5 +1,6 @@ +REQUIRES = x86 + TARGET = intel_fb_drv -LIBS = base intel_fb_drv intel_fb_include libc-setjmp server +LIBS = base intel_fb_drv intel_fb_include libc-setjmp server config blit SRC_CC = main.cc lx_emul.cc dummies.cc -SRC_C = i2c-algo-bit.c INC_DIR += $(REP_DIR)/src/include diff --git a/repos/dde_linux/src/include/lx_emul/impl/delay.h b/repos/dde_linux/src/include/lx_emul/impl/delay.h index e5a141fc9..1f9fe5e2e 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/delay.h +++ b/repos/dde_linux/src/include/lx_emul/impl/delay.h @@ -14,6 +14,8 @@ /* Genode includes */ #include +#include + /* * XXX We may consider to use the Lx::Timer instead of opening a dedicated * timer session. @@ -24,7 +26,11 @@ static Timer::Connection _delay_timer; void udelay(unsigned long usecs) { _delay_timer.usleep(usecs); } -void msleep(unsigned int msecs) { _delay_timer.msleep(msecs); } +void msleep(unsigned int msecs) +{ + _delay_timer.msleep(msecs); + Lx::timer_update_jiffies(); +} void mdelay(unsigned long msecs) { msleep(msecs); } diff --git a/repos/dde_linux/src/include/lx_emul/impl/gfp.h b/repos/dde_linux/src/include/lx_emul/impl/gfp.h index efd4c34ef..b4067f371 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/gfp.h +++ b/repos/dde_linux/src/include/lx_emul/impl/gfp.h @@ -17,11 +17,13 @@ struct page *alloc_pages(gfp_t gfp_mask, unsigned int order) { - struct page *page = (struct page *)kzalloc(sizeof(struct page), 0); + struct page *page = (struct page *)kzalloc(sizeof(struct page) * 1<addr = Lx::Malloc::dma().alloc(size, 12); + Genode::Ram_dataspace_capability ds_cap = Lx::backend_alloc(size, Genode::UNCACHED); + page->addr = Genode::env()->rm_session()->attach(ds_cap); + page->paddr = Genode::Dataspace_client(ds_cap).phys_addr(); if (!page->addr) { PERR("alloc_pages: %zu failed", size); @@ -31,7 +33,11 @@ struct page *alloc_pages(gfp_t gfp_mask, unsigned int order) Lx::Addr_to_page_mapping::insert(page); - atomic_set(&page->_count, 1); + for (unsigned i = 0; i < 1UL<addr + i*PAGE_SIZE); + page[i].paddr = page->paddr + i*PAGE_SIZE; + atomic_set(&page[i]._count, 1); + } return page; } diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/irq.h b/repos/dde_linux/src/include/lx_emul/impl/internal/irq.h new file mode 100644 index 000000000..2075e2530 --- /dev/null +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/irq.h @@ -0,0 +1,213 @@ +/* + * \brief Signal context for IRQ's + * \author Josef Soentgen + * \author Christian Helmuth + * \author Stefan Kalkowski + * \date 2014-10-14 + */ + +/* + * Copyright (C) 2014-2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _LX_EMUL__IMPL__INTERNAL__IRQ_H_ +#define _LX_EMUL__IMPL__INTERNAL__IRQ_H_ + +/* Genode includes */ +#include +#include +#include + +/* Linux emulation environment includes */ +#include + +namespace Lx { class Irq; } + + +class Lx::Irq +{ + private: + + /** + * Helper utilty for composing IRQ related names + */ + struct Name_composer + { + char name[16]; + + Name_composer(Platform::Device &device) + { + Genode::snprintf(name, sizeof(name), + "irq_%02x:%02x", + device.vendor_id(), + device.device_id()); + } + }; + + /** + * This contains the Linux-driver handlers + */ + class Handler : public Lx::List::Element + { + private: + + void *_dev; /* Linux device */ + irq_handler_t _handler; /* Linux handler */ + irq_handler_t _thread_fn; /* Linux thread function */ + + public: + + Handler(void *dev, irq_handler_t handler, + irq_handler_t thread_fn) + : _dev(dev), _handler(handler), _thread_fn(thread_fn) { } + + bool handle() + { + switch (_handler(0, _dev)) { + case IRQ_WAKE_THREAD: + _thread_fn(0, _dev); + case IRQ_HANDLED: + return true; + case IRQ_NONE: + break; + } + return false; + } + }; + + public: + + /** + * Context encapsulates the handling of an IRQ + */ + class Context : public Lx::List::Element + { + private: + + Name_composer _name; + Platform::Device &_dev; + Genode::Irq_session_client _irq_sess; + Lx::List _handler; /* List of registered handlers */ + Lx::Task _task; + + Genode::Signal_rpc_member _dispatcher; + + /** + * Signal handler + */ + void _handle(unsigned) + { + _task.unblock(); + + /* kick off scheduling */ + Lx::scheduler().schedule(); + } + + static void _run_irq(void *args) + { + Context *ctx = static_cast(args); + + while (1) { + Lx::scheduler().current()->block_and_schedule(); + ctx->handle_irq(); + } + } + + public: + + /** + * Constructor + */ + Context(Server::Entrypoint &ep, + Platform::Device &dev) + : + _name(dev), + _dev(dev), + _irq_sess(dev.irq(0)), + _task(_run_irq, this, _name.name, Lx::Task::PRIORITY_3, Lx::scheduler()), + _dispatcher(ep, *this, &Context::_handle) + { + _irq_sess.sigh(_dispatcher); + + /* initial ack to receive further IRQ signals */ + _irq_sess.ack_irq(); + } + + /** + * Handle IRQ + */ + void handle_irq() + { + bool handled = false; + + /* report IRQ to all clients */ + for (Handler *h = _handler.first(); h; h = h->next()) { + if ((handled = h->handle())) break; + } + + _irq_sess.ack_irq(); + } + + /** + * Add linux handler to context + */ + void add_handler(Handler *h) { _handler.append(h); } + + bool device(Platform::Device &dev) { + return (&dev == &_dev); } + }; + + private: + + using Context_slab = Genode::Tslab; + using Handler_slab = Genode::Tslab; + + Server::Entrypoint &_ep; + Lx::List _list; + Context_slab _context_alloc; + Handler_slab _handler_alloc; + + /** + * Find context for given device + */ + Context *_find_context(Platform::Device &dev) + { + for (Context *i = _list.first(); i; i = i->next()) + if (i->device(dev)) return i; + return nullptr; + } + + Irq(Server::Entrypoint &ep) + : _ep(ep), + _context_alloc(Genode::env()->heap()), + _handler_alloc(Genode::env()->heap()) { } + + public: + + static Irq &irq(Server::Entrypoint *ep = nullptr); + + /** + * Request an IRQ + */ + void request_irq(Platform::Device &dev, irq_handler_t handler, + void *dev_id, irq_handler_t thread_fn = 0) + { + Context *ctx = _find_context(dev); + + /* if this IRQ is not registered */ + if (!ctx) { + ctx = new (&_context_alloc) Context(_ep, dev); + _list.insert(ctx); + } + + /* register Linux handler */ + Handler *h = new (&_handler_alloc) + Handler(dev_id, handler, thread_fn); + ctx->add_handler(h); + } +}; + +#endif /* _LX_EMUL__IMPL__INTERNAL__IRQ_H_ */ diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/malloc.h b/repos/dde_linux/src/include/lx_emul/impl/internal/malloc.h index 5d5bf576a..975f9f274 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/internal/malloc.h +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/malloc.h @@ -119,7 +119,7 @@ class Lx::Malloc msb = SLAB_STOP_LOG2; if (msb > SLAB_STOP_LOG2) { - // PERR("Slab too large %u reqested %zu cached %d", 1U << msb, size, _cached); + PERR("Slab too large %u reqested %zu cached %d", 1U << msb, size, _cached); return 0; } diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/mapped_io_mem_range.h b/repos/dde_linux/src/include/lx_emul/impl/internal/mapped_io_mem_range.h index 3039d172a..ba5d4768c 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/internal/mapped_io_mem_range.h +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/mapped_io_mem_range.h @@ -26,6 +26,8 @@ namespace Lx { class Mapped_io_mem_range; void *ioremap(resource_size_t, unsigned long, Genode::Cache_attribute); + void iounmap(volatile void*); + Genode::Dataspace_capability ioremap_lookup(Genode::addr_t, Genode::size_t); } /** @@ -37,47 +39,58 @@ class Lx::Mapped_io_mem_range : public Lx::List::Element { private: - Genode::Attached_dataspace _ds; - - Genode::size_t const _size; - Genode::addr_t const _phys; - Genode::addr_t const _virt; + Genode::size_t const _size; + Genode::addr_t const _phys; + Genode::Rm_connection _rm; + Genode::Attached_dataspace _ds; + Genode::addr_t const _virt; public: Mapped_io_mem_range(Genode::addr_t phys, Genode::size_t size, - Genode::Io_mem_dataspace_capability ds_cap) - : - _ds(ds_cap), - _size(size), - _phys(phys), - _virt((Genode::addr_t)_ds.local_addr() | (phys & 0xfffUL)) - { } + Genode::Io_mem_dataspace_capability ds_cap, + Genode::addr_t offset) + : _size(size), + _phys(phys), + _rm(0, size), + _ds(_rm.dataspace()), + _virt((Genode::addr_t)_ds.local_addr() | (phys &0xfffUL)) { + _rm.attach_at(ds_cap, 0, size, offset); } Genode::addr_t phys() const { return _phys; } Genode::addr_t virt() const { return _virt; } + Genode::Dataspace_capability cap() const { return _ds.cap(); } /** * Return true if the mapped range contains the specified sub range */ - bool contains(Genode::addr_t phys, Genode::size_t size) const + bool phys_range(Genode::addr_t phys, Genode::size_t size) const { return (phys >= _phys) && (phys + size - 1 <= _phys + _size - 1); } + + /** + * Return true if the mapped range contains the specified sub range + */ + bool virt_range(Genode::addr_t virt, Genode::size_t size) const + { + return (virt >= _virt) && (virt + size - 1 <= _virt + _size - 1); + } }; +static Lx::List ranges; + + void *Lx::ioremap(resource_size_t phys_addr, unsigned long size, Genode::Cache_attribute cache_attribute) { using namespace Genode; - static Lx::List ranges; - /* search for the requested region within the already mapped ranges */ for (Lx::Mapped_io_mem_range *r = ranges.first(); r; r = r->next()) { - if (r->contains(phys_addr, size)) { + if (r->phys_range(phys_addr, size)) { void * const virt = (void *)(r->virt() + phys_addr - r->phys()); PLOG("ioremap: return sub range phys 0x%lx (size %lx) to virt 0x%lx", (long)phys_addr, (long)size, (long)virt); @@ -85,20 +98,20 @@ void *Lx::ioremap(resource_size_t phys_addr, unsigned long size, } } + addr_t offset; Io_mem_dataspace_capability ds_cap = - Lx::pci_dev_registry()->io_mem(phys_addr, cache_attribute, size); + Lx::pci_dev_registry()->io_mem(phys_addr, cache_attribute, + size, offset); if (!ds_cap.valid()) { - PERR("Failed to request I/O memory: [%zx,%lx)", phys_addr, phys_addr + size); return nullptr; } - Genode::size_t const ds_size = Genode::Dataspace_client(ds_cap).size(); - Lx::Mapped_io_mem_range *io_mem = - new (env()->heap()) Lx::Mapped_io_mem_range(phys_addr, ds_size, ds_cap); + new (env()->heap()) Lx::Mapped_io_mem_range(phys_addr, size, + ds_cap, offset); ranges.insert(io_mem); @@ -109,4 +122,30 @@ void *Lx::ioremap(resource_size_t phys_addr, unsigned long size, return (void *)(io_mem->virt() + sub_page_offset); } +void Lx::iounmap(volatile void * virt) +{ + using namespace Genode; + + /* search for the requested region within the already mapped ranges */ + for (Lx::Mapped_io_mem_range *r = ranges.first(); r; r = r->next()) { + + if (r->virt() == (addr_t)virt) { + ranges.remove(r); + destroy(env()->heap(), r); + return; + } + } +} + +Genode::Dataspace_capability +Lx::ioremap_lookup(Genode::addr_t virt_addr, Genode::size_t size) +{ + /* search for the requested region within the already mapped ranges */ + for (Lx::Mapped_io_mem_range *r = ranges.first(); r; r = r->next()) + if (r->virt_range(virt_addr, size)) + return r->cap(); + + return Genode::Dataspace_capability(); +} + #endif /* _LX_EMUL__IMPL__INTERNAL__MAPPED_IO_MEM_RANGE_H_ */ diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/pci_backend_alloc.h b/repos/dde_linux/src/include/lx_emul/impl/internal/pci_backend_alloc.h index df2804dad..1a3c27737 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/internal/pci_backend_alloc.h +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/pci_backend_alloc.h @@ -78,12 +78,17 @@ Lx::backend_alloc(Genode::addr_t size, Genode::Cache_attribute cached) cap = env()->ram_session()->alloc(size); o = new (env()->heap()) Ram_object(cap); } else { - /* transfer quota to pci driver, otherwise it will give us a exception */ - char buf[32]; - Genode::snprintf(buf, sizeof(buf), "ram_quota=%ld", size); - Genode::env()->parent()->upgrade(Lx::pci()->cap(), buf); + size_t donate = size; + cap = retry( + [&] () { return Lx::pci()->alloc_dma_buffer(size); }, + [&] () { + char quota[32]; + Genode::snprintf(quota, sizeof(quota), "ram_quota=%zd", + donate); + Genode::env()->parent()->upgrade(Lx::pci()->cap(), quota); + donate = donate * 2 > size ? 4096 : donate * 2; + }); - cap = Lx::pci()->alloc_dma_buffer(size); o = new (env()->heap()) Dma_object(cap); } @@ -96,13 +101,16 @@ void Lx::backend_free(Genode::Ram_dataspace_capability cap) { using namespace Genode; - Memory_object_base *o = memory_pool.lookup_and_lock(cap); - if (!o) - return; + Memory_object_base *object; + memory_pool.apply(cap, [&] (Memory_object_base *o) { + object = o; + if (!object) + return; - o->free(); - memory_pool.remove_locked(o); - destroy(env()->heap(), o); + object->free(); + memory_pool.remove(object); + }); + destroy(env()->heap(), object); } diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/pci_dev.h b/repos/dde_linux/src/include/lx_emul/impl/internal/pci_dev.h index 8d882b6ea..8a48166cd 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/internal/pci_dev.h +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/pci_dev.h @@ -54,6 +54,7 @@ class Lx::Pci_dev : public pci_dev, public Lx::List::Element Platform::Device_client _client; Io_port _io_port; + Genode::Io_mem_session_capability _io_mem[DEVICE_COUNT_RESOURCE]; /* offset used in PCI config space */ enum Pci_config { IRQ = 0x3c, REV = 0x8, CMD = 0x4, @@ -143,7 +144,7 @@ class Lx::Pci_dev : public pci_dev, public Lx::List::Element /* enable bus master */ cmd |= 0x4; - _client.config_write(CMD, cmd, Device::ACCESS_16BIT); + config_write(CMD, cmd); /* get pci express capability */ this->pcie_cap = 0; @@ -178,12 +179,34 @@ class Lx::Pci_dev : public pci_dev, public Lx::List::Element template void config_write(unsigned int devfn, T val) { - _client.config_write(devfn, val, _access_size(val)); + Genode::size_t donate = 4096; + Genode::retry( + [&] () { _client.config_write(devfn, val, _access_size(val)); }, + [&] () { + char quota[32]; + Genode::snprintf(quota, sizeof(quota), "ram_quota=%zd", + donate); + Genode::env()->parent()->upgrade(pci()->cap(), quota); + donate *= 2; + }); } Platform::Device &client() { return _client; } Io_port &io_port() { return _io_port; } + + Genode::Io_mem_session_capability io_mem(unsigned bar, + Genode::Cache_attribute cache_attribute) + { + if (bar >= DEVICE_COUNT_RESOURCE) + return Genode::Io_mem_session_capability(); + + if (!_io_mem[bar].valid()) + _io_mem[bar] = _client.io_mem(_client.phys_bar_to_virt(bar), + cache_attribute); + + return _io_mem[bar]; + } }; @@ -200,7 +223,7 @@ void Lx::for_each_pci_device(FUNC const &func) { /* * Functor that is called if the platform driver throws a - * 'Quota_exceeded' exception. + * 'Out_of_metadata' exception. */ auto handler = [&] () { Genode::env()->parent()->upgrade(Lx::pci()->cap(), @@ -212,7 +235,7 @@ void Lx::for_each_pci_device(FUNC const &func) */ Platform::Device_capability cap; auto attempt = [&] () { cap = Lx::pci()->first_device(); }; - Genode::retry(attempt, handler); + Genode::retry(attempt, handler); /* * Iterate over the devices of the platform session. @@ -234,7 +257,7 @@ void Lx::for_each_pci_device(FUNC const &func) Lx::pci()->release_device(cap); cap = next_cap; }; - Genode::retry(attempt, handler); + Genode::retry(attempt, handler); } } diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/pci_dev_registry.h b/repos/dde_linux/src/include/lx_emul/impl/internal/pci_dev_registry.h index 12d23fa19..43375a98f 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/internal/pci_dev_registry.h +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/pci_dev_registry.h @@ -29,6 +29,7 @@ namespace Lx { Pci_dev_registry *pci_dev_registry(); } + class Lx::Pci_dev_registry { private: @@ -45,7 +46,8 @@ class Lx::Pci_dev_registry Genode::Io_mem_dataspace_capability io_mem(resource_size_t phys, Genode::Cache_attribute cache_attribute, - Genode::size_t size) + Genode::size_t size, + Genode::addr_t &offset) { enum { PCI_ROM_RESOURCE = 6 }; @@ -54,23 +56,18 @@ class Lx::Pci_dev_registry unsigned bar = 0; for (; bar < PCI_ROM_RESOURCE; bar++) { if ((pci_resource_flags(d, bar) & IORESOURCE_MEM) && - (pci_resource_start(d, bar) == phys)) + (pci_resource_start(d, bar) <= phys) && + (pci_resource_end(d, bar) >= (phys+size-1))) break; } if (bar >= PCI_ROM_RESOURCE) continue; - Platform::Device &device = d->client(); - - unsigned const resource_id = - device.phys_bar_to_virt(bar); - /* offset from the beginning of the PCI resource */ - Genode::addr_t const offset = - phys - pci_resource_start(d, bar); + offset = phys - pci_resource_start(d, bar); Genode::Io_mem_session_capability io_mem_cap = - device.io_mem(resource_id, cache_attribute, offset, size); + d->io_mem(bar, cache_attribute); return Genode::Io_mem_session_client(io_mem_cap).dataspace(); } @@ -82,7 +79,6 @@ class Lx::Pci_dev_registry template T io_read(unsigned port) { - PDBG("io_read %u", port); /* try I/O access on all PCI devices */ for (Pci_dev *d = _devs.first(); d; d = d->next()) { T value = 0; @@ -97,8 +93,6 @@ class Lx::Pci_dev_registry template void io_write(unsigned port, T value) { - PDBG("io_write %u", port); - /* try I/O access on all PCI devices, return on first success */ for (Pci_dev *d = _devs.first(); d; d = d->next()) if (d->io_port().out(port, value)) diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/scheduler.h b/repos/dde_linux/src/include/lx_emul/impl/internal/scheduler.h index 65358dedb..efd2acb0e 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/internal/scheduler.h +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/scheduler.h @@ -52,7 +52,7 @@ class Lx::Scheduler { private: - bool verbose = true; + bool verbose = false; Lx::List _present_list; Genode::Lock _present_list_mutex; diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/task.h b/repos/dde_linux/src/include/lx_emul/impl/internal/task.h index bcac85d43..242e23f9e 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/internal/task.h +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/task.h @@ -120,6 +120,8 @@ class Lx::Task : public Lx::List::Element void wait_enqueue(List *list) { + if (_wait_le_enqueued && _wait_list == list) return; + if (_wait_le_enqueued) { PERR("%p already queued in %p", this, _wait_list); Genode::sleep_forever(); diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/timer.h b/repos/dde_linux/src/include/lx_emul/impl/internal/timer.h index 6ea712168..41f822823 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/internal/timer.h +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/timer.h @@ -23,6 +23,7 @@ /* Linux emulation environment includes */ #include +#include namespace Lx { diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/work.h b/repos/dde_linux/src/include/lx_emul/impl/internal/work.h new file mode 100644 index 000000000..b6b2b429e --- /dev/null +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/work.h @@ -0,0 +1,146 @@ +/* + * \brief Work queue implementation + * \author Josef Soentgen + * \author Stefan Kalkowski + * \date 2015-10-26 + */ + +/* + * Copyright (C) 2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _LX_EMUL__IMPL__INTERNAL__WORK_H_ +#define _LX_EMUL__IMPL__INTERNAL__WORK_H_ + +/* Linux emulation environment includes */ +#include +#include + +namespace Lx { + class Work; +} + + +class Lx::Work +{ + public: + + /** + * Context encapsulates a normal work item + */ + struct Context : public Lx::List::Element + { + void *work; + enum Type { NORMAL, DELAYED, TASKLET } type; + + void exec() { + switch (type) { + case NORMAL: + { + work_struct *w = static_cast(work); + w->func(w); + } + break; + case DELAYED: + { + delayed_work *w = static_cast(work); + w->work.func(&(w)->work); + } + break; + case TASKLET: + { + tasklet_struct *tasklet = static_cast(work); + tasklet->func(tasklet->data); + } + break; + } + } + + Context(delayed_work *w) : work(w), type(DELAYED) { } + Context(work_struct *w) : work(w), type(NORMAL) { } + Context(tasklet_struct *w) : work(w), type(TASKLET) { } + }; + + private: + + Lx::Task _task; + Lx::List _list; + + Genode::Tslab _work_alloc; + + Work() + : _task(Work::run_work, reinterpret_cast(this), "work_queue", + Lx::Task::PRIORITY_2, Lx::scheduler()), + _work_alloc(Genode::env()->heap()) { } + + public: + + static Work & work_queue(); + + /** + * Unblock corresponding task + */ + void unblock() { _task.unblock(); } + + /** + * Schedule work item + */ + template + void schedule(WORK *work) + { + Context *c = new (&_work_alloc) Context(work); + _list.append(c); + } + + /** + * Execute all available work items + */ + void exec() + { + while (Context *c = _list.first()) { + c->exec(); + _list.remove(c); + destroy(&_work_alloc, c); + } + } + + /** + * Cancel work item + */ + bool cancel_work(struct work_struct *work, bool sync = false) + { + for (Context *c = _list.first(); c; c = c->next()) { + if (c->work == work) { + if (sync) + c->exec(); + + _list.remove(c); + destroy(&_work_alloc, c); + return true; + } + } + + return false; + } + + static void run_work(void * wq) + { + Work * work_queue = reinterpret_cast(wq); + while (1) { + work_queue->exec(); + Lx::scheduler().current()->block_and_schedule(); + } + } +}; + + +Lx::Work & Lx::Work::work_queue() +{ + static Lx::Work work; + return work; +} + +#endif /* _LX_EMUL__IMPL__INTERNAL__WORK_H_ */ diff --git a/repos/dde_linux/src/include/lx_emul/impl/io.h b/repos/dde_linux/src/include/lx_emul/impl/io.h index 3ace39c8d..f8cc7cbc2 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/io.h +++ b/repos/dde_linux/src/include/lx_emul/impl/io.h @@ -15,7 +15,7 @@ #include -void *ioremap(resource_size_t phys_addr, unsigned long size) +void *ioremap(phys_addr_t phys_addr, unsigned long size) { return Lx::ioremap(phys_addr, size, Genode::UNCACHED); } diff --git a/repos/dde_linux/src/include/lx_emul/impl/pci.h b/repos/dde_linux/src/include/lx_emul/impl/pci.h index 8ef3d162e..f3563a11b 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/pci.h +++ b/repos/dde_linux/src/include/lx_emul/impl/pci.h @@ -44,7 +44,7 @@ extern "C" int pci_register_driver(struct pci_driver *driver) /* look if we find the device ID in the driver's 'id_table' */ pci_device_id const *matching_id = nullptr; - for (pci_device_id const *id = id_table; id->class_ != (unsigned)PCI_ANY_ID; id++) + for (pci_device_id const *id = id_table; id->class_ != 0; id++) if (id->device == device_id) matching_id = id; @@ -62,7 +62,7 @@ extern "C" int pci_register_driver(struct pci_driver *driver) pci_dev->dev.driver = &driver->driver; /* call probe function of the Linux driver */ - if (!driver->probe(pci_dev, matching_id)) { + if (driver->probe(pci_dev, matching_id)) { /* if the probing failed, revert the creation of 'pci_dev' */ pci_dev_put(pci_dev); @@ -88,6 +88,13 @@ extern "C" size_t pci_resource_start(struct pci_dev *dev, unsigned bar) return dev->resource[bar].start; } +extern "C" size_t pci_resource_end(struct pci_dev *dev, unsigned bar) +{ + if (bar >= DEVICE_COUNT_RESOURCE) + return 0; + + return dev->resource[bar].end; +} extern "C" size_t pci_resource_len(struct pci_dev *dev, unsigned bar) { diff --git a/repos/dde_linux/src/include/lx_emul/impl/sched.h b/repos/dde_linux/src/include/lx_emul/impl/sched.h index 5c17033d0..7a80d43d4 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/sched.h +++ b/repos/dde_linux/src/include/lx_emul/impl/sched.h @@ -26,14 +26,15 @@ signed long schedule_timeout(signed long timeout) { struct timer_list timer; + unsigned long expire = timeout + jiffies; setup_timer(&timer, unblock_task, (unsigned long)Lx::scheduler().current()); - mod_timer(&timer, timeout); + mod_timer(&timer, expire); Lx::scheduler().current()->block_and_schedule(); del_timer(&timer); - timeout = (timeout - jiffies); + timeout = (expire - jiffies); return timeout < 0 ? 0 : timeout; } diff --git a/repos/dde_linux/src/include/lx_emul/impl/work.h b/repos/dde_linux/src/include/lx_emul/impl/work.h new file mode 100644 index 000000000..1069addc7 --- /dev/null +++ b/repos/dde_linux/src/include/lx_emul/impl/work.h @@ -0,0 +1,80 @@ +/* + * \brief Implementation of linux/workqueue.h + * \author Stefan Kalkowski + * \date 2015-10-26 + */ + +/* + * Copyright (C) 2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + + +int schedule_work(struct work_struct *work) +{ + Lx::Work::work_queue().schedule(work); + Lx::Work::work_queue().unblock(); + return 1; +} + + +static void _schedule_delayed_work(unsigned long w) +{ + schedule_work((struct work_struct *)w); +} + + +bool queue_delayed_work(struct workqueue_struct *wq, + struct delayed_work *dwork, unsigned long delay) +{ + /* treat delayed work without delay like any other work */ + if (delay == 0) { + schedule_work(&dwork->work); + } else { + setup_timer(&dwork->timer, _schedule_delayed_work, (unsigned long)&dwork->work); + mod_timer(&dwork->timer, delay); + } + return true; +} + + +int schedule_delayed_work(struct delayed_work *dwork, unsigned long delay) +{ + return queue_delayed_work(system_wq, dwork, delay); +} + + +bool cancel_work_sync(struct work_struct *work) +{ + return Lx::Work::work_queue().cancel_work(work, true); +} + + +bool cancel_delayed_work(struct delayed_work *dwork) +{ + int pending = timer_pending(&dwork->timer); + del_timer(&dwork->timer); + + /* if the timer is still pending dwork was not executed */ + return pending; +} + + +bool cancel_delayed_work_sync(struct delayed_work *dwork) +{ + bool pending = cancel_delayed_work(dwork); + + if (pending) { + PERR("WARN: delayed_work %p is executed directly in current '%s' routine", + dwork, Lx::scheduler().current()->name()); + + dwork->work.func(&dwork->work); + } + + return pending; +} + diff --git a/repos/dde_linux/src/include/lx_emul/irq.h b/repos/dde_linux/src/include/lx_emul/irq.h index ad3e43e88..5ac80de52 100644 --- a/repos/dde_linux/src/include/lx_emul/irq.h +++ b/repos/dde_linux/src/include/lx_emul/irq.h @@ -24,3 +24,10 @@ typedef enum irqreturn { IRQ_HANDLED = 1, IRQ_WAKE_THREAD = 2, } irqreturn_t; + + +/*********************** + ** linux/interrupt.h ** + ***********************/ + +typedef irqreturn_t (*irq_handler_t)(int, void *); diff --git a/repos/dde_linux/src/include/lx_emul/kernel.h b/repos/dde_linux/src/include/lx_emul/kernel.h index 7ec001ad6..7cc116d91 100644 --- a/repos/dde_linux/src/include/lx_emul/kernel.h +++ b/repos/dde_linux/src/include/lx_emul/kernel.h @@ -39,6 +39,15 @@ #define KERN_WARNING "WARNING: " #define KERN_WARN "WARNING: " +static inline int _printk(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + lx_vprintf(fmt, args); + va_end(args); + return 0; +} + /* * Debug macros */ diff --git a/repos/dde_linux/src/include/lx_emul/pci.h b/repos/dde_linux/src/include/lx_emul/pci.h index cbbd6fb29..dac438737 100644 --- a/repos/dde_linux/src/include/lx_emul/pci.h +++ b/repos/dde_linux/src/include/lx_emul/pci.h @@ -96,6 +96,7 @@ return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val); } size_t pci_resource_len(struct pci_dev *dev, unsigned bar); size_t pci_resource_start(struct pci_dev *dev, unsigned bar); +size_t pci_resource_end(struct pci_dev *dev, unsigned bar); void pci_dev_put(struct pci_dev *dev); struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from); diff --git a/repos/dde_linux/src/include/lx_emul/scatterlist.h b/repos/dde_linux/src/include/lx_emul/scatterlist.h index f9f4b657d..f0a3df8ca 100644 --- a/repos/dde_linux/src/include/lx_emul/scatterlist.h +++ b/repos/dde_linux/src/include/lx_emul/scatterlist.h @@ -41,7 +41,9 @@ struct sg_table struct sg_page_iter { struct scatterlist *sg; - unsigned int sg_pgoffset; /* page offset within the sg */ + unsigned int sg_pgoffset; /* page offset within the sg */ + unsigned int __nents; + int __pg_advance; }; struct sg_mapping_iter diff --git a/repos/dde_linux/src/include/lx_emul/work.h b/repos/dde_linux/src/include/lx_emul/work.h index 072d01bde..e1cd41917 100644 --- a/repos/dde_linux/src/include/lx_emul/work.h +++ b/repos/dde_linux/src/include/lx_emul/work.h @@ -183,17 +183,17 @@ void __wait_event(wait_queue_head_t); #define wait_event(wq, condition) ({ _wait_event(wq, condition); }) #define wait_event_interruptible(wq, condition) ({ _wait_event(wq, condition); 0; }) -#define _wait_event_timeout(wq, condition, timeout) \ - ({ int res = 1; \ - prepare_to_wait(&wq, 0, 0); \ - while (1) { \ - if ((condition) || !res) { \ - break; \ - } \ - res = schedule_timeout(jiffies + timeout); \ - } \ - finish_wait(&wq, 0); \ - res; \ +#define _wait_event_timeout(wq, condition, timeout) \ + ({ int res = 1; \ + prepare_to_wait(&wq, 0, 0); \ + while (1) { \ + if ((condition) || !res) { \ + break; \ + } \ + res = schedule_timeout(timeout); \ + } \ + finish_wait(&wq, 0); \ + res; \ }) #define wait_event_timeout(wq, condition, timeout) \