From d65beb970dbd57028cdf30fc413a117bb5cca6c1 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Fri, 18 Sep 2015 16:34:19 +0200 Subject: [PATCH] dde_linux: KMS-based Intel framebuffer driver (II) * enable i915 driver from Linux 3.14.5 * tested for generation 5 till 8 GPUs The driver can be configured at run-time via the config ROM. Every connector of the graphic card can be configured separately using the following syntax Also, when enabled within the intel framebuffer driver configuration like the following a simple ram dataspace is propagated to the client and the driver itselfs copies from that buffer to the framebuffer triggered via refresh calls. This option is useful to alleviate tearing effects. The driver distributes all available connectors of the graphic card and their supported resolutions via a report. It looks like follows ... ... The driver distributes the report only if this is stated within its configuration, like the following Fix #1764 --- repos/base/run/platform_drv.inc | 7 +- repos/dde_linux/intel_fb.list | 23 +- repos/dde_linux/lib/mk/intel_fb_drv.mk | 12 +- repos/dde_linux/patches/intel_fb_16bit.patch | 13 + repos/dde_linux/patches/intel_fb_edp.patch | 55 ++ repos/dde_linux/patches/intel_fb_report.patch | 12 + repos/dde_linux/patches/intel_fb_update.patch | 29 + repos/dde_linux/patches/intel_fb_x201.patch | 15 + repos/dde_linux/ports/dde_linux.hash | 2 +- repos/dde_linux/ports/dde_linux.port | 11 +- repos/dde_linux/run/intel_fb.run | 29 +- .../src/drivers/framebuffer/intel/README | 55 ++ .../src/drivers/framebuffer/intel/dummies.cc | 85 +- .../drivers/framebuffer/intel/gen_dummies.h | 793 ++-------------- .../drivers/framebuffer/intel/i2c-algo-bit.c | 31 - .../framebuffer/intel/include/component.h | 157 ++++ .../framebuffer/intel/include/drm/drmP.h | 41 +- .../framebuffer/intel/include/lx_emul.h | 321 +++++-- .../src/drivers/framebuffer/intel/lx_emul.cc | 876 ++++++++++++++++-- .../framebuffer/intel/lx_emul_private.h | 12 + .../src/drivers/framebuffer/intel/main.cc | 84 +- .../src/drivers/framebuffer/intel/target.mk | 5 +- .../src/include/lx_emul/impl/delay.h | 8 +- .../dde_linux/src/include/lx_emul/impl/gfp.h | 12 +- .../src/include/lx_emul/impl/internal/irq.h | 213 +++++ .../include/lx_emul/impl/internal/malloc.h | 2 +- .../impl/internal/mapped_io_mem_range.h | 81 +- .../lx_emul/impl/internal/pci_backend_alloc.h | 30 +- .../include/lx_emul/impl/internal/pci_dev.h | 33 +- .../lx_emul/impl/internal/pci_dev_registry.h | 20 +- .../include/lx_emul/impl/internal/scheduler.h | 2 +- .../src/include/lx_emul/impl/internal/task.h | 2 + .../src/include/lx_emul/impl/internal/timer.h | 1 + .../src/include/lx_emul/impl/internal/work.h | 146 +++ repos/dde_linux/src/include/lx_emul/impl/io.h | 2 +- .../dde_linux/src/include/lx_emul/impl/pci.h | 11 +- .../src/include/lx_emul/impl/sched.h | 5 +- .../dde_linux/src/include/lx_emul/impl/work.h | 80 ++ repos/dde_linux/src/include/lx_emul/irq.h | 7 + repos/dde_linux/src/include/lx_emul/kernel.h | 9 + repos/dde_linux/src/include/lx_emul/pci.h | 1 + .../src/include/lx_emul/scatterlist.h | 4 +- repos/dde_linux/src/include/lx_emul/work.h | 22 +- 43 files changed, 2299 insertions(+), 1060 deletions(-) create mode 100644 repos/dde_linux/patches/intel_fb_16bit.patch create mode 100644 repos/dde_linux/patches/intel_fb_edp.patch create mode 100644 repos/dde_linux/patches/intel_fb_report.patch create mode 100644 repos/dde_linux/patches/intel_fb_update.patch create mode 100644 repos/dde_linux/patches/intel_fb_x201.patch create mode 100644 repos/dde_linux/src/drivers/framebuffer/intel/README delete mode 100644 repos/dde_linux/src/drivers/framebuffer/intel/i2c-algo-bit.c create mode 100644 repos/dde_linux/src/drivers/framebuffer/intel/include/component.h create mode 100644 repos/dde_linux/src/include/lx_emul/impl/internal/irq.h create mode 100644 repos/dde_linux/src/include/lx_emul/impl/internal/work.h create mode 100644 repos/dde_linux/src/include/lx_emul/impl/work.h 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) \