diff --git a/repos/dde_linux/intel_fb.list b/repos/dde_linux/intel_fb.list
new file mode 100644
index 0000000000..011cfa1f0c
--- /dev/null
+++ b/repos/dde_linux/intel_fb.list
@@ -0,0 +1,63 @@
+linux-3.14.5/drivers/char/agp/intel-gtt.c
+linux-3.14.5/drivers/char/agp/intel-agp.h
+linux-3.14.5/drivers/char/agp/agp.h
+linux-3.14.5/drivers/char/agp/generic.c
+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/gpu/drm/drm_mm.c
+linux-3.14.5/drivers/gpu/drm/drm_crtc.c
+linux-3.14.5/drivers/gpu/drm/drm_edid.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
+linux-3.14.5/drivers/gpu/drm/i915/i915_gem.c
+linux-3.14.5/drivers/gpu/drm/i915/i915_gem_stolen.c
+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_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_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/include/asm-generic/atomic64.h
+linux-3.14.5/include/asm-generic/ioctl.h
+linux-3.14.5/include/asm-generic/getorder.h
+linux-3.14.5/include/asm-generic/bitops/__ffs.h
+linux-3.14.5/include/asm-generic/bitops/__fls.h
+linux-3.14.5/include/asm-generic/bitops/ffs.h
+linux-3.14.5/include/asm-generic/bitops/fls.h
+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/log2.h
+linux-3.14.5/include/linux/pci_ids.h
+linux-3.14.5/include/linux/i2c-algo-bit.h
+linux-3.14.5/include/linux/i2c.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_mm.h
+linux-3.14.5/include/drm/drm_crtc.h
+linux-3.14.5/include/drm/drm_crtc_helper.h
+linux-3.14.5/include/drm/drm_edid.h
+linux-3.14.5/include/uapi/drm/i915_drm.h
+linux-3.14.5/include/uapi/drm/drm.h
+linux-3.14.5/include/uapi/linux/pci_regs.h
+linux-3.14.5/include/uapi/linux/i2c.h
+linux-3.14.5/include/uapi/asm-generic/ioctl.h
+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/arch/x86/include/asm/agp.h
+
diff --git a/repos/dde_linux/lib/import/import-intel_fb_include.mk b/repos/dde_linux/lib/import/import-intel_fb_include.mk
new file mode 100644
index 0000000000..ee4a436510
--- /dev/null
+++ b/repos/dde_linux/lib/import/import-intel_fb_include.mk
@@ -0,0 +1,27 @@
+LX_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/drivers/framebuffer/intel
+SRC_DIR := $(REP_DIR)/src/drivers/framebuffer/intel
+
+# architecture-dependent includes
+ifeq ($(filter-out $(SPECS),x86),)
+ ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/x86 \
+ $(LX_CONTRIB_DIR)/arch/x86/include
+ ifeq ($(filter-out $(SPECS),32bit),)
+ ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/x86_32
+ endif # 32bit
+ ifeq ($(filter-out $(SPECS),64bit),)
+ ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/x86_64
+ endif # 64bit
+endif # x86
+
+INC_DIR += $(SRC_DIR)/include \
+ $(REP_DIR)/src/include \
+ $(ARCH_SRC_INC_DIR) \
+ $(LX_CONTRIB_DIR)/drivers/gpu/drm \
+ $(LX_CONTRIB_DIR)/drivers/gpu/include/drm \
+ $(LX_CONTRIB_DIR)/drivers/gpu/include \
+ $(LX_CONTRIB_DIR)/include \
+ $(LX_CONTRIB_DIR)/include/uapi \
+ $(LIB_CACHE_DIR)/intel_fb_include
+
+CC_OPT += -U__linux__ -D__KERNEL__
+CC_OPT += -DCONFIG_DRM_I915_KMS -DCONFIG_I2C -DCONFIG_I2C_BOARDINFO
diff --git a/repos/dde_linux/lib/mk/intel_fb_drv.mk b/repos/dde_linux/lib/mk/intel_fb_drv.mk
new file mode 100644
index 0000000000..d5a5fd05dc
--- /dev/null
+++ b/repos/dde_linux/lib/mk/intel_fb_drv.mk
@@ -0,0 +1,25 @@
+LX_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/drivers/framebuffer/intel
+SRC_DIR := $(REP_DIR)/src/drivers/framebuffer/intel
+
+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/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
+
+#
+# Reduce build noise of compiling contrib code
+#
+CC_WARN = -Wall -Wno-uninitialized -Wno-unused-but-set-variable \
+ -Wno-unused-variable -Wno-unused-function
+
+vpath %.c $(LX_CONTRIB_DIR)/drivers/char/agp
+vpath %.c $(LX_CONTRIB_DIR)/drivers/i2c
+vpath %.c $(LX_CONTRIB_DIR)/drivers/gpu/drm/i915
+vpath %.c $(LX_CONTRIB_DIR)/drivers/gpu/drm
+
diff --git a/repos/dde_linux/lib/mk/intel_fb_include.mk b/repos/dde_linux/lib/mk/intel_fb_include.mk
new file mode 100644
index 0000000000..7ea5de6934
--- /dev/null
+++ b/repos/dde_linux/lib/mk/intel_fb_include.mk
@@ -0,0 +1,17 @@
+#
+# Pseudo library to generate a symlink for each header file included by the
+# contrib code. Each symlink points to the same 'lx_emul.h' file, which
+# provides our emulation of the Linux kernel API.
+#
+
+LX_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/drivers/framebuffer/intel
+LX_EMUL_H := $(REP_DIR)/src/drivers/framebuffer/intel/include/lx_emul.h
+
+GEN_INCLUDES := $(shell grep -rh "^\#include .*\/" $(LX_CONTRIB_DIR) |\
+ sed "s/^\#include [^<\"]*[<\"]\([^>\"]*\)[>\"].*/\1/" | sort | uniq)
+
+all: $(GEN_INCLUDES)
+
+$(GEN_INCLUDES):
+ $(VERBOSE)mkdir -p $(dir $@)
+ $(VERBOSE)ln -sf $(LX_EMUL_H) $@
diff --git a/repos/dde_linux/ports/dde_linux.port b/repos/dde_linux/ports/dde_linux.port
index 0f70dd29b5..4f9f0847f5 100644
--- a/repos/dde_linux/ports/dde_linux.port
+++ b/repos/dde_linux/ports/dde_linux.port
@@ -1,9 +1,12 @@
LICENSE := GPL
VERSION := 1
-DOWNLOADS := dwc_otg.git usb.archive lxip.archive wifi.archive \
+DOWNLOADS := dwc_otg.git usb.archive lxip.archive intel_fb.archive wifi.archive \
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
#
@@ -37,6 +40,16 @@ URL(dwc_otg) := https://github.com/nfeske/dwc_otg.git
REV(dwc_otg) := r2
DIR(dwc_otg) := $(SRC_DIR_USB)/drivers/usb/host/dwc_otg
+#
+# Intel framebuffer driver
+#
+SRC_DIR_INTEL_FB := src/drivers/framebuffer/intel
+URL(intel_fb) := ${URL(usb)}
+SHA(intel_fb) := ${SHA(usb)}
+DIR(intel_fb) := $(SRC_DIR_INTEL_FB)
+TAR_OPT(intel_fb) := --strip-components=1 --files-from $(REP_DIR)/intel_fb.list
+HASH_INPUT += $(REP_DIR)/intel_fb.list
+
#
# mac80211 stack, iwlwifi and iwslegacy sources
#
@@ -162,4 +175,7 @@ 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 :=
+
# vi: set ft=make :
diff --git a/repos/dde_linux/run/intel_fb.run b/repos/dde_linux/run/intel_fb.run
new file mode 100644
index 0000000000..21e339bbc7
--- /dev/null
+++ b/repos/dde_linux/run/intel_fb.run
@@ -0,0 +1,79 @@
+#
+# Build
+#
+
+set build_components {
+ core init
+ drivers/timer
+ drivers/framebuffer/intel
+}
+
+source ${genode_dir}/repos/base/run/platform_drv.inc
+append_platform_drv_build_components
+
+build $build_components
+
+create_boot_directory
+
+proc platform_drv_policy {} {
+ return {
+
+
+
+
+
+ }
+}
+
+#
+# Generate config
+#
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+append_platform_drv_config
+
+append config {
+
+
+
+
+
+
+
+
+}
+
+install_config $config
+
+#
+# Boot modules
+#
+
+# generic modules
+set boot_modules {
+ core init timer intel_fb_drv
+}
+
+append_platform_drv_boot_modules
+
+build_boot_image $boot_modules
+
+run_genode_until forever
diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/dummies.cc b/repos/dde_linux/src/drivers/framebuffer/intel/dummies.cc
new file mode 100644
index 0000000000..6efed3db16
--- /dev/null
+++ b/repos/dde_linux/src/drivers/framebuffer/intel/dummies.cc
@@ -0,0 +1,139 @@
+/*
+ * \brief Dummy functions
+ * \author Norman Feske
+ * \date 2015-08-18
+ */
+
+/*
+ * 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 "lx_emul_private.h"
+
+extern "C" {
+
+#include
+#include
+
+/*
+ * Incorporate dummy implemementations semi-automaticall generated via the
+ * 'gen_dummy' script.
+ */
+
+#include "gen_dummies.h"
+
+/*
+ * Manually defined dummies (because they are not covered by the heuristics
+ * of the 'gen_dummy' script).
+ */
+
+struct timespec timespec_sub(struct timespec lhs, struct timespec rhs)
+{
+ TRACE_AND_STOP;
+ return { 0, 0 };
+}
+
+struct timespec ns_to_timespec(const s64 nsec)
+{
+ TRACE_AND_STOP;
+ 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;
+ return -1;
+}
+
+int i915_gem_execbuffer2(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int i915_gem_set_tiling(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int i915_gem_get_tiling(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ TRACE_AND_STOP;
+ 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;
+ return false;
+}
+
+void *krealloc(const void *, size_t, gfp_t)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+void down_read(struct rw_semaphore *sem)
+{
+ TRACE_AND_STOP;
+}
+
+void device_unregister(struct device *dev)
+{
+ TRACE_AND_STOP;
+}
+
+
+} /* 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
new file mode 100644
index 0000000000..3cfcdc371f
--- /dev/null
+++ b/repos/dde_linux/src/drivers/framebuffer/intel/gen_dummies.h
@@ -0,0 +1,1682 @@
+bool access_ok(int access, void *addr, size_t size)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int acpi_video_register(void)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void acpi_video_unregister(void)
+{
+ TRACE_AND_STOP;
+}
+
+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;
+}
+
+int console_trylock(void)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void console_unlock(void)
+{
+ TRACE_AND_STOP;
+}
+
+size_t copy_from_user(void *to, void const *from, size_t len)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+size_t copy_to_user(void *dst, void const *src, size_t len)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void cpu_relax(void)
+{
+ TRACE_AND_STOP;
+}
+
+void destroy_timer_on_stack(struct timer_list *timer)
+{
+ TRACE_AND_STOP;
+}
+
+void destroy_workqueue(struct workqueue_struct *wq)
+{
+ TRACE_AND_STOP;
+}
+
+int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ 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;
+ return -1;
+}
+
+void drm_clflush_pages(struct page *pages[], unsigned long num_pages)
+{
+ TRACE_AND_STOP;
+}
+
+void drm_clflush_sg(struct sg_table *st)
+{
+ TRACE_AND_STOP;
+}
+
+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;
+ return -1;
+}
+
+int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, uint32_t handle)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void drm_gem_free_mmap_offset(struct drm_gem_object *obj)
+{
+ TRACE_AND_STOP;
+}
+
+int drm_gem_handle_create(struct drm_file *file_priv, struct drm_gem_object *obj, u32 *handlep)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj, size_t size)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, u32 handle)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+void drm_gem_object_reference(struct drm_gem_object *obj)
+{
+ TRACE_AND_STOP;
+}
+
+void drm_gem_object_release(struct drm_gem_object *obj)
+{
+ TRACE_AND_STOP;
+}
+
+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;
+ return -1;
+}
+
+int drm_gem_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv, uint32_t handle, uint32_t flags, int *prime_fd)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void drm_gem_vm_close(struct vm_area_struct *vma)
+{
+ TRACE_AND_STOP;
+}
+
+void drm_gem_vm_open(struct vm_area_struct *vma)
+{
+ TRACE_AND_STOP;
+}
+
+struct drm_local_map *drm_getsarea(struct drm_device *dev)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+bool drm_handle_vblank(struct drm_device *dev, int crtc)
+{
+ TRACE_AND_STOP;
+ 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;
+ return -1;
+}
+
+int drm_irq_uninstall(struct drm_device *dev)
+{
+ TRACE_AND_STOP;
+ 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;
+ return -1;
+}
+
+int drm_open(struct inode *inode, struct file *filp)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size, size_t align)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah)
+{
+ TRACE_AND_STOP;
+}
+
+unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg)
+{
+ TRACE_AND_STOP;
+}
+
+void drm_put_dev(struct drm_device *dev)
+{
+ TRACE_AND_STOP;
+}
+
+ssize_t drm_read(struct file *filp, char __user *buffer, size_t count, loff_t *offset)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int drm_release(struct inode *inode, struct file *filp)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void drm_send_vblank_event(struct drm_device *dev, int crtc, struct drm_pending_vblank_event *e)
+{
+ 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;
+}
+
+int drm_vblank_get(struct drm_device *dev, int crtc)
+{
+ TRACE_AND_STOP;
+ 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;
+}
+
+bool drm_vma_node_has_offset(struct drm_vma_offset_node *node)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+__u64 drm_vma_node_offset_addr(struct drm_vma_offset_node *node)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void drm_vma_node_unmap(struct drm_vma_offset_node *node, struct address_space *file_mapping)
+{
+ 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;
+ return -1;
+}
+
+int fault_in_multipages_writeable(char __user *uaddr, int size)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+struct inode *file_inode(struct file *f)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+void flush_scheduled_work(void)
+{
+ TRACE_AND_STOP;
+}
+
+void flush_workqueue(struct workqueue_struct *wq)
+{
+ TRACE_AND_STOP;
+}
+
+void __free_pages(struct page *page, unsigned int order)
+{
+ TRACE_AND_STOP;
+}
+
+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;
+ return -1;
+}
+
+void i915_capture_error_state(struct drm_device *dev)
+{
+ TRACE_AND_STOP;
+}
+
+void i915_destroy_error_state(struct drm_device *dev)
+{
+ TRACE_AND_STOP;
+}
+
+void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
+{
+ TRACE_AND_STOP;
+}
+
+int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void i915_gem_context_fini(struct drm_device *dev)
+{
+ TRACE_AND_STOP;
+}
+
+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;
+ return -1;
+}
+
+int __must_check i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm, int min_size, unsigned alignment, unsigned cache_level, bool mappable, bool nonblock)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj)
+{
+ TRACE_AND_STOP;
+}
+
+void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj)
+{
+ TRACE_AND_STOP;
+}
+
+struct dma_buf *i915_gem_prime_export(struct drm_device *dev, struct drm_gem_object *gem_obj, int flags)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone)
+{
+ TRACE_AND_STOP;
+}
+
+int i915_restore_state(struct drm_device *dev)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int i915_save_state(struct drm_device *dev)
+{
+ TRACE_AND_STOP;
+ 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;
+ return -1;
+}
+
+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;
+ return -1;
+}
+
+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;
+}
+
+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;
+ return -1;
+}
+
+void __intel_ring_advance(struct intel_ring_buffer *ring)
+{
+ TRACE_AND_STOP;
+}
+
+int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int __must_check intel_ring_cacheline_align(struct intel_ring_buffer *ring)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int intel_ring_flush_all_caches(struct intel_ring_buffer *ring)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+u32 intel_ring_get_active_head(struct intel_ring_buffer *ring)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int __must_check intel_ring_idle(struct intel_ring_buffer *ring)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno)
+{
+ TRACE_AND_STOP;
+}
+
+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;
+ return -1;
+}
+
+int intel_sprite_set_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ TRACE_AND_STOP;
+ 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;
+}
+
+void *io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+void io_mapping_unmap_atomic(void *vaddr)
+{
+ TRACE_AND_STOP;
+}
+
+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;
+ return -1;
+}
+
+void mapping_set_gfp_mask(struct address_space *m, gfp_t mask)
+{
+ TRACE_AND_STOP;
+}
+
+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;
+ return -1;
+}
+
+dma_addr_t page_to_pfn(struct page *page)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+resource_size_t pcibios_align_resource(void *, const struct resource *, resource_size_t, resource_size_t)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void pci_disable_device(struct pci_dev *dev)
+{
+ TRACE_AND_STOP;
+}
+
+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;
+ return -1;
+}
+
+struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+void *pci_get_drvdata(struct pci_dev *pdev)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+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;
+ return -1;
+}
+
+int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address, size_t size, int direction)
+{
+ TRACE_AND_STOP;
+}
+
+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;
+ return -1;
+}
+
+int release_resource(struct resource *r)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void remove_wait_queue(wait_queue_head_t *, wait_queue_t *)
+{
+ TRACE_AND_STOP;
+}
+
+int request_resource(struct resource *root, struct resource *)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+unsigned long round_jiffies_up(unsigned long j)
+{
+ TRACE_AND_STOP;
+ 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;
+}
+
+void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec)
+{
+ TRACE_AND_STOP;
+}
+
+int set_page_dirty(struct page *page)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int set_pages_wb(struct page *page, int numpages)
+{
+ TRACE_AND_STOP;
+ 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;
+}
+
+struct page *shmem_read_mapping_page( struct address_space *mapping, pgoff_t index)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, pgoff_t index, gfp_t gfp_mask)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
+{
+ TRACE_AND_STOP;
+}
+
+int signal_pending(struct task_struct *p)
+{
+ TRACE_AND_STOP;
+ 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;
+ return -1;
+}
+
+s64 timespec_to_ns(const struct timespec *ts)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+bool timespec_valid(const struct timespec *ts)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+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;
+ return -1;
+}
+
+void vga_switcheroo_unregister_client(struct pci_dev *dev)
+{
+ TRACE_AND_STOP;
+}
+
+phys_addr_t virt_to_phys(volatile void *address)
+{
+ TRACE_AND_STOP;
+ 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;
+ return -1;
+}
+
+unsigned long vm_mmap(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int wake_up_process(struct task_struct *tsk)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+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;
+ return -1;
+}
+
+int acpi_lid_open(void)
+{
+ TRACE_AND_STOP;
+ 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;
+ return NULL;
+}
+
+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)
+{
+ 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;
+ return -1;
+}
+
+int acpi_dev_pm_attach(struct device *dev, bool power_on)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+void acpi_dev_pm_detach(struct device *dev, bool power_off)
+{
+ TRACE_AND_STOP;
+}
+
+bool acpi_driver_match_device(struct device *dev, const struct device_driver *drv)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
+{
+ TRACE_AND_STOP;
+ 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;
+ return -1;
+}
+
+int device_for_each_child(struct device *dev, void *data, int (*fn)(struct device *dev, void *data))
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int device_init_wakeup(struct device *dev, bool val)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+const char *dev_name(const struct device *dev)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+void gpio_free(unsigned gpio)
+{
+ TRACE_AND_STOP;
+}
+
+int gpio_get_value(unsigned int gpio)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+bool gpio_is_valid(int number)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+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;
+}
+
+int of_alias_get_id(struct device_node *np, const char *stem)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+int of_driver_match_device(struct device *dev, const struct device_driver *drv)
+{
+ TRACE_AND_STOP;
+ 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;
+ return -1;
+}
+
+size_t strlcpy(char *dest, const char *src, size_t size)
+{
+ TRACE_AND_STOP;
+ return -1;
+}
+
+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;
+}
+
+
diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/gen_dummy b/repos/dde_linux/src/drivers/framebuffer/intel/gen_dummy
new file mode 100755
index 0000000000..6084c730b3
--- /dev/null
+++ b/repos/dde_linux/src/drivers/framebuffer/intel/gen_dummy
@@ -0,0 +1,99 @@
+#!/usr/bin/tclsh
+
+#
+# \brief Private utility to generate a dummy function from a symbol name
+# \date 2015-08-21
+# \author Norman Feske
+#
+# The script must be executed in its directory and takes a symbol name as last
+# argument. It searches the following places for a declaration that corresponds
+# to the specified symbol:
+#
+# - the local include/ directory
+# - the dde_linux/src/include/lx_emul/ directory
+# - the contrib/dde_linux-/src/drivers/framebuffer/intel directory
+#
+# If a declaration could be found, the script generates a dummy implementation
+# with the signature of the declarated function.
+#
+
+set symbol $argv
+
+# determine contrib directory of dde_linux
+set lx_drv_path [exec ../../../../../../tool/ports/current dde_linux]
+append lx_drv_path "/src/drivers/framebuffer/intel"
+
+# grep for lines that contain the symbol and have with no leading whitespace
+if {[catch {
+set header [exec grep -rl "^\\w.*$symbol\\>" include ../../../include/lx_emul $lx_drv_path | grep -v "~"]
+}]} {
+ puts stderr "failed to lookup symbol $symbol"
+ exit 1
+}
+
+if {[llength $header] != 1} {
+ puts stderr "cannot generate dummy for symbol $symbol"
+ exit 1
+}
+
+puts stderr "found declaration of $symbol in $header"
+
+set statements [split [exec cat $header] ";{}"]
+
+foreach statement $statements {
+
+ # strip off comments and preprocessor commands
+ regsub -all {/\*.*?\*/} $statement "" statement
+ regsub -all {//.*?\n} $statement "" statement
+ regsub -all {#.*?\n} $statement "\n" statement
+
+ # delete consecutive newlines
+ while {[regexp {\n\n} $statement dummy]} {
+ regsub -all {\n\n} $statement "\n" statement
+ }
+
+ # function declarations have no leading tabs
+ if {[regexp {^\t} $statement dummy]} continue
+
+ # skip statements where the symbol does not occur
+ if {![regexp "$symbol\\(" $statement dummy]} continue
+
+ # strip leading whitespace (linefeed)
+ regsub {^\s*} $statement "" statement
+
+ # strip leading extern keyword
+ regsub {^extern\s*} $statement "" statement
+
+ # strip leading inline keyword
+ regsub {^inline\s*} $statement "" statement
+
+ # merge multi-line parameter list into a single line
+ regsub -all {\s*\n\s*} $statement " " statement
+
+ # strip function attributes starting with '__'
+ regsub -all {\)\s*__.*} $statement ")" statement
+
+ # determine return type 'ret' of the function
+ regexp {^[^\(]*} $statement func_ret
+ regsub {\s[^\s\*]*$} $func_ret "" ret
+
+ # output function definition
+ puts "$statement"
+ puts "{"
+ puts "\tTRACE_AND_STOP;"
+ if {[regexp {\*} $ret]} {
+ # function returns a pointer
+ puts "\treturn NULL;"
+ } elseif {[regexp {void} $ret dummy]} {
+ # void function
+ } else {
+ # function with return value
+ puts "\treturn -1;"
+ }
+ puts "}\n"
+
+ # success
+ exit 0
+}
+
+puts stderr "failed to match declaration of $symbol in $header"
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
new file mode 100644
index 0000000000..58e373e00a
--- /dev/null
+++ b/repos/dde_linux/src/drivers/framebuffer/intel/i2c-algo-bit.c
@@ -0,0 +1,31 @@
+/*
+ * \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/drm/drmP.h b/repos/dde_linux/src/drivers/framebuffer/intel/include/drm/drmP.h
new file mode 100644
index 0000000000..79086b835d
--- /dev/null
+++ b/repos/dde_linux/src/drivers/framebuffer/intel/include/drm/drmP.h
@@ -0,0 +1,684 @@
+/*
+ * \brief Platform interface of DRM code
+ * \author Norman Feske
+ * \date 2015-08-19
+ */
+
+#ifndef _DRMP_H_
+#define _DRMP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* local includes */
+#include
+
+/*
+ * Unfortunately, DRM headers use certain C++ keywords as variable names.
+ * To enable the inclusion of 'drmP.h' from C++ source codes, we have to
+ * rename these identifiers.
+ */
+#ifdef __cplusplus
+#define new _new
+#define virtual _virtual
+#define private _private
+#endif /* __cplusplus */
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#ifdef __cplusplus
+#undef virtual
+#undef new
+#undef private
+#endif /* __cplusplus */
+
+extern unsigned int drm_debug;
+
+
+/*******************
+ ** DRM constants **
+ *******************/
+
+enum {
+ DRM_MINOR_CONTROL = 2,
+// DRM_MINOR_RENDER = 3,
+// DRM_MAGIC_HASH_ORDER = 4,
+};
+
+enum {
+ DRM_AUTH = 0x1,
+ DRM_MASTER = 0x2,
+ DRM_ROOT_ONLY = 0x4,
+ DRM_CONTROL_ALLOW = 0x8,
+ DRM_UNLOCKED = 0x10,
+ DRM_RENDER_ALLOW = 0x20,
+};
+
+enum {
+ DRIVER_USE_AGP = 0x1,
+ DRIVER_REQUIRE_AGP = 0x2,
+ DRIVER_HAVE_IRQ = 0x40,
+ DRIVER_IRQ_SHARED = 0x80,
+ DRIVER_GEM = 0x1000,
+ DRIVER_MODESET = 0x2000,
+ DRIVER_PRIME = 0x4000,
+ DRIVER_RENDER = 0x8000,
+};
+
+//enum { DRM_HZ = HZ };
+
+enum {
+ DRM_SCANOUTPOS_VALID = (1 << 0),
+ DRM_SCANOUTPOS_INVBL = (1 << 1),
+ DRM_SCANOUTPOS_ACCURATE = (1 << 2),
+};
+
+enum { DRM_CALLED_FROM_VBLIRQ = 1 };
+
+//enum {
+// DRM_CONNECTOR_POLL_HPD = 1 << 0,
+// DRM_CONNECTOR_POLL_CONNECT = 1 << 1,
+// DRM_CONNECTOR_POLL_DISCONNECT = 1 << 2,
+//};
+
+
+/****************
+ ** DRM macros **
+ ****************/
+
+#define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
+
+///*
+// * Type and function mappings
+// */
+//#define DRM_IRQ_ARGS void *arg
+//#define DRM_ARRAY_SIZE ARRAY_SIZE
+//#define DRM_WAKEUP wake_up
+//#define DRM_INIT_WAITQUEUE init_waitqueue_head
+//#define DRM_AGP_KERN struct agp_kern_info
+//#define DRM_AGP_MEM struct agp_memory
+//#define DRM_COPY_TO_USER copy_to_user
+//
+///*
+// * Debug macros
+// */
+#define DRM_VERBOSE 1
+
+#if DRM_VERBOSE
+#define DRM_INFO(fmt, arg...) do { \
+ lx_printfln("[" DRM_NAME ":%s] *INFO* " fmt , __func__ , ##arg); } while (0)
+
+#define DRM_ERROR(fmt, arg...) do { \
+ lx_printfln("[" DRM_NAME ":%s] *ERROR* " fmt , __func__ , ##arg); } while (0)
+
+#define DRM_DEBUG(fmt, arg...) do { \
+ lx_printfln("[" DRM_NAME ":%s] *DEBUG* " fmt , __func__ , ##arg); } while (0)
+
+#define DRM_DEBUG_DRIVER(fmt, arg...) do { \
+ lx_printfln("[" DRM_NAME ":%s] *DRIVER* " fmt , __func__ , ##arg); } while (0)
+
+#define DRM_DEBUG_KMS(fmt, arg...) do { \
+ lx_printfln("[" DRM_NAME ":%s] *KMS* " fmt , __func__ , ##arg); } while (0)
+#else
+#define DRM_INFO(fmt, arg...) do { } while (0)
+#define DRM_ERROR(fmt, arg...) do { } while (0)
+#define DRM_DEBUG(fmt, arg...) do { } while (0)
+#define DRM_DEBUG_DRIVER(fmt, arg...) do { } while (0)
+#define DRM_DEBUG_KMS(fmt, arg...) do { } while (0)
+#endif
+
+#define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x)
+
+#define DRM_UT_KMS 0x04
+
+
+///***************
+// ** DRM types **
+// ***************/
+//
+///*
+// * Forward type declarations
+// */
+struct drm_device;
+struct drm_mm_node;
+struct drm_master;
+struct drm_file;
+struct drm_crtc;
+struct drm_plane;
+struct drm_display_mode;
+struct drm_connector;
+struct drm_mode_create_dumb;
+struct drm_mode_fb_cmd2;
+
+
+/**
+ * Ioctl handler function
+ */
+typedef int drm_ioctl_t(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+/**
+ * Ioctl representation
+ */
+struct drm_ioctl_desc {
+ unsigned int cmd;
+ int flags;
+ drm_ioctl_t *func;
+ unsigned int cmd_drv;
+ const char *name;
+};
+
+#define DRM_IOCTL_NR(n) (n & 0xff)
+
+#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
+ [DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl, .name = #ioctl}
+
+#if 0
+#define DRM_IOCTL_DEF(ioctl, _func, _flags) \
+ [ioctl & 0xff] = {.cmd = ioctl, .func = _func, .flags = _flags}
+#endif
+
+
+struct drm_gem_object;
+
+
+struct drm_driver {
+ u32 driver_features;
+ const struct vm_operations_struct *gem_vm_ops;
+ const struct drm_ioctl_desc *ioctls;
+ int num_ioctls;
+ const struct file_operations *fops;
+ int major;
+ int minor;
+ int patchlevel;
+ char *name;
+ char *desc;
+ char *date;
+
+ int (*load) (struct drm_device *, unsigned long flags);
+ int (*unload) (struct drm_device *);
+ int (*open) (struct drm_device *, struct drm_file *);
+ void (*lastclose) (struct drm_device *);
+ void (*preclose) (struct drm_device *, struct drm_file *file_priv);
+ void (*postclose) (struct drm_device *, struct drm_file *);
+
+ int (*suspend) (struct drm_device *, pm_message_t state);
+ int (*resume) (struct drm_device *);
+
+ int (*device_is_agp) (struct drm_device *dev);
+ int (*master_create)(struct drm_device *dev, struct drm_master *master);
+ void (*master_destroy)(struct drm_device *dev, struct drm_master *master);
+ void (*gem_free_object) (struct drm_gem_object *obj);
+
+ int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv,
+ uint32_t handle, uint32_t flags, int *prime_fd);
+ int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv,
+ int prime_fd, uint32_t *handle);
+ struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
+ struct drm_gem_object *obj, int flags);
+ struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
+ struct dma_buf *dma_buf);
+
+ int (*dumb_create)(struct drm_file *file_priv,
+ struct drm_device *dev,
+ struct drm_mode_create_dumb *args);
+ int (*dumb_map_offset)(struct drm_file *file_priv,
+ struct drm_device *dev, uint32_t handle,
+ uint64_t *offset);
+ int (*dumb_destroy)(struct drm_file *file_priv,
+ struct drm_device *dev,
+ uint32_t handle);
+ int (*get_vblank_timestamp) (struct drm_device *dev, int crtc,
+ int *max_error,
+ struct timeval *vblank_time,
+ unsigned flags);
+ u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);
+ int (*get_scanout_position) (struct drm_device *dev, int crtc,
+ unsigned int flags,
+ int *vpos, int *hpos, ktime_t *stime,
+ ktime_t *etime);
+ irqreturn_t(*irq_handler) (int irq, void *arg);
+ void (*irq_preinstall) (struct drm_device *dev);
+ int (*irq_postinstall) (struct drm_device *dev);
+ void (*irq_uninstall) (struct drm_device *dev);
+ int (*enable_vblank) (struct drm_device *dev, int crtc);
+ void (*disable_vblank) (struct drm_device *dev, int crtc);
+};
+
+
+///* needed by drm_agpsupport.c */
+//struct drm_agp_mem {
+// unsigned long handle;
+// DRM_AGP_MEM *memory;
+// unsigned long bound;
+// int pages;
+// struct list_head head;
+//};
+//
+//struct drm_agp_head {
+// DRM_AGP_KERN agp_info;
+// unsigned long base;
+//
+// /*
+// * Members used by drm_agpsupport.c
+// */
+// int acquired;
+// struct agp_bridge_data *bridge;
+// int enabled;
+// unsigned long mode;
+// struct list_head memory;
+// int cant_use_aperture;
+// unsigned long page_mask;
+//};
+
+#define DRM_SWITCH_POWER_ON 0
+#define DRM_SWITCH_POWER_OFF 1
+#define DRM_SWITCH_POWER_CHANGING 2
+
+struct drm_i915_private;
+
+struct drm_device {
+// int pci_device;
+ struct pci_dev *pdev;
+ struct mutex struct_mutex;
+ struct drm_driver *driver;
+ struct drm_i915_private *dev_private;
+// struct drm_gem_mm *mm_private;
+// enum drm_stat_type types[15];
+// unsigned long counters;
+ struct address_space *dev_mapping;
+ struct drm_agp_head *agp;
+ int irq_enabled; /* needed for i915_dma.c */
+ spinlock_t count_lock;
+ struct drm_mode_config mode_config;
+ int open_count;
+ int vblank_disable_allowed;
+ u32 max_vblank_count;
+ struct drm_minor *primary; /* needed by i915_dma.c */
+// atomic_t object_count;
+// atomic_t object_memory;
+// atomic_t pin_count;
+// atomic_t pin_memory;
+// atomic_t gtt_count;
+// atomic_t gtt_memory;
+// uint32_t gtt_total;
+// uint32_t invalidate_domains;
+// uint32_t flush_domains;
+ int switch_power_state;
+ spinlock_t event_lock;
+ struct device *dev; /* i915_gem_stolen.c */
+};
+
+//
+//struct drm_map_list {
+// struct drm_hash_item hash;
+// struct drm_local_map *map;
+// struct drm_mm_node *file_offset_node;
+//};
+
+
+/***************************
+ ** drm/drm_vma_manager.h **
+ ***************************/
+
+struct drm_vma_offset_node {
+ int dummy;
+};
+
+
+struct drm_gem_object {
+
+// /** Related drm device */
+ struct drm_device *dev;
+//
+// /** File representing the shmem storage */
+ struct file *filp;
+//
+// /**
+// * Size of the object, in bytes. Immutable over the object's
+// * lifetime.
+// */
+ size_t size;
+//
+// /**
+// * Global name for this object, starts at 1. 0 means unnamed.
+// * Access is covered by the object_name_lock in the related drm_device
+// */
+// int name;
+//
+// /* Mapping info for this object */
+// struct drm_map_list map_list;
+//
+// /**
+// * Memory domains. These monitor which caches contain read/write data
+// * related to the object. When transitioning from one set of domains
+// * to another, the driver is called to ensure that caches are suitably
+// * flushed and invalidated
+// */
+ uint32_t read_domains;
+ uint32_t write_domain;
+//
+// /**
+// * While validating an exec operation, the
+// * new read/write domain values are computed here.
+// * They will be transferred to the above values
+// * at the point that any cache flushing occurs
+// */
+// uint32_t pending_read_domains;
+// uint32_t pending_write_domain;
+//
+// void *driver_private;
+ struct drm_vma_offset_node vma_node;
+ struct dma_buf_attachment *import_attach;
+};
+
+typedef struct drm_dma_handle {
+ void *vaddr;
+ size_t size;
+ dma_addr_t busaddr; /* needed by i915_drv.h */
+} drm_dma_handle_t;
+
+typedef struct drm_local_map {
+ size_t offset; /* Requested physical address (0 for SAREA)*/
+ unsigned long size; /* Requested physical size (bytes) */
+// enum drm_map_type type; /* Type of memory to map */
+// enum drm_map_flags flags; /* Flags */
+ void *handle; /* User-space: "Handle" to pass to mmap() */
+ /* Kernel-space: kernel-virtual address */
+ int mtrr; /* MTRR slot used */
+} drm_local_map_t;
+
+//struct drm_gem_mm {
+// struct drm_mm offset_manager;
+// struct drm_open_hash offset_hash;
+//};
+//
+struct drm_lock_data {
+ struct drm_hw_lock *hw_lock; /* for i915_dma.c */
+ struct drm_file *file_priv; /* for i915_dma.c */
+};
+//
+struct drm_master {
+ struct drm_lock_data lock; /* needed for i915_dma.c */
+ void *driver_priv; /* needed for i915_dma.c */
+ struct drm_minor *minor;
+};
+
+struct drm_file {
+ void *driver_priv;
+ struct drm_minor *minor; /* needed for drm_agpsupport.c */
+ struct drm_master *master; /* needed for i915_dma.c */
+ struct list_head fbs;
+ struct mutex fbs_lock;
+ unsigned stereo_allowed :1;
+ unsigned is_master :1; /* this file private is a master for a minor */
+ int event_space;
+};
+//
+///*
+// * needed for drm_agpsupport.c
+// */
+struct drm_minor {
+ struct device *kdev; /* needed by i915_irq.c */
+ struct drm_device *dev;
+ struct drm_master *master; /* needed for i915_dma.c */
+ int index; /**< Minor device number */
+ struct drm_mode_group mode_group;
+ int type; /**< Control or render */
+};
+//
+///*
+// * needed for drm_crtc_helper.h, included by i915_dma.c
+// */
+//struct drm_encoder { void *helper_private; };
+//struct drm_mode_set { };
+
+
+#define DRM_MODE_OBJECT_CRTC 0xcccccccc
+//#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
+//#define DRM_MODE_OBJECT_ENCODER 0xe0e0e0e0
+#define DRM_MODE_OBJECT_MODE 0xdededede
+//#define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
+//#define DRM_MODE_OBJECT_FB 0xfbfbfbfb
+//#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
+//#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
+//#define DRM_MODE_OBJECT_BRIDGE 0xbdbdbdbd
+
+#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \
+ .name = nm, .status = 0, .type = (t), .clock = (c), \
+ .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \
+ .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \
+ .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \
+ .vscan = (vs), .flags = (f), \
+ .base.type = DRM_MODE_OBJECT_MODE
+
+#define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */
+
+
+struct drm_pending_vblank_event;
+
+
+struct drm_fb_helper { int dummy; };
+
+
+#include
+
+
+/***************************
+ ** drm/drm_crtc_helper.h **
+ ***************************/
+
+struct drm_pending_event {
+ struct drm_event *event;
+// struct list_head link;
+ struct drm_file *file_priv;
+// pid_t pid; /* pid of requester, no guarantee it's valid by the time
+// we deliver the event, for tracing only */
+ void (*destroy)(struct drm_pending_event *event);
+};
+
+struct drm_pending_vblank_event {
+ int dummy;
+ struct drm_pending_event base;
+// int pipe;
+ struct drm_event_vblank event;
+};
+
+
+/******************
+ ** Misc helpers **
+ ******************/
+
+/* normally found in drm_os_linux.h */
+#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
+do { \
+ DECLARE_WAITQUEUE(entry, current); \
+ unsigned long end = jiffies + (timeout); \
+ add_wait_queue(&(queue), &entry); \
+ \
+ for (;;) { \
+ __set_current_state(TASK_INTERRUPTIBLE); \
+ if (condition) \
+ break; \
+ if (time_after_eq(jiffies, end)) { \
+ ret = -EBUSY; \
+ break; \
+ } \
+ schedule_timeout((HZ/100 > 1) ? HZ/100 : 1); \
+ if (signal_pending(current)) { \
+ ret = -EINTR; \
+ break; \
+ } \
+ } \
+ __set_current_state(TASK_RUNNING); \
+ remove_wait_queue(&(queue), &entry); \
+} while (0)
+
+
+/* normally found in Linux drmP.h */
+#define LOCK_TEST_WITH_RETURN( dev, _file_priv ) \
+do { \
+ if (!_DRM_LOCK_IS_HELD(_file_priv->master->lock.hw_lock->lock) || \
+ _file_priv->master->lock.file_priv != _file_priv) { \
+ DRM_ERROR( "%s called without lock held, held %d owner %p %p\n",\
+ __func__, _DRM_LOCK_IS_HELD(_file_priv->master->lock.hw_lock->lock),\
+ _file_priv->master->lock.file_priv, _file_priv); \
+ return -EINVAL; \
+ } \
+} while (0)
+
+
+static inline int drm_core_check_feature(struct drm_device *dev, int feature) {
+ return ((dev->driver->driver_features & feature) ? 1 : 0); }
+
+#if 0
+
+static inline int drm_core_has_AGP(struct drm_device *dev) {
+ return drm_core_check_feature(dev, DRIVER_USE_AGP); }
+
+/*
+ * Functions normally provided by drm_bufs.c
+ */
+static inline resource_size_t
+drm_get_resource_start(struct drm_device *dev, unsigned int rsc) {
+ return pci_resource_start(dev->pdev, rsc); }
+
+static inline resource_size_t
+drm_get_resource_len(struct drm_device *dev, unsigned int rsc) {
+ return pci_resource_len(dev->pdev, rsc); }
+
+#endif
+
+static __inline__ bool drm_can_sleep(void) { return true; }
+
+extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah);
+extern int drm_noop(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_irq_install(struct drm_device *dev);
+extern int drm_irq_uninstall(struct drm_device *dev);
+extern struct drm_local_map *drm_getsarea(struct drm_device *dev);
+extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
+extern void drm_vblank_cleanup(struct drm_device *dev);
+extern void drm_kms_helper_poll_disable(struct drm_device *dev);
+extern void drm_kms_helper_poll_init(struct drm_device *dev);
+extern void drm_mm_takedown(struct drm_mm *mm);
+extern bool drm_helper_hpd_irq_event(struct drm_device *dev);
+extern void drm_modeset_lock_all(struct drm_device *dev);
+extern void drm_mode_config_reset(struct drm_device *dev);
+extern void drm_modeset_unlock_all(struct drm_device *dev);
+extern void drm_kms_helper_poll_enable(struct drm_device *dev);
+extern int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver);
+extern void drm_put_dev(struct drm_device *dev);
+extern void drm_gem_vm_open(struct vm_area_struct *vma);
+extern void drm_gem_vm_close(struct vm_area_struct *vma);
+extern int drm_open(struct inode *inode, struct file *filp);
+extern int drm_release(struct inode *inode, struct file *filp);
+extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
+extern long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
+extern ssize_t drm_read(struct file *filp, char __user *buffer, size_t count, loff_t *offset);
+extern int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
+extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv, uint32_t handle, uint32_t flags, int *prime_fd);
+extern int drm_gem_prime_fd_to_handle(struct drm_device *dev, struct drm_file *file_priv, int prime_fd, uint32_t *handle);
+extern int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, uint32_t handle);
+extern int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver);
+extern void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver);
+extern void drm_vblank_off(struct drm_device *dev, int crtc);
+extern void drm_encoder_cleanup(struct drm_encoder *encoder);
+extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
+extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc);
+extern struct drm_connector *drm_select_eld(struct drm_encoder *encoder, struct drm_display_mode *mode);
+extern int drm_av_sync_delay(struct drm_connector *connector, struct drm_display_mode *mode);
+extern struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, u32 handle);
+extern void drm_gem_object_unreference(struct drm_gem_object *obj);
+extern void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj);
+extern uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
+extern void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
+extern void drm_framebuffer_unreference(struct drm_framebuffer *fb);
+extern void drm_mode_set_name(struct drm_display_mode *mode);
+extern void drm_crtc_cleanup(struct drm_crtc *crtc);
+extern void drm_send_vblank_event(struct drm_device *dev, int crtc, struct drm_pending_vblank_event *e);
+extern void drm_vblank_put(struct drm_device *dev, int crtc);
+extern int drm_vblank_get(struct drm_device *dev, int crtc);
+extern void drm_gem_object_reference(struct drm_gem_object *obj);
+extern void drm_mode_debug_printmodeline(const struct drm_display_mode *mode);
+extern void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src);
+extern void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags);
+extern int drm_object_property_set_value(struct drm_mode_object *obj, struct drm_property *property, uint64_t val);
+extern void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode);
+extern bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2);
+extern bool drm_encoder_crtc_ok(struct drm_encoder *encoder, struct drm_crtc *crtc);
+extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size);
+extern void drm_crtc_helper_add(struct drm_crtc *crtc, const struct drm_crtc_helper_funcs *funcs);
+extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type);
+extern void drm_helper_move_panel_connectors_to_head(struct drm_device *);
+extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
+extern int drm_gem_handle_create(struct drm_file *file_priv, struct drm_gem_object *obj, u32 *handlep);
+extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, struct drm_mode_fb_cmd2 *mode_cmd);
+extern int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, const struct drm_framebuffer_funcs *funcs);
+extern void drm_mode_config_init(struct drm_device *dev);
+extern void drm_kms_helper_poll_fini(struct drm_device *dev);
+extern void drm_sysfs_connector_remove(struct drm_connector *connector);
+extern void drm_mode_config_cleanup(struct drm_device *dev);
+extern int drm_mode_connector_attach_encoder(struct drm_connector *connector, struct drm_encoder *encoder);
+extern bool drm_dp_enhanced_frame_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
+extern int drm_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, const struct drm_encoder_funcs *funcs, int encoder_type);
+extern int drm_dp_bw_code_to_link_rate(u8 link_bw);
+extern u8 drm_dp_max_lane_count(const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
+extern u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
+extern bool drm_probe_ddc(struct i2c_adapter *adapter);
+extern struct edid *drm_edid_duplicate(const struct edid *edid);
+extern struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter);
+extern bool drm_detect_monitor_audio(struct edid *edid);
+extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, const struct drm_display_mode *mode);
+extern void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
+extern void drm_connector_cleanup(struct drm_connector *connector);
+extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
+extern int drm_mode_create_scaling_mode_property(struct drm_device *dev);
+extern void drm_object_attach_property(struct drm_mode_object *obj, struct drm_property *property, uint64_t init_val);
+extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
+extern int drm_mode_connector_update_edid_property(struct drm_connector *connector, struct edid *edid);
+extern void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid);
+extern int drm_connector_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type);
+extern int drm_sysfs_connector_add(struct drm_connector *connector);
+extern void drm_clflush_virt_range(char *addr, unsigned long length);
+extern void drm_vma_node_unmap(struct drm_vma_offset_node *node, struct address_space *file_mapping);
+extern bool drm_vma_node_has_offset(struct drm_vma_offset_node *node);
+extern int drm_gem_create_mmap_offset(struct drm_gem_object *obj);
+extern void drm_gem_free_mmap_offset(struct drm_gem_object *obj);
+extern __u64 drm_vma_node_offset_addr(struct drm_vma_offset_node *node);
+extern bool drm_mm_node_allocated(struct drm_mm_node *node);
+extern void drm_mm_remove_node(struct drm_mm_node *node);
+extern void drm_clflush_sg(struct sg_table *st);
+extern int drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj, size_t size);
+extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg);
+extern void drm_gem_object_release(struct drm_gem_object *obj);
+extern drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size, size_t align);
+extern void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
+extern void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
+extern const char *drm_get_connector_name(const struct drm_connector *connector);
+extern const char *drm_get_encoder_name(const struct drm_encoder *encoder);
+extern const char *drm_get_format_name(uint32_t format);
+extern void drm_mm_init(struct drm_mm *mm, unsigned long start, unsigned long size);
+extern int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node);
+extern 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);
+extern const char *drm_get_connector_status_name(enum drm_connector_status status);
+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);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* extern "C" */
+
+#endif /* _DRMP_H_ */
diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/include/i915_trace.h b/repos/dde_linux/src/drivers/framebuffer/intel/include/i915_trace.h
new file mode 100644
index 0000000000..8e1a48a237
--- /dev/null
+++ b/repos/dde_linux/src/drivers/framebuffer/intel/include/i915_trace.h
@@ -0,0 +1 @@
+#include
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
new file mode 100644
index 0000000000..7c6e8b79ff
--- /dev/null
+++ b/repos/dde_linux/src/drivers/framebuffer/intel/include/lx_emul.h
@@ -0,0 +1,1491 @@
+/*
+ * \brief Emulation of the Linux kernel API used by DRM
+ * \author Norman Feske
+ * \date 2015-08-19
+ *
+ * The content of this file, in particular data structures, is partially
+ * derived from Linux-internal headers.
+ */
+
+#ifndef _LX_EMUL_H_
+#define _LX_EMUL_H_
+
+#include
+#include
+
+#include
+
+
+/*****************
+ ** asm/param.h **
+ *****************/
+
+enum { HZ = 100UL };
+
+
+#include
+#include
+#include
+#include
+
+#define smp_mb__before_atomic_inc() barrier()
+
+void atomic_set_mask(unsigned int mask, atomic_t *v);
+
+#include
+#include
+
+typedef unsigned long kernel_ulong_t;
+
+
+/************************
+ ** uapi/linux/types.h **
+ ************************/
+
+typedef __u16 __le16;
+typedef __u16 __be16;
+typedef __u32 __le32;
+typedef __u32 __be32;
+typedef __u64 __le64;
+typedef __u64 __be64;
+
+
+/********************
+ ** linux/printk.h **
+ ********************/
+
+/* needed by drm_edid.c */
+enum { DUMP_PREFIX_NONE, };
+
+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);
+
+
+/*********************
+ ** uapi/linux/fb.h **
+ *********************/
+
+#define KHZ2PICOS(a) (1000000000UL/(a))
+
+
+
+/*******************
+ ** linux/ctype.h **
+ *******************/
+
+#define isascii(c) (((unsigned char)(c))<=0x7f)
+#define isprint(c) (isascii(c) && ((unsigned char)(c) >= 32))
+
+
+
+/****************
+ ** asm/page.h **
+ ****************/
+
+/*
+ * For now, hardcoded
+ */
+#define PAGE_SIZE 4096UL
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+dma_addr_t page_to_phys(void *page);
+
+enum {
+ PAGE_SHIFT = 12,
+};
+
+struct page
+{
+// unsigned long flags;
+// int pfmemalloc;
+// int mapping;
+ atomic_t _count;
+ void *addr;
+ unsigned long private;
+} __attribute((packed));
+
+/* needed for agp/generic.c */
+struct page *virt_to_page(void *addr);
+
+
+#include
+
+unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size);
+
+#include
+
+
+#include
+
+/* needed by 'virt_to_phys', which is needed by agp/generic.c */
+typedef unsigned long phys_addr_t;
+
+#include
+
+void *memchr_inv(const void *s, int c, size_t n);
+
+#include
+#include
+
+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_info_once(fmt, ...) printk(KERN_INFO fmt, ##__VA_ARGS__)
+
+int sprintf(char *buf, const char *fmt, ...);
+int snprintf(char *buf, size_t size, const char *fmt, ...);
+
+int sscanf(const char *, const char *, ...);
+
+enum { SPRINTF_STR_LEN = 64 };
+
+#define kasprintf(gfp, fmt, ...) ({ \
+ void *buf = kmalloc(SPRINTF_STR_LEN, 0); \
+ sprintf(buf, fmt, __VA_ARGS__); \
+ buf; \
+})
+
+/* linux/i2c.h */
+#define __deprecated
+
+
+/************************
+ ** linux/page-flags.h **
+ ************************/
+
+//void SetPageDirty(struct page *page);
+
+/* needed by agp/generic.c */
+void SetPageReserved(struct page *page);
+void ClearPageReserved(struct page *page);
+
+
+/********************
+ ** linux/printk.h **
+ ********************/
+
+extern void hex_dump_to_buffer(const void *buf, size_t len,
+ int rowsize, int groupsize,
+ char *linebuf, size_t linebuflen, bool ascii);
+
+
+#include
+
+#define MODULE_ALIAS_MISCDEV(x) /* needed by agp/backend.c */
+
+/* i2c-core.c */
+#define postcore_initcall(fn) void postcore_##fn(void) { fn(); }
+
+
+/**************************
+ ** linux/preempt_mask.h **
+ **************************/
+
+/* needed bu i2c-core.c */
+bool in_atomic();
+
+
+/**********************
+ ** linux/irqflags.h **
+ **********************/
+
+/* needed bu i2c-core.c */
+bool irqs_disabled();
+
+
+/*********************
+ ** linux/jiffies.h **
+ *********************/
+
+#include
+
+#define time_before(a,b) time_after(b,a)
+#define time_before_eq(a,b) time_after_eq(b,a)
+
+#define time_in_range(a,b,c) \
+ (time_after_eq(a,b) && \
+ time_before_eq(a,c))
+
+
+
+#include
+#include
+#include
+
+
+static inline int mutex_lock_interruptible(struct mutex *lock) {
+ mutex_lock(lock);
+ return 0;
+}
+
+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)
+
+
+/******************
+ ** linux/time.h **
+ ******************/
+
+#include
+
+void getrawmonotonic(struct timespec *ts);
+
+struct timespec timespec_sub(struct timespec lhs, struct timespec rhs);
+bool timespec_valid(const struct timespec *ts);
+void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
+unsigned long get_seconds(void);
+struct timespec ns_to_timespec(const s64 nsec);
+s64 timespec_to_ns(const struct timespec *ts);
+
+
+/*******************
+ ** linux/timer.h **
+ *******************/
+
+#include
+
+#define del_singleshot_timer_sync(t) del_timer_sync(t)
+
+
+#include
+
+extern bool flush_delayed_work(struct delayed_work *dwork);
+
+extern unsigned long timespec_to_jiffies(const struct timespec *value);
+
+#define wait_event_interruptible_timeout wait_event_timeout
+
+#define setup_timer_on_stack setup_timer
+
+void destroy_timer_on_stack(struct timer_list *timer);
+
+unsigned long round_jiffies_up_relative(unsigned long j);
+
+
+/*******************
+ ** linux/sched.h **
+ *******************/
+
+enum { TASK_RUNNING, TASK_INTERRUPTIBLE, TASK_UNINTERRUPTIBLE };
+
+struct mm_struct;
+struct task_struct {
+ struct mm_struct *mm;
+ char comm[16]; /* needed by agp/generic.c, only for debug output */
+};
+
+signed long schedule_timeout(signed long timeout);
+void __set_current_state(int state);
+int signal_pending(struct task_struct *p);
+void schedule(void);
+int wake_up_process(struct task_struct *tsk);
+void io_schedule(void);
+
+/* normally declared in linux/smp.h, included by sched.h */
+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;
+
+
+/************************
+ ** linux/completion.h **
+ ************************/
+
+struct completion { unsigned done; };
+
+void __wait_completion(struct completion *work);
+void complete(struct completion *); /* i2c-core.c */
+void init_completion(struct completion *x);
+
+
+/*********************
+ ** linux/raid/pq.h **
+ *********************/
+
+void cpu_relax(void); /* i915_dma.c */
+
+
+/*******************
+ ** linux/delay.h **
+ *******************/
+
+void msleep(unsigned int);
+void udelay(unsigned long);
+void mdelay(unsigned long);
+void ndelay(unsigned long);
+
+void usleep_range(unsigned long min, unsigned long max); /* intel_dp.c */
+
+
+/*****************
+ ** linux/idr.h **
+ *****************/
+
+/* needed by intel_drv.h */
+struct idr { int dummy; };
+
+void idr_init(struct idr *idp); /* i915_gem.c */
+int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask);
+void idr_remove(struct idr *idp, int id);
+void *idr_find(struct idr *idr, int id);
+void idr_destroy(struct idr *idp);
+
+
+struct ida { int dummy; };
+
+void ida_destroy(struct ida *ida);
+void ida_init(struct ida *ida);
+int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, gfp_t gfp_mask);
+void ida_remove(struct ida *ida, int id);
+
+#define IDR_INIT(name) { .dummy = 0, }
+#define DEFINE_IDR(name) struct idr name = IDR_INIT(name)
+
+
+/*************************
+ ** linux/scatterlist.h **
+ *************************/
+
+#include
+
+struct page *sg_page_iter_page(struct sg_page_iter *piter);
+
+void sg_free_table(struct sg_table *);
+int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
+
+void sg_mark_end(struct scatterlist *sg);
+
+dma_addr_t sg_page_iter_dma_address(struct sg_page_iter *piter);
+
+
+
+#include
+
+enum kobject_action {
+// KOBJ_ADD,
+// KOBJ_REMOVE,
+ KOBJ_CHANGE,
+// KOBJ_MOVE,
+// KOBJ_ONLINE,
+// KOBJ_OFFLINE,
+// KOBJ_MAX
+};
+
+int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, char *envp[]);
+
+
+/************************
+ ** asm/memory_model.h **
+ ************************/
+
+dma_addr_t page_to_pfn(struct page *page);
+
+
+/*********************
+ ** linux/pagemap.h **
+ *********************/
+
+int fault_in_multipages_writeable(char __user *uaddr, int size);
+int fault_in_multipages_readable(const char __user *uaddr, int size);
+
+#define page_cache_release(page) put_page(page)
+
+struct address_space;
+
+gfp_t mapping_gfp_mask(struct address_space * mapping);
+void mapping_set_gfp_mask(struct address_space *m, gfp_t mask);
+
+
+/******************
+ ** linux/swap.h **
+ ******************/
+
+void mark_page_accessed(struct page *);
+
+
+/**********************
+ ** linux/mm_types.h **
+ **********************/
+
+struct vm_area_struct {
+ unsigned long vm_start;
+ void *vm_private_data;
+};
+
+struct mm_struct { struct rw_semaphore mmap_sem; };
+
+
+/**********************
+ ** linux/shrinker.h **
+ **********************/
+
+struct shrink_control {
+ unsigned long nr_to_scan;
+};
+
+struct shrinker {
+ int (*shrink)(int nr_to_scan, gfp_t gfp_mask);
+ unsigned long (*scan_objects)(struct shrinker *, struct shrink_control *sc);
+ unsigned long (*count_objects)(struct shrinker *, struct shrink_control *sc); /* i915_gem.c */
+ int seeks;
+};
+
+int register_shrinker(struct shrinker *);
+void unregister_shrinker(struct shrinker *);
+
+#define SHRINK_STOP (~0UL)
+
+
+/****************
+ ** linux/mm.h **
+ ****************/
+
+//extern unsigned long totalram_pages;
+//
+enum {
+ VM_FAULT_OOM = 0x001,
+ VM_FAULT_SIGBUS = 0x002,
+ VM_FAULT_NOPAGE = 0x100,
+};
+
+enum { FAULT_FLAG_WRITE = 0x1 };
+//
+enum { DEFAULT_SEEKS = 2 };
+//
+//#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE)
+
+#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
+
+struct vm_fault {
+ void *virtual_address;
+ unsigned int flags;
+};
+//
+//struct file;
+struct address_space;
+//
+//unsigned long do_mmap(struct file *file, unsigned long addr,
+// unsigned long len, unsigned long prot,
+// unsigned long flag, unsigned long offset);
+//
+//void unmap_mapping_range(struct address_space *mapping,
+// loff_t const holebegin, loff_t const holelen,
+// int even_cows);
+//
+int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr,
+ unsigned long pfn);
+
+int set_page_dirty(struct page *page);
+
+void get_page(struct page *page);
+void put_page(struct page *page);
+//
+//int get_user_pages(void *tsk, struct mm_struct *mm,
+// unsigned long start, int nr_pages, int write, int force,
+// struct page **pages, struct vm_area_struct **vmas);
+//
+//void *page_address(struct page *page);
+//
+//struct shrinker {
+// int (*shrink)(int nr_to_scan, gfp_t gfp_mask);
+// int seeks;
+//};
+//
+//void register_shrinker(struct shrinker *);
+//void unregister_shrinker(struct shrinker *);
+
+extern unsigned long totalram_pages;
+
+
+struct vm_area_struct;
+struct vm_fault;
+
+struct vm_operations_struct {
+ void (*open)(struct vm_area_struct * area);
+ void (*close)(struct vm_area_struct * area);
+ int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);
+};
+
+struct file;
+
+extern unsigned long vm_mmap(struct file *, unsigned long,
+ unsigned long, unsigned long,
+ unsigned long, unsigned long);
+
+static inline void *page_address(struct page *page) { return page->addr; };
+
+int is_vmalloc_addr(const void *x);
+
+void free_pages(unsigned long addr, unsigned int order);
+
+
+#include
+
+
+/***************
+ ** asm/smp.h **
+ ***************/
+
+void wbinvd();
+void wbinvd_on_all_cpus();
+
+
+/*********************
+ ** linux/vmalloc.h **
+ *********************/
+
+//enum { VM_IOREMAP = 0x1 };
+
+/* needed by agp/generic.c */
+void *vmalloc(unsigned long size);
+void *vzalloc(unsigned long size);
+void vfree(const void *addr);
+
+///* needed by drm_memory.c */
+//void vunmap(const void *addr);
+//void *vmap(struct page **pages, unsigned int count, unsigned long flags, pgprot_t prot);
+
+
+/************************
+ ** uapi/linux/const.h **
+ ************************/
+
+#define _AT(T,X) ((T)(X))
+
+
+/*************************************************
+ ** asm/pgtable_64_types.h, asm/pgtable_types.h **
+ *************************************************/
+
+typedef unsigned long pteval_t;
+
+
+#define _PAGE_BIT_PRESENT 0 /* is present */
+#define _PAGE_BIT_RW 1 /* writeable */
+#define _PAGE_BIT_PWT 3 /* page write through */
+#define _PAGE_BIT_PCD 4 /* page cache disabled */
+#define _PAGE_BIT_PAT 7 /* on 4KB pages */
+
+#define _PAGE_PRESENT (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT)
+#define _PAGE_RW (_AT(pteval_t, 1) << _PAGE_BIT_RW)
+#define _PAGE_PWT (_AT(pteval_t, 1) << _PAGE_BIT_PWT)
+#define _PAGE_PCD (_AT(pteval_t, 1) << _PAGE_BIT_PCD)
+#define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
+
+
+/**********************
+ ** asm/cacheflush.h **
+ **********************/
+
+int set_pages_wb(struct page *page, int numpages);
+int set_pages_uc(struct page *page, int numpages);
+
+
+/******************
+ ** linux/slab.h **
+ ******************/
+
+enum {
+ SLAB_HWCACHE_ALIGN = 0x00002000ul,
+// SLAB_CACHE_DMA = 0x00004000ul,
+// SLAB_PANIC = 0x00040000ul,
+//
+// SLAB_LX_DMA = 0x80000000ul,
+};
+
+void *kzalloc(size_t size, gfp_t flags);
+void kfree(const void *);
+void *kcalloc(size_t n, size_t size, gfp_t flags);
+void *kmalloc(size_t size, gfp_t flags);
+void *krealloc(const void *, size_t, gfp_t);
+
+struct kmem_cache;
+struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, unsigned long, void (*)(void *));
+void kmem_cache_destroy(struct kmem_cache *);
+void *kmem_cache_zalloc(struct kmem_cache *k, gfp_t flags);
+void kmem_cache_free(struct kmem_cache *, void *);
+
+
+/**********************
+ ** linux/byteorder/ **
+ **********************/
+
+#include
+
+
+/******************
+ ** linux/swab.h **
+ ******************/
+
+#define swab16 __swab16
+
+
+/**********************
+ ** linux/highmem.h **
+ **********************/
+
+static inline void *kmap(struct page *page) { return page_address(page); }
+static inline void *kmap_atomic(struct page *page) { return kmap(page); }
+static inline void kunmap(struct page *page) { }
+static inline void kunmap_atomic(void *addr) { }
+
+
+#include
+
+void __free_pages(struct page *page, unsigned int order);
+
+#define __free_page(page) __free_pages((page), 0)
+
+struct page *alloc_pages(gfp_t gfp_mask, unsigned int order);
+
+#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
+
+unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order);
+
+
+/**************************************
+ ** asm-generic/dma-mapping-common.h **
+ **************************************/
+
+struct dma_attrs;
+struct device;
+
+enum dma_data_direction { DMA_DATA_DIRECTION_DUMMY };
+
+int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs);
+
+#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
+
+
+void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs);
+
+#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
+
+
+/*********************
+ ** linux/dma-buf.h **
+ *********************/
+
+struct dma_buf;
+
+
+/********************
+ ** linux/pm_qos.h **
+ ********************/
+
+enum { PM_QOS_CPU_DMA_LATENCY, };
+
+struct pm_qos_request { int dummy; };
+
+void pm_qos_remove_request(struct pm_qos_request *req);
+void pm_qos_update_request(struct pm_qos_request *req, s32 new_value);
+void pm_qos_add_request(struct pm_qos_request *req, int pm_qos_class, s32 value);
+
+
+#define PM_QOS_DEFAULT_VALUE -1
+
+
+/***********************
+ ** linux/pm_wakeup.h **
+ ***********************/
+
+bool device_can_wakeup(struct device *dev);
+int device_init_wakeup(struct device *dev, bool val);
+
+
+/*******************
+ ** linux/sysfs.h **
+ *******************/
+
+struct attribute { int dummy; };
+
+struct attribute_group {
+// const char *name;
+// umode_t (*is_visible)(struct kobject *,
+// struct attribute *, int);
+ struct attribute **attrs;
+// struct bin_attribute **bin_attrs;
+};
+
+
+/****************
+ ** linux/pm.h **
+ ****************/
+
+#include
+
+enum {
+ PM_EVENT_QUIESCE = 0x0008,
+ PM_EVENT_PRETHAW = PM_EVENT_QUIESCE,
+};
+
+#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn)
+
+
+/********************
+ ** linux/device.h **
+ ********************/
+
+struct device_driver;
+struct subsys_private;
+
+struct bus_type
+{
+ const char *name;
+
+ int (*match)(struct device *dev, struct device_driver *drv);
+ int (*probe)(struct device *dev);
+ int (*remove)(struct device *dev);
+ void (*shutdown)(struct device *dev);
+ int (*suspend)(struct device *dev, pm_message_t state);
+ int (*resume)(struct device *dev);
+
+ const struct dev_pm_ops *pm;
+ struct subsys_private *p;
+};
+
+struct device_type
+{
+ const struct attribute_group **groups;
+ int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
+ void (*release)(struct device *dev);
+};
+
+struct dev_archdata { int dummy; };
+
+struct device {
+ struct device *parent;
+ struct kobject kobj;
+ u64 _dma_mask_buf;
+ u64 *dma_mask;
+ u64 coherent_dma_mask;
+ struct device_driver *driver;
+ void *drvdata; /* not in Linux */
+ const struct device_type *type;
+ void *platform_data;
+ struct dev_archdata archdata;
+ struct bus_type *bus;
+ struct device_node *of_node;
+};
+
+struct device_attribute {
+ struct attribute attr;
+// ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+// char *buf);
+// ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+// const char *buf, size_t count);
+};
+
+#define DEVICE_ATTR(_name, _mode, _show, _store) \
+ struct device_attribute dev_attr_##_name = { { 0 } }
+
+#define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \
+ struct device_attribute dev_attr_##_name = { { 0 } }
+
+#define dev_info( dev, format, arg...) lx_printf("dev_info: " format , ## arg)
+#define dev_warn( dev, format, arg...) lx_printf("dev_warn: " format , ## arg)
+#define dev_WARN( dev, format, arg...) lx_printf("dev_WARN: " format , ## arg)
+#define dev_err( dev, format, arg...) lx_printf("dev_error: " format , ## arg)
+#define dev_notice(dev, format, arg...) lx_printf("dev_notice: " format , ## arg)
+#define dev_crit( dev, format, arg...) lx_printf("dev_crit: " format , ## arg)
+
+#define dev_printk(level, dev, format, arg...) \
+ lx_printf("dev_printk: " format , ## arg)
+#define dev_dbg(dev, format, arg...) \
+ lx_printf("dev_dbg: " format, ## arg)
+
+struct device_driver
+{
+ int dummy;
+ char const *name;
+ struct bus_type *bus;
+ struct module *owner;
+// const char *mod_name;
+// const struct of_device_id *of_match_table;
+// const struct acpi_device_id *acpi_match_table;
+// int (*probe) (struct device *dev);
+// int (*remove) (struct device *dev);
+//
+ const struct dev_pm_ops *pm;
+};
+
+int driver_register(struct device_driver *drv);
+void driver_unregister(struct device_driver *drv);
+
+void *dev_get_drvdata(const struct device *dev);
+int dev_set_drvdata(struct device *dev, void *data);
+int dev_set_name(struct device *dev, const char *name, ...);
+
+int bus_register(struct bus_type *bus);
+void bus_unregister(struct bus_type *bus);
+
+struct device *get_device(struct device *dev);
+void put_device(struct device *dev);
+
+int device_for_each_child(struct device *dev, void *data, int (*fn)(struct device *dev, void *data));
+int device_register(struct device *dev);
+void device_unregister(struct device *dev);
+
+const char *dev_name(const struct device *dev);
+
+int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
+ void *data, int (*fn)(struct device_driver *, void *));
+
+int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data,
+ int (*fn)(struct device *dev, void *data));
+
+/* needed by linux/i2c.h */
+struct acpi_device;
+
+struct acpi_dev_node { struct acpi_device *companion; };
+
+
+/****************
+ ** linux/io.h **
+ ****************/
+
+#define writel(value, addr) (*(volatile uint32_t *)(addr) = (value))
+#define readl(addr) (*(volatile uint32_t *)(addr))
+
+#define iowrite32(v, addr) writel((v), (addr))
+#define ioread32(addr) readl(addr)
+
+void outb(u8 value, u32 port);
+void outw(u16 value, u32 port);
+void outl(u32 value, u32 port);
+
+u8 inb(u32 port);
+u16 inw(u32 port);
+u32 inl(u32 port);
+
+void iounmap(volatile void *addr);
+
+void __iomem *ioremap(phys_addr_t offset, unsigned long size);
+
+/**
+ * Map I/O memory write combined
+ */
+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);
+
+
+/*********************
+ ** linux/uaccess.h **
+ *********************/
+
+enum { VERIFY_READ = 0, VERIFY_WRITE = 1 };
+
+#define get_user(x, ptr) ({ (x) = *(ptr); 0; })
+#define put_user(x, ptr) ({ *(ptr) = (x); 0; })
+
+bool access_ok(int access, void *addr, size_t size);
+
+size_t copy_from_user(void *to, void const *from, size_t len);
+size_t copy_to_user(void *dst, void const *src, size_t len);
+
+#define __copy_from_user copy_from_user
+#define __copy_to_user copy_to_user
+#define __copy_from_user_inatomic copy_from_user
+#define __copy_to_user_inatomic copy_to_user
+#define __copy_from_user_inatomic_nocache copy_from_user
+
+
+/*************************
+ ** linux/dma-mapping.h **
+ *************************/
+
+#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
+
+int dma_set_coherent_mask(struct device *dev, u64 mask);
+
+
+/************************
+ ** linux/io-mapping.h **
+ ************************/
+
+struct io_mapping;
+
+void *io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset);
+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);
+
+#include
+
+
+/********************
+ ** linux/ioport.h **
+ ********************/
+
+#include
+
+extern struct resource iomem_resource;
+
+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 **
+ *****************/
+
+enum { DEVICE_COUNT_RESOURCE = 6 };
+
+struct pci_dev {
+ unsigned int devfn;
+ unsigned int irq;
+ struct resource resource[DEVICE_COUNT_RESOURCE];
+ struct pci_bus *bus; /* i915_dma.c */
+ unsigned short vendor; /* intel-agp.c */
+ unsigned short device;
+ u8 hdr_type;
+ bool msi_enabled;
+ struct device dev; /* intel-agp.c */
+ unsigned short subsystem_vendor; /* intel_display.c */
+ unsigned short subsystem_device;
+ u8 revision; /* i915_gem.c */
+ u8 pcie_cap;
+ u16 pcie_flags_reg;
+ unsigned int class;
+};
+
+struct pci_device_id {
+ u32 vendor, device, subvendor, subdevice, class, class_mask;
+ unsigned long driver_data;
+};
+
+#include
+
+struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn);
+int pci_bus_alloc_resource(struct pci_bus *bus,
+ struct resource *res, resource_size_t size,
+ resource_size_t align, resource_size_t min,
+ unsigned int type_mask,
+ resource_size_t (*alignf)(void *,
+ const struct resource *,
+ resource_size_t,
+ resource_size_t),
+ void *alignf_data);
+resource_size_t pcibios_align_resource(void *, const struct resource *,
+ resource_size_t,
+ resource_size_t);
+int pci_set_power_state(struct pci_dev *dev, pci_power_t state);
+struct pci_dev *pci_get_class(unsigned int device_class, struct pci_dev *from);
+int pci_save_state(struct pci_dev *dev);
+
+enum { PCIBIOS_MIN_MEM = 0UL };
+
+
+static inline void pci_set_drvdata(struct pci_dev *pdev, void *data)
+{
+ pdev->dev.drvdata = data;
+}
+
+static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
+{
+ *dev->dev.dma_mask = mask;
+ return 0;
+}
+
+static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
+{
+ dev->dev.coherent_dma_mask = mask;
+ return 0;
+}
+
+/* agp/generic.c */
+#define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
+
+static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
+{
+ lx_printf("pci_bus_address called\n");
+ return (dma_addr_t)pci_resource_start(pdev, bar);
+}
+
+struct pci_dev *pci_dev_get(struct pci_dev *dev);
+
+
+/**********************************
+ ** asm-generic/pci-dma-compat.h **
+ **********************************/
+
+void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address, size_t size, int direction);
+
+dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, unsigned long offset, size_t size, int direction);
+
+int pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr);
+
+
+/*****************************
+ ** asm-generic/pci_iomap.h **
+ *****************************/
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+void pci_iounmap(struct pci_dev *dev, void __iomem *p);
+
+
+/***********************
+ ** linux/irqreturn.h **
+ ***********************/
+
+#include
+
+
+/************************
+ ** linux/capability.h **
+ ************************/
+
+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 **
+ *************************/
+
+#include
+
+
+/********************
+ ** linux/vgaarb.h **
+ ********************/
+
+/*
+ * needed for compiling i915_dma.c
+ */
+
+enum {
+ VGA_RSRC_LEGACY_IO = 0x01,
+ VGA_RSRC_LEGACY_MEM = 0x02,
+ VGA_RSRC_NORMAL_IO = 0x04,
+ VGA_RSRC_NORMAL_MEM = 0x08,
+};
+
+int vga_client_register(struct pci_dev *pdev, void *cookie,
+ void (*irq_set_state)(void *cookie, bool state),
+ unsigned int (*set_vga_decode)(void *cookie, bool state));
+
+int vga_get_uninterruptible(struct pci_dev *pdev, unsigned int rsrc);
+
+void vga_put(struct pci_dev *pdev, unsigned int rsrc);
+
+
+/**********************
+ ** linux/notifier.h **
+ **********************/
+
+/* needed by intel_lvds.c */
+
+struct notifier_block;
+
+typedef int (*notifier_fn_t)(struct notifier_block *nb, unsigned long action, void *data);
+
+struct notifier_block { notifier_fn_t notifier_call; };
+
+enum { NOTIFY_OK = 0x0001 };
+
+
+/*******************
+ ** acpi/button.h **
+ *******************/
+
+int acpi_lid_open(void);
+int acpi_lid_notifier_register(struct notifier_block *nb);
+int acpi_lid_notifier_unregister(struct notifier_block *nb);
+
+
+/****************************
+ ** linux/vga_switcheroo.h **
+ ****************************/
+
+/*
+ * needed for compiling i915_dma.c
+ */
+
+enum vga_switcheroo_state { VGA_SWITCHEROO_OFF, VGA_SWITCHEROO_ON };
+
+struct vga_switcheroo_client_ops {
+ void (*set_gpu_state)(struct pci_dev *dev, enum vga_switcheroo_state);
+ void (*reprobe)(struct pci_dev *dev);
+ bool (*can_switch)(struct pci_dev *dev);
+};
+
+int vga_switcheroo_register_client(struct pci_dev *dev,
+ const struct vga_switcheroo_client_ops *ops,
+ bool driver_power_control);
+
+void vga_switcheroo_unregister_client(struct pci_dev *dev);
+
+int vga_switcheroo_process_delayed_switch(void);
+
+
+/******************
+ ** acpi/video.h **
+ ******************/
+
+int acpi_video_register(void);
+void acpi_video_unregister(void);
+
+
+/*****************
+ ** asm/ioctl.h **
+ *****************/
+
+#include
+
+
+/*********************
+ ** linux/console.h **
+ *********************/
+
+void console_lock(void);
+void console_unlock(void);
+int console_trylock(void);
+
+
+/****************
+ ** linux/fb.h **
+ ****************/
+
+enum { FBINFO_STATE_RUNNING = 0, FBINFO_STATE_SUSPENDED = 1 };
+
+
+/****************
+ ** linux/fs.h **
+ ****************/
+
+struct file;
+struct poll_table_struct;
+struct inode;
+struct inode_operations { void (*truncate) (struct inode *); };
+
+struct inode {
+ const struct inode_operations *i_op;
+ struct address_space *i_mapping;
+};
+
+/* i915_drv.c */
+struct file_operations {
+ struct module *owner;
+ loff_t (*llseek) (struct file *, loff_t, int);
+ ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
+ unsigned int (*poll) (struct file *, struct poll_table_struct *);
+ long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
+ int (*mmap) (struct file *, struct vm_area_struct *);
+ int (*open) (struct inode *, struct file *);
+ int (*release) (struct inode *, struct file *);
+};
+
+enum { PROT_READ = 0x1, PROT_WRITE = 0x2 };
+
+enum { MAP_SHARED = 0x1 };
+
+loff_t noop_llseek(struct file *file, loff_t offset, int whence);
+
+struct inode *file_inode(struct file *f);
+
+
+/**********************
+ ** linux/shmem_fs.h **
+ **********************/
+
+extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end);
+
+extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
+ pgoff_t index, gfp_t gfp_mask);
+//extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
+// pgoff_t index, gfp_t gfp_mask);
+extern struct page *shmem_read_mapping_page( struct address_space *mapping, pgoff_t index);
+
+
+/********************
+ ** linux/math64.h **
+ ********************/
+
+static inline u64 div_u64(u64 dividend, u32 divisor) { return dividend / divisor; }
+
+
+/*****************************
+ ** linux/mod_devicetable.h **
+ *****************************/
+
+enum dmi_field {
+// DMI_NONE,
+// DMI_BIOS_VENDOR,
+// DMI_BIOS_VERSION,
+// DMI_BIOS_DATE,
+ DMI_SYS_VENDOR,
+ DMI_PRODUCT_NAME,
+ DMI_PRODUCT_VERSION,
+// DMI_PRODUCT_SERIAL,
+// DMI_PRODUCT_UUID,
+ DMI_BOARD_VENDOR,
+ DMI_BOARD_NAME,
+// DMI_BOARD_VERSION,
+// DMI_BOARD_SERIAL,
+// DMI_BOARD_ASSET_TAG,
+// DMI_CHASSIS_VENDOR,
+// DMI_CHASSIS_TYPE,
+// DMI_CHASSIS_VERSION,
+// DMI_CHASSIS_SERIAL,
+// DMI_CHASSIS_ASSET_TAG,
+// DMI_STRING_MAX,
+};
+
+struct dmi_strmatch {
+ unsigned char slot:7;
+ unsigned char exact_match:1;
+ char substr[79];
+};
+
+struct dmi_system_id {
+ int (*callback)(const struct dmi_system_id *);
+ const char *ident;
+ struct dmi_strmatch matches[4];
+ void *driver_data;
+};
+
+extern int dmi_check_system(const struct dmi_system_id *list);
+
+#define DMI_MATCH(a, b) { .slot = a, .substr = b }
+#define DMI_EXACT_MATCH(a, b) { .slot = a, .substr = b, .exact_match = 1 }
+
+#define I2C_MODULE_PREFIX "i2c:"
+#define I2C_NAME_SIZE 20
+
+struct i2c_device_id {
+ char name[I2C_NAME_SIZE];
+ kernel_ulong_t driver_data; /* Data private to the driver */
+};
+
+/*********************
+ ** asm/processor.h **
+ *********************/
+
+struct boot_cpu_data {
+ unsigned x86_clflush_size;
+};
+
+extern struct boot_cpu_data boot_cpu_data;
+
+
+/***********************
+ ** linux/backlight.h **
+ ***********************/
+
+/* intel_panel.c */
+
+struct backlight_properties {
+ int brightness;
+};
+
+struct backlight_device {
+ struct backlight_properties props;
+};
+
+
+/*****************
+ ** linux/i2c.h **
+ *****************/
+
+struct i2c_adapter;
+struct i2c_msg;
+
+#include
+
+
+
+/****************
+ ** linux/of.h **
+ ****************/
+
+int of_alias_get_id(struct device_node *np, const char *stem);
+
+
+/***********************
+ ** linux/of_device.h **
+ ***********************/
+
+int of_driver_match_device(struct device *dev, const struct device_driver *drv);
+
+
+/******************
+ ** linux/acpi.h **
+ ******************/
+
+struct kobject_uevent_env;
+
+bool acpi_driver_match_device(struct device *dev, const struct device_driver *drv);
+int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
+
+int acpi_dev_pm_attach(struct device *dev, bool power_on);
+void acpi_dev_pm_detach(struct device *dev, bool power_off);
+
+int acpi_device_modalias(struct device *, char *, int);
+
+#define ACPI_COMPANION(dev) (NULL)
+#define ACPI_COMPANION_SET(dev, adev) do { } while (0)
+
+const char *acpi_dev_name(struct acpi_device *adev);
+
+
+/******************
+ ** linux/gpio.h **
+ ******************/
+
+/* make these flag values available regardless of GPIO kconfig options */
+#define GPIOF_DIR_OUT (0 << 0)
+#define GPIOF_DIR_IN (1 << 0)
+
+#define GPIOF_INIT_LOW (0 << 1)
+#define GPIOF_INIT_HIGH (1 << 1)
+
+#define GPIOF_IN (GPIOF_DIR_IN)
+#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
+
+#define GPIOF_OPEN_DRAIN (1 << 3)
+
+/* needed bu drivers/i2c/i2c-core.c */
+int gpio_get_value(unsigned int gpio);
+void gpio_set_value(unsigned int gpio, int value);
+int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
+void gpio_free(unsigned gpio);
+bool gpio_is_valid(int number);
+
+
+/*******************
+ ** Configuration **
+ *******************/
+
+/* evaluated in i915_drv.c */
+enum { CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT = 1 };
+
+
+/**************************
+ ** Dummy trace funtions **
+ **************************/
+
+/* normally provided by i915_trace.h */
+
+#define trace_i915_gem_object_pread(...)
+#define trace_i915_gem_object_pwrite(...)
+#define trace_i915_gem_request_wait_begin(...)
+#define trace_i915_gem_request_wait_end(...)
+#define trace_i915_gem_object_fault(...)
+#define trace_i915_gem_request_add(...)
+#define trace_i915_gem_request_retire(...)
+#define trace_i915_gem_ring_sync_to(...)
+#define trace_i915_gem_object_change_domain(...)
+#define trace_i915_vma_unbind(...)
+#define trace_i915_vma_bind(...)
+#define trace_i915_gem_object_clflush(...)
+#define trace_i915_gem_object_create(...)
+#define trace_i915_gem_object_destroy(...)
+#define trace_i915_flip_complete(...)
+#define trace_i915_flip_request(...)
+#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
new file mode 100644
index 0000000000..81a550ae01
--- /dev/null
+++ b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc
@@ -0,0 +1,627 @@
+/*
+ * \brief Emulation of Linux kernel interfaces
+ * \author Norman Feske
+ * \date 2015-08-19
+ */
+
+/* local includes */
+#include "lx_emul_private.h"
+
+/* Genode includes */
+#include
+
+/* DRM-specific includes */
+extern "C" {
+#include
+#include
+#include
+}
+
+
+void lx_printf(char const *fmt, ...)
+{
+ va_list va;
+ va_start(va, fmt);
+ Genode::vprintf(fmt, va);
+ va_end(va);
+}
+
+
+void lx_vprintf(char const *fmt, va_list va)
+{
+ Genode::vprintf(fmt, va);
+}
+
+
+/****************************************
+ ** Common Linux kernel infrastructure **
+ ****************************************/
+
+#include
+
+int oops_in_progress;
+
+
+/********************
+ ** linux/string.h **
+ ********************/
+
+char *strncpy(char *dst, const char* src, size_t n)
+{
+ return Genode::strncpy(dst, src, n);
+}
+
+
+/*****************
+ ** linux/dmi.h **
+ *****************/
+
+int dmi_check_system(const struct dmi_system_id *list)
+{
+ TRACE;
+ /*
+ * Is used to check for quirks of the platform.
+ */
+ return 0;
+}
+
+
+/*******************
+ ** linux/delay.h **
+ *******************/
+
+#include
+
+
+/**********************
+ ** Global variables **
+ **********************/
+
+struct task_struct *current;
+
+
+struct boot_cpu_data boot_cpu_data;
+
+
+/*******************
+ ** Kernel memory **
+ *******************/
+
+#include
+#include
+
+
+dma_addr_t page_to_phys(void *p)
+{
+ struct page *page = (struct page *)p;
+
+ 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;
+}
+
+
+/*****************
+ ** linux/idr.h **
+ *****************/
+
+void idr_init(struct idr *idp)
+{
+ TRACE;
+}
+
+
+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 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;
+}
+
+
+
+/**********************
+ ** asm/cacheflush.h **
+ **********************/
+
+int set_pages_uc(struct page *page, int numpages)
+{
+ TRACE;
+ return 0;
+}
+
+
+/********************
+ ** linux/ioport.h **
+ ********************/
+
+struct resource iomem_resource;
+
+
+/*********
+ ** PCI **
+ *********/
+
+#include
+#include
+
+struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn)
+{
+ if (bus != 0 || devfn != 0)
+ TRACE_AND_STOP;
+
+ pci_dev *pci_dev = nullptr;
+
+ auto lamda = [&] (Platform::Device_capability cap) {
+
+ Platform::Device_client client(cap);
+
+ /* request bus address of device from platform driver */
+ unsigned char dev_bus = 0, dev_slot = 0, dev_fn = 0;
+ client.bus_address(&dev_bus, &dev_slot, &dev_fn);
+
+ if (dev_bus == bus && PCI_SLOT(devfn) == dev_slot && PCI_FUNC(devfn) == dev_fn) {
+ Lx::Pci_dev *dev = new (Genode::env()->heap()) Lx::Pci_dev(cap);
+ Lx::pci_dev_registry()->insert(dev);
+ pci_dev = dev;
+ return true;
+ }
+
+ return false;
+ };
+
+ Lx::for_each_pci_device(lamda);
+
+ return pci_dev;
+}
+
+
+struct pci_dev *pci_get_class(unsigned int class_code, struct pci_dev *from)
+{
+ /*
+ * The function is solely called by the i915 initialization code to
+ * probe for the ISA bridge device in order to detect the hardware
+ * generation.
+ *
+ * We look up the bridge but don't need to support the iteration over
+ * multiple devices of the given class.
+ */
+ if (from)
+ return nullptr;
+
+ pci_dev *pci_dev = nullptr;
+
+ auto lamda = [&] (Platform::Device_capability cap) {
+
+ Platform::Device_client client(cap);
+
+ if (client.class_code() == class_code) {
+ pci_dev = new (Genode::env()->heap()) Lx::Pci_dev(cap);
+ return true;
+ }
+
+ return false;
+ };
+
+ Lx::for_each_pci_device(lamda);
+
+ return pci_dev;
+}
+
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
+{
+ return pci_ioremap_bar(dev, bar);
+}
+
+
+struct pci_dev *pci_dev_get(struct pci_dev *dev)
+{
+ TRACE;
+ return dev;
+};
+
+
+int vga_get_uninterruptible(struct pci_dev *pdev, unsigned int rsrc)
+{
+ /*
+ * This function locks the VGA device. It is normally provided by the
+ * VGA arbiter in the Linux kernel. We don't need this arbitration because
+ * the platform-driver enforces the exclusive access to the VGA resources
+ * by our driver.
+ *
+ * At the time when this function is called, the 'pci_dev' structure for
+ * the VGA card was already requested. Hence, subsequent I/O accesses
+ * should work.
+ */
+ TRACE;
+ return 0;
+}
+
+
+void vga_put(struct pci_dev *pdev, unsigned int rsrc)
+{
+ TRACE;
+}
+
+
+int pci_bus_alloc_resource(struct pci_bus *, struct resource *, resource_size_t,
+ resource_size_t, resource_size_t, unsigned int,
+ resource_size_t (*)(void *, const struct resource *, resource_size_t, resource_size_t),
+ void *alignf_data)
+{
+ TRACE;
+ return 0;
+}
+
+
+void pci_set_master(struct pci_dev *dev)
+{
+ TRACE;
+}
+
+
+int pci_enable_msi(struct pci_dev *dev)
+{
+ TRACE;
+ return 0;
+}
+
+
+
+struct io_mapping
+{
+ private:
+
+ resource_size_t _base;
+ unsigned long _size;
+
+ public:
+
+ /**
+ * Constructor
+ */
+ io_mapping(resource_size_t base, unsigned long size) :
+ _base(base), _size(size) { }
+
+ resource_size_t base() const { return _base; }
+};
+
+
+/**
+ * I/O mapping used by i915_dma.c to map the GTT aperture
+ */
+struct io_mapping *io_mapping_create_wc(resource_size_t base, unsigned long size)
+{
+ static int called;
+ TRACE;
+
+ if (called++ != 0) {
+ PERR("io_mapping_create_wc unexpectedly called twice");
+ return 0;
+ }
+
+ io_mapping *mapping = new (Genode::env()->heap()) io_mapping(base, size);
+ return mapping;
+}
+
+
+/****************
+ ** linux/io.h **
+ ****************/
+
+int arch_phys_wc_add(unsigned long base, unsigned long size)
+{
+ /*
+ * Linux tries to manipulate physical memory attributes here (e.g.,
+ * using MTRRs). But when using PAT, this is not needed. When running
+ * on top of a microkernel, we cannot manipulate the attributes
+ * anyway.
+ */
+ TRACE;
+ return 0;
+}
+
+
+/********************
+ ** linux/device.h **
+ ********************/
+
+struct subsys_private { int dummy; };
+
+int bus_register(struct bus_type *bus)
+{
+ /*
+ * called by i2c-core init
+ *
+ * The subsequent code checks for the 'p' member of the 'bus'. So
+ * we have to supply a valid pointer there.
+ */
+
+ static subsys_private priv = { 0 };
+ bus->p = &priv;
+
+ TRACE;
+ return 0;
+}
+
+
+int driver_register(struct device_driver *drv)
+{
+ TRACE;
+ return 0;
+}
+
+
+int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data,
+ int (*fn)(struct device *dev, void *data))
+{
+ /*
+ * Called bu the i2c-core driver after registering the driver. This
+ * function is called to process drivers that are present at initialization
+ * time. Since we initialize the i2c driver prior the others, we don't
+ * need to perform anything.
+ */
+ TRACE;
+ return 0;
+}
+
+
+int dev_set_name(struct device *dev, const char *name, ...)
+{
+ PDBG("name=%s", name);
+ TRACE;
+ return 0;
+}
+
+
+int device_register(struct device *dev)
+{
+ TRACE;
+ return 0;
+}
+
+
+/***********************
+ ** linux/workqueue.h **
+ ***********************/
+
+struct workqueue_struct *create_singlethread_workqueue(char const *)
+{
+ workqueue_struct *wq = (workqueue_struct *)kzalloc(sizeof(workqueue_struct), 0);
+ return wq;
+}
+
+struct workqueue_struct *alloc_ordered_workqueue(char const *name , unsigned int flags, ...)
+{
+ return create_singlethread_workqueue(name);
+}
+
+
+/***************
+ ** Execution **
+ ***************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+void __wait_completion(struct completion *work)
+{
+ TRACE_AND_STOP;
+}
+
+
+void mutex_lock_nest_lock(struct mutex *lock, struct mutex *)
+{
+ TRACE;
+ /*
+ * Called by drm_crtc.c: drm_modeset_lock_all, drm_crtc_init to
+ * lock the crtc mutex.
+ */
+ mutex_lock(lock);
+}
+
+
+/************************
+ ** DRM implementation **
+ ************************/
+
+unsigned int drm_debug = 1;
+
+
+extern "C" int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
+{
+ PDBG("call pci_register_driver");
+
+ return pci_register_driver(pdriver);
+}
+
+
+struct drm_device *drm_dev_alloc(struct drm_driver *driver, struct device *parent)
+{
+ struct drm_device *dev = (drm_device *)kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return nullptr;
+
+ dev->driver = driver;
+
+ spin_lock_init(&dev->count_lock);
+ spin_lock_init(&dev->event_lock);
+
+ mutex_init(&dev->struct_mutex);
+
+// ret = drm_gem_init(dev);
+// if (ret) {
+// PERR("drm_gem_init failed");
+// return nullptr;
+// }
+
+ return dev;
+}
+
+
+/*
+ * Called indirectly when 'pci_register_driver' has found a matching
+ * device.
+ */
+int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
+ struct drm_driver *driver)
+{
+ drm_device *dev = drm_dev_alloc(driver, &pdev->dev);
+ if (!dev)
+ return -ENOMEM;
+
+// ret = pci_enable_device(pdev);
+
+ dev->pdev = pdev;
+
+ pci_set_drvdata(pdev, dev);
+
+// drm_pci_agp_init(dev);
+
+ /*
+ * Kick off the actual driver initialization code
+ *
+ * In the Linux DRM code, this happens indirectly via the call of
+ * 'drm_dev_register'.
+ */
+ driver->load(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,
+ driver->date, pci_name(pdev), dev->primary->index);
+
+ return 0;
+}
+
+
+/**
+ * Called from 'i915_driver_load'
+ */
+int drm_vblank_init(struct drm_device *dev, int num_crtcs)
+{
+ TRACE;
+ return 0;
+}
+
+
+int drm_irq_install(struct drm_device *dev)
+{
+ TRACE;
+ return 0;
+}
+
+
+/**************************************
+ ** 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)
+{
+ 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;
+}
+
+int register_shrinker(struct shrinker *)
+{
+ TRACE;
+ return 0;
+}
+
+int vga_client_register(struct pci_dev *pdev, void *cookie, void (*irq_set_state)(void *cookie, bool state), unsigned int (*set_vga_decode)(void *cookie, bool state))
+{
+ TRACE;
+ return -ENODEV;
+}
+
+int vga_switcheroo_register_client(struct pci_dev *dev, const struct vga_switcheroo_client_ops *ops, bool driver_power_control)
+{
+ TRACE;
+ return 0;
+}
+
+int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
+{
+ TRACE;
+ return 0;
+}
+
+struct i915_ctx_hang_stats * i915_gem_context_get_hang_stats(struct drm_device *dev, struct drm_file *file, u32 id)
+{
+ TRACE_AND_STOP;
+ return NULL;
+}
+
+struct resource * devm_request_mem_region(struct device *dev, resource_size_t start, resource_size_t n, const char *name)
+{
+ /*
+ * This function solely called for keeping the stolen memory preserved
+ * for the driver only ('i915_stolen_to_physical'). The returned pointer is
+ * just checked for NULL but not used otherwise.
+ */
+ TRACE;
+ static struct resource dummy;
+ return &dummy;
+}
+
+
+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
new file mode 100644
index 0000000000..c47c5b0287
--- /dev/null
+++ b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul_private.h
@@ -0,0 +1,28 @@
+/*
+ * \brief Local definitions of the Linux kernel API implementation
+ * \author Norman Feske
+ * \date 2015-08-24
+ */
+
+#ifndef _LX_EMUL_PRIVATE_H_
+#define _LX_EMUL_PRIVATE_H_
+
+/* Genode includes */
+#include
+#include
+
+/* Linux kernel API */
+#include
+
+#define TRACE \
+ do { \
+ PLOG("%s not implemented", __func__); \
+ } while (0)
+
+#define TRACE_AND_STOP \
+ do { \
+ PWRN("%s not implemented", __func__); \
+ 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
new file mode 100644
index 0000000000..c35960c3da
--- /dev/null
+++ b/repos/dde_linux/src/drivers/framebuffer/intel/main.cc
@@ -0,0 +1,115 @@
+/*
+ * \brief Intel framebuffer driver
+ * \author Norman Feske
+ * \date 2015-08-19
+ */
+
+/*
+ * 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.
+ */
+
+/* Genode includes */
+#include
+#include
+
+/* Linux emulation environment includes */
+#include
+#include
+#include
+#include
+#include
+
+
+namespace Server { struct Main; }
+
+
+Lx::Scheduler & Lx::scheduler()
+{
+ static Lx::Scheduler inst;
+ return inst;
+}
+
+
+Lx::Timer & Lx::timer(Server::Entrypoint *ep, unsigned long *jiffies)
+{
+ return _timer_impl(ep, jiffies);
+}
+
+
+Platform::Connection *Lx::pci()
+{
+ static Platform::Connection _pci;
+ return &_pci;
+}
+
+
+Lx::Pci_dev_registry *Lx::pci_dev_registry()
+{
+ static Lx::Pci_dev_registry _pci_dev_registry;
+ return &_pci_dev_registry;
+}
+
+
+namespace Lx {
+ Genode::Object_pool memory_pool;
+};
+
+
+extern "C" int postcore_i2c_init(); /* i2c-core.c */
+extern "C" int module_i915_init(); /* i915_drv.c */
+
+
+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();
+ }
+}
+
+
+unsigned long jiffies;
+
+
+struct Server::Main
+{
+ Entrypoint &ep;
+
+ /* init singleton Lx::Timer */
+ Lx::Timer &timer = Lx::timer(&ep, &jiffies);
+
+ /* Linux task that handles the initialization */
+ Lx::Task linux { run_linux, nullptr, "linux",
+ Lx::Task::PRIORITY_0, Lx::scheduler() };
+
+ Main(Entrypoint &ep) : ep(ep)
+ {
+ Genode::printf("--- intel framebuffer driver ---\n");
+
+ /* give all task a first kick before returning */
+ Lx::scheduler().schedule();
+
+ PDBG("returning from main");
+ }
+};
+
+
+namespace Server {
+
+ char const *name() { return "intel_fb_ep"; }
+
+ size_t stack_size() { return 8*1024*sizeof(long); }
+
+ void construct(Entrypoint &ep)
+ {
+ static Main main(ep);
+ }
+}
diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/target.mk b/repos/dde_linux/src/drivers/framebuffer/intel/target.mk
new file mode 100644
index 0000000000..a92f5c8363
--- /dev/null
+++ b/repos/dde_linux/src/drivers/framebuffer/intel/target.mk
@@ -0,0 +1,5 @@
+TARGET = intel_fb_drv
+LIBS = base intel_fb_drv intel_fb_include libc-setjmp server
+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/atomic.h b/repos/dde_linux/src/include/lx_emul/atomic.h
new file mode 100644
index 0000000000..0829b40903
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/atomic.h
@@ -0,0 +1,111 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*******************
+ ** asm/cmpxchg.h **
+ *******************/
+
+#define cmpxchg(ptr, o, n) ({ \
+ typeof(*ptr) prev = *ptr; \
+ *ptr = (*ptr == o) ? n : *ptr; \
+ prev;\
+ })
+
+#define xchg(ptr, x) ({ \
+ typeof(*ptr) old = *ptr; \
+ *ptr = x; \
+ old; \
+})
+
+#define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v)))
+
+
+/******************
+ ** asm/atomic.h **
+ ******************/
+
+#include
+
+#define ATOMIC_INIT(i) { (i) }
+
+typedef struct atomic { long counter; } atomic_t;
+typedef atomic_t atomic_long_t;
+
+static inline int atomic_read(const atomic_t *p) { return p->counter; }
+static inline void atomic_set(atomic_t *p, int i) { p->counter = i; }
+static inline void atomic_sub(int i, atomic_t *p) { p->counter -= i; }
+static inline void atomic_add(int i, atomic_t *p) { p->counter += i; }
+static inline int atomic_sub_return(int i, atomic_t *p) { p->counter -= i; return p->counter; }
+static inline int atomic_add_return(int i, atomic_t *p) { p->counter += i; return p->counter; }
+static inline int atomic_sub_and_test(int i, atomic_t *p) { return atomic_sub_return(i, p) == 0; }
+
+static inline void atomic_dec(atomic_t *p) { atomic_sub(1, p); }
+static inline void atomic_inc(atomic_t *p) { atomic_add(1, p); }
+static inline int atomic_dec_return(atomic_t *p) { return atomic_sub_return(1, p); }
+static inline int atomic_inc_return(atomic_t *p) { return atomic_add_return(1, p); }
+static inline int atomic_dec_and_test(atomic_t *p) { return atomic_sub_and_test(1, p); }
+static inline int atomic_inc_not_zero(atomic_t *p) { return p->counter ? atomic_inc_return(p) : 0; }
+
+static inline void atomic_long_inc(atomic_long_t *p) { atomic_add(1, p); }
+static inline void atomic_long_sub(int i, atomic_long_t *p) { atomic_sub(i, p); }
+static inline long atomic_long_add_return(long i, atomic_long_t *p) { return atomic_add_return(i, p); }
+static inline long atomic_long_read(atomic_long_t *p) { return atomic_read(p); }
+
+static inline int atomic_cmpxchg(atomic_t *v, int old, int n)
+{
+ return cmpxchg(&v->counter, old, n);
+}
+
+static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint)
+{
+ int val, c = hint;
+
+ /* sanity test, should be removed by compiler if hint is a constant */
+ if (!hint)
+ return atomic_inc_not_zero(v);
+
+ do {
+ val = atomic_cmpxchg(v, c, c + 1);
+ if (val == c)
+ return 1;
+ c = val;
+ } while (c);
+
+ return 0;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int ret;
+ unsigned long flags;
+ (void)flags;
+
+ ret = v->counter;
+ if (ret != u)
+ v->counter += a;
+
+ return ret != u;
+}
+
+#define smp_mb__before_atomic_dec()
+
+
+/*******************************
+ ** asm-generic/atomic-long.h **
+ *******************************/
+
+#define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i)
diff --git a/repos/dde_linux/src/include/lx_emul/bitops.h b/repos/dde_linux/src/include/lx_emul/bitops.h
new file mode 100644
index 0000000000..c87dc14a34
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/bitops.h
@@ -0,0 +1,111 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*******************************
+ ** asm-generic/bitsperlong.h **
+ *******************************/
+
+#define BITS_PER_LONG (__SIZEOF_LONG__ * 8)
+
+
+/**********************************
+ ** linux/bitops.h, asm/bitops.h **
+ **********************************/
+
+#define BITS_PER_BYTE 8
+#define BIT(nr) (1UL << (nr))
+#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
+
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
+
+#include
+
+#define test_and_clear_bit(nr, addr) \
+ __test_and_clear_bit(nr, (volatile unsigned long *)(addr))
+#define test_and_set_bit(nr, addr) \
+ __test_and_set_bit(nr, (volatile unsigned long *)(addr))
+#define set_bit(nr, addr) \
+ __set_bit(nr, (volatile unsigned long *)(addr))
+#define clear_bit(nr, addr) \
+ __clear_bit(nr, (volatile unsigned long *)(addr))
+
+#define smp_mb__before_clear_bit()
+#define smp_mb__after_clear_bit() smp_mb()
+
+/**
+ * Find first zero bit (limit to machine word size)
+ */
+long find_next_zero_bit_le(const void *addr,
+ unsigned long size, unsigned long offset);
+
+
+#include
+#include
+#include
+#include
+#include
+
+static inline unsigned fls_long(unsigned long l)
+{
+ if (sizeof(l) == 4)
+ return fls(l);
+ return fls64(l);
+}
+
+static inline unsigned long __ffs64(u64 word)
+{
+#if BITS_PER_LONG == 32
+ if (((u32)word) == 0UL)
+ return __ffs((u32)(word >> 32)) + 32;
+#elif BITS_PER_LONG != 64
+#error BITS_PER_LONG not 32 or 64
+#endif
+ return __ffs((unsigned long)word);
+}
+
+#include
+
+#define for_each_set_bit(bit, addr, size) \
+ for ((bit) = find_first_bit((addr), (size)); \
+ (bit) < (size); \
+ (bit) = find_next_bit((addr), (size), (bit) + 1))
+
+static inline int get_bitmask_order(unsigned int count) {
+ return __builtin_clz(count) ^ 0x1f; }
+
+static inline __s32 sign_extend32(__u32 value, int index)
+{
+ __u8 shift = 31 - index;
+ return (__s32)(value << shift) >> shift;
+}
+
+static inline __u32 rol32(__u32 word, unsigned int shift)
+{
+ return (word << shift) | (word >> (32 - shift));
+}
+
+static inline __u32 ror32(__u32 word, unsigned int shift)
+{
+ return (word >> shift) | (word << (32 - shift));
+}
+
+static inline __u16 ror16(__u16 word, unsigned int shift)
+{
+ return (word >> shift) | (word << (16 - shift));
+}
+
diff --git a/repos/dde_linux/src/include/lx_emul/bug.h b/repos/dde_linux/src/include/lx_emul/bug.h
new file mode 100644
index 0000000000..48fa6e0788
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/bug.h
@@ -0,0 +1,40 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/***************
+ ** asm/bug.h **
+ ***************/
+
+#define WARN_ON(condition) ({ \
+ int ret = !!(condition); \
+ if (ret) lx_printf("[%s] WARN_ON(" #condition ") ", __func__); \
+ ret; })
+
+#define WARN(condition, fmt, arg...) ({ \
+ int ret = !!(condition); \
+ if (ret) lx_printf("[%s] *WARN* " fmt , __func__ , ##arg); \
+ ret; })
+
+#define BUG() do { \
+ lx_printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
+ while (1); \
+} while (0)
+
+#define WARN_ON_ONCE WARN_ON
+#define WARN_ONCE WARN
+
+#define BUG_ON(condition) do { if (condition) BUG(); } while(0)
diff --git a/repos/dde_linux/src/include/lx_emul/byteorder.h b/repos/dde_linux/src/include/lx_emul/byteorder.h
new file mode 100644
index 0000000000..1ad816084a
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/byteorder.h
@@ -0,0 +1,48 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*************************************
+ ** linux/byteorder/little_endian.h **
+ *************************************/
+
+#include
+
+
+/*******************************
+ ** linux/byteorder/generic.h **
+ *******************************/
+
+#define le16_to_cpu __le16_to_cpu
+#define be16_to_cpu __be16_to_cpu
+#define le32_to_cpu __le32_to_cpu
+#define be32_to_cpu __be32_to_cpu
+#define le16_to_cpus __le16_to_cpus
+#define cpu_to_le16p __cpu_to_le16p
+#define cpu_to_be16p __cpu_to_be16p
+#define cpu_to_le16 __cpu_to_le16
+#define cpu_to_le16s __cpu_to_le16s
+#define cpu_to_be16 __cpu_to_be16
+#define cpu_to_le32 __cpu_to_le32
+#define cpu_to_be32 __cpu_to_be32
+#define cpu_to_le32s __cpu_to_le32s
+#define cpu_to_le64 __cpu_to_le64
+#define le16_to_cpup __le16_to_cpup
+#define be16_to_cpup __be16_to_cpup
+#define le32_to_cpup __le32_to_cpup
+#define le32_to_cpus __le32_to_cpus
+#define be32_to_cpup __be32_to_cpup
+#define le64_to_cpu __le64_to_cpu
diff --git a/repos/dde_linux/src/include/lx_emul/compiler.h b/repos/dde_linux/src/include/lx_emul/compiler.h
new file mode 100644
index 0000000000..5a9dbc3a48
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/compiler.h
@@ -0,0 +1,70 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/**********************
+ ** linux/compiler.h **
+ **********************/
+
+#define likely
+#define unlikely
+
+#define __user
+#define __iomem
+#define __rcu
+#define __percpu
+#define __must_check
+#define __force
+#define __read_mostly
+
+#define __releases(x) /* needed by usb/core/devio.c */
+#define __acquires(x) /* needed by usb/core/devio.c */
+#define __force
+#define __maybe_unused
+#define __bitwise
+
+# define __acquire(x) (void)0
+# define __release(x) (void)0
+
+#define __must_check
+
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+
+#define __attribute_const__
+#undef __always_inline
+#define __always_inline
+#undef __unused
+
+#define noinline __attribute__((noinline))
+
+#define __printf(a, b) __attribute__((format(printf, a, b)))
+
+#define __always_unused
+#define __read_mostly
+
+#define __noreturn __attribute__((noreturn))
+
+
+/**************************
+ ** linux/compiler-gcc.h **
+ **************************/
+
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+#define uninitialized_var(x) x = x
+
diff --git a/repos/dde_linux/src/include/lx_emul/errno.h b/repos/dde_linux/src/include/lx_emul/errno.h
new file mode 100644
index 0000000000..341242ab7c
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/errno.h
@@ -0,0 +1,126 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*******************************
+ ** linux/errno.h and friends **
+ *******************************/
+
+/**
+ * Error codes
+ *
+ * Note that the codes do not correspond to those of the Linux kernel.
+ */
+enum {
+ /*
+ * The following numbers correspond to FreeBSD
+ */
+ EPERM = 1,
+ ENOENT = 2,
+ ESRCH = 3,
+ EINTR = 4,
+ EIO = 5,
+ ENXIO = 6,
+ E2BIG = 7,
+ EDEADLK = 11,
+ ENOMEM = 12,
+ EACCES = 13,
+ EFAULT = 14,
+ EBUSY = 16,
+ EEXIST = 17,
+ EXDEV = 18,
+ ENODEV = 19,
+ EINVAL = 22,
+ ENFILE = 23,
+ EFBIG = 27,
+ ENOSPC = 28,
+ ESPIPE = 29,
+ EPIPE = 32,
+ EDOM = 33,
+ ERANGE = 34,
+ EAGAIN = 35,
+ EINPROGRESS = 36,
+ EALREADY = 37,
+ ENOTSOCK = 38,
+ EDESTADDRREQ = 39,
+ EMSGSIZE = 40,
+ ENOPROTOOPT = 42,
+ EPROTONOSUPPORT = 43,
+ ESOCKTNOSUPPORT = 44,
+ EOPNOTSUPP = 45,
+ EPFNOSUPPORT = 46,
+ EAFNOSUPPORT = 47,
+ EADDRINUSE = 48,
+ EADDRNOTAVAIL = 49,
+ ENETDOWN = 50,
+ ENETUNREACH = 51,
+ ECONNABORTED = 53,
+ ECONNRESET = 54,
+ ENOBUFS = 55,
+ EISCONN = 56,
+ ENOTCONN = 57,
+ ETIMEDOUT = 60,
+ ECONNREFUSED = 61,
+ ENAMETOOLONG = 63,
+ EHOSTDOWN = 64,
+ EHOSTUNREACH = 65,
+ ENOSYS = 78,
+ ENOMSG = 83,
+ EOVERFLOW = 84,
+ ECANCELED = 85,
+ EILSEQ = 86,
+ EBADMSG = 89,
+ ENOLINK = 91,
+ EPROTO = 92,
+
+ /*
+ * The following numbers correspond to nothing
+ */
+ EREMOTEIO = 200,
+ ERESTARTSYS = 201,
+ ENODATA = 202,
+ ETOOSMALL = 203,
+ ENOIOCTLCMD = 204,
+ ENONET = 205,
+ ENOTSUPP = 206,
+ ENOTUNIQ = 207,
+ ERFKILL = 208,
+ ETIME = 209,
+
+ MAX_ERRNO = 4095,
+};
+
+
+ /*****************
+ ** linux/err.h **
+ *****************/
+
+#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
+
+static inline bool IS_ERR(void const *ptr) {
+ return (unsigned long)(ptr) > (unsigned long)(-1000); }
+
+static inline void * ERR_PTR(long error) {
+ return (void *) error; }
+
+static inline void * ERR_CAST(const void *ptr) {
+ return (void *) ptr; }
+
+static inline long IS_ERR_OR_NULL(const void *ptr) {
+ return !ptr || IS_ERR_VALUE((unsigned long)ptr); }
+
+static inline long PTR_ERR(const void *ptr) { return (long) ptr; }
+
diff --git a/repos/dde_linux/src/include/lx_emul/extern_c_begin.h b/repos/dde_linux/src/include/lx_emul/extern_c_begin.h
new file mode 100644
index 0000000000..a880be1952
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/extern_c_begin.h
@@ -0,0 +1,30 @@
+/*
+ * \brief Include before including Linux headers in C++
+ * \author Christian Helmuth
+ * \date 2014-08-21
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifdef __cplusplus
+
+#define extern_c_begin
+
+extern "C" {
+
+/* some warnings should only be switched of for Linux headers */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpointer-arith"
+#pragma GCC diagnostic ignored "-Wsign-compare"
+
+/* deal with C++ keywords used for identifiers etc. */
+#define private private_
+#define class class_
+#define new new_
+
+#endif /* __cplusplus */
diff --git a/repos/dde_linux/src/include/lx_emul/extern_c_end.h b/repos/dde_linux/src/include/lx_emul/extern_c_end.h
new file mode 100644
index 0000000000..f9aa11ad11
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/extern_c_end.h
@@ -0,0 +1,24 @@
+/*
+ * \brief Include after including Linux headers in C++
+ * \author Christian Helmuth
+ * \date 2014-08-21
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifdef __cplusplus
+
+#undef new
+#undef class
+#undef private
+
+#pragma GCC diagnostic pop
+
+} /* extern "C" */
+
+#endif /* __cplusplus */
diff --git a/repos/dde_linux/src/include/lx_emul/gfp.h b/repos/dde_linux/src/include/lx_emul/gfp.h
new file mode 100644
index 0000000000..6f385ef8e7
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/gfp.h
@@ -0,0 +1,58 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*****************
+ ** linux/gfp.h **
+ *****************/
+
+enum {
+ __GFP_DMA = 0x00000001u,
+ __GFP_HIGHMEM = 0x00000002u,
+ __GFP_DMA32 = 0x00000004u,
+ __GFP_MOVABLE = 0x00000008u,
+ __GFP_WAIT = 0x00000010u,
+ __GFP_HIGH = 0x00000020u,
+ __GFP_IO = 0x00000040u,
+ __GFP_FS = 0x00000080u,
+ __GFP_COLD = 0x00000100u,
+ __GFP_NOWARN = 0x00000200u,
+ __GFP_REPEAT = 0x00000400u,
+ __GFP_NOFAIL = 0x00000800u,
+ __GFP_NORETRY = 0x00001000u,
+ __GFP_MEMALLOC = 0x00002000u,
+ __GFP_COMP = 0x00004000u,
+ __GFP_ZERO = 0x00008000u,
+ __GFP_NOMEMALLOC = 0x00010000u,
+ __GFP_HARDWALL = 0x00020000u,
+ __GFP_THISNODE = 0x00040000u,
+ __GFP_RECLAIMABLE = 0x00080000u,
+ __GFP_KMEMCG = 0x00100000u,
+ __GFP_NOTRACK = 0x00200000u,
+ __GFP_NO_KSWAPD = 0x00400000u,
+ __GFP_OTHER_NODE = 0x00800000u,
+ __GFP_WRITE = 0x01000000u,
+
+ GFP_LX_DMA = 0x80000000u,
+
+ GFP_ATOMIC = __GFP_HIGH,
+ GFP_DMA = __GFP_DMA,
+ GFP_DMA32 = __GFP_DMA32,
+ GFP_KERNEL = __GFP_WAIT | __GFP_IO | __GFP_FS,
+ GFP_USER = __GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL,
+ GFP_HIGHUSER = __GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL |
+ __GFP_HIGHMEM,
+};
diff --git a/repos/dde_linux/src/include/lx_emul/impl/completion.h b/repos/dde_linux/src/include/lx_emul/impl/completion.h
new file mode 100644
index 0000000000..5fdac72f66
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/completion.h
@@ -0,0 +1,112 @@
+/*
+ * \brief Implementation of linux/completion.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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.
+ */
+
+typedef Lx::Task::List_element Wait_le;
+typedef Lx::Task::List Wait_list;
+
+
+void init_waitqueue_head(wait_queue_head_t *wq)
+{
+ wq->list = new (Genode::env()->heap()) Wait_list;
+}
+
+
+int waitqueue_active(wait_queue_head_t *wq)
+{
+ Wait_list *list = static_cast(wq->list);
+ if (!list)
+ return 0;
+
+ return list->first() ? 1 : 0;
+}
+
+
+void __wake_up(wait_queue_head_t *wq, bool all)
+{
+ Wait_list *list = static_cast(wq->list);
+ if (!list) {
+ PWRN("wait_queue_head_t is empty, wq: %p called from: %p", wq, __builtin_return_address(0));
+ return;
+ }
+
+ Wait_le *le = list->first();
+ do {
+ if (!le)
+ return;
+
+ le->object()->unblock();
+ } while (all && (le = le->next()));
+}
+
+
+void wake_up_interruptible_sync_poll(wait_queue_head_t *wq, int)
+{
+ __wake_up(wq, false);
+}
+
+
+void __wait_event(wait_queue_head_t wq)
+{
+ Wait_list *list = static_cast(wq.list);
+ if (!list) {
+ PERR("__wait_event(): empty list in wq: %p", &wq);
+ Genode::sleep_forever();
+ }
+
+ Lx::Task *task = Lx::scheduler().current();
+
+ task->wait_enqueue(list);
+ task->block_and_schedule();
+ task->wait_dequeue(list);
+}
+
+
+void init_completion(struct completion *work)
+{
+ work->done = 0;
+}
+
+
+void complete(struct completion *work)
+{
+ work->done = 1;
+}
+
+
+unsigned long wait_for_completion_timeout(struct completion *work,
+ unsigned long timeout)
+{
+ __wait_completion(work);
+ return 1;
+}
+
+
+int wait_for_completion_interruptible(struct completion *work)
+{
+ __wait_completion(work);
+ return 0;
+}
+
+
+long wait_for_completion_interruptible_timeout(struct completion *work,
+ unsigned long timeout)
+{
+ __wait_completion(work);
+ return 1;
+}
+
+
+void wait_for_completion(struct completion *work)
+{
+ __wait_completion(work);
+}
diff --git a/repos/dde_linux/src/include/lx_emul/impl/delay.h b/repos/dde_linux/src/include/lx_emul/impl/delay.h
new file mode 100644
index 0000000000..e5a141fc96
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/delay.h
@@ -0,0 +1,30 @@
+/*
+ * \brief Implementation of linux/delay.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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.
+ */
+
+/* Genode includes */
+#include
+
+/*
+ * XXX We may consider to use the Lx::Timer instead of opening a dedicated
+ * timer session.
+ */
+static Timer::Connection _delay_timer;
+
+
+void udelay(unsigned long usecs) { _delay_timer.usleep(usecs); }
+
+
+void msleep(unsigned int msecs) { _delay_timer.msleep(msecs); }
+
+
+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
new file mode 100644
index 0000000000..efd4c34efa
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/gfp.h
@@ -0,0 +1,43 @@
+/*
+ * \brief Implementation of linux/gfp.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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
+#include
+
+
+struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)
+{
+ struct page *page = (struct page *)kzalloc(sizeof(struct page), 0);
+
+ size_t size = PAGE_SIZE << order;
+
+ page->addr = Lx::Malloc::dma().alloc(size, 12);
+
+ if (!page->addr) {
+ PERR("alloc_pages: %zu failed", size);
+ kfree(page);
+ return 0;
+ }
+
+ Lx::Addr_to_page_mapping::insert(page);
+
+ atomic_set(&page->_count, 1);
+
+ return page;
+}
+
+
+void get_page(struct page *page)
+{
+ atomic_inc(&page->_count);
+}
diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/addr_to_page_mapping.h b/repos/dde_linux/src/include/lx_emul/impl/internal/addr_to_page_mapping.h
new file mode 100644
index 0000000000..4d507eba83
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/addr_to_page_mapping.h
@@ -0,0 +1,78 @@
+/*
+ * \brief Address-to-page mapping helper
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \author Norman Feske
+ * \date 2014-10-10
+ */
+
+/*
+ * Copyright (C) 2014 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__ADDR_TO_PAGE_MAPPING_H_
+#define _LX_EMUL__IMPL__INTERNAL__ADDR_TO_PAGE_MAPPING_H_
+
+/* Linux emulation environment includes */
+#include
+#include
+
+namespace Lx { class Addr_to_page_mapping; }
+
+class Lx::Addr_to_page_mapping : public Lx::List::Element
+{
+ private:
+
+ unsigned long _addr { 0 };
+ struct page *_page { 0 };
+
+ static Genode::List *_list()
+ {
+ static Genode::List _l;
+ return &_l;
+ }
+
+ public:
+
+ Addr_to_page_mapping(unsigned long addr, struct page *page)
+ : _addr(addr), _page(page) { }
+
+ static void insert(struct page *page)
+ {
+ Addr_to_page_mapping *m = (Addr_to_page_mapping*)
+ Lx::Malloc::mem().alloc(sizeof (Addr_to_page_mapping));
+
+ m->_addr = (unsigned long)page->addr;
+ m->_page = page;
+
+ _list()->insert(m);
+ }
+
+ static void remove(struct page *page)
+ {
+ Addr_to_page_mapping *mp = 0;
+ for (Addr_to_page_mapping *m = _list()->first(); m; m = m->next())
+ if (m->_page == page)
+ mp = m;
+
+ if (mp) {
+ _list()->remove(mp);
+ Lx::Malloc::mem().free(mp);
+ }
+ }
+
+ static struct page* find_page(unsigned long addr)
+ {
+ for (Addr_to_page_mapping *m = _list()->first(); m; m = m->next())
+ if (m->_addr == addr)
+ return m->_page;
+
+ return 0;
+ }
+};
+
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__ADDR_TO_PAGE_MAPPING_H_ */
diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/debug.h b/repos/dde_linux/src/include/lx_emul/impl/internal/debug.h
new file mode 100644
index 0000000000..5248d6beaf
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/debug.h
@@ -0,0 +1,23 @@
+/*
+ * \brief Debug utilities
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \author Norman Feske
+ * \date 2014-10-10
+ */
+
+/*
+ * Copyright (C) 2014 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__DEBUG_H_
+#define _LX_EMUL__IMPL__INTERNAL__DEBUG_H_
+
+#ifndef PDBGV
+#define PDBGV(...) do { if (verbose) PDBG(__VA_ARGS__); } while (0)
+#endif
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__DEBUG_H_ */
diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/io_port.h b/repos/dde_linux/src/include/lx_emul/impl/internal/io_port.h
new file mode 100644
index 0000000000..2975dcd97c
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/io_port.h
@@ -0,0 +1,83 @@
+/*
+ * \brief I/O port access helper
+ * \author Sebastian Sumpf
+ * \author Norman Feske
+ * \date 2014-10-10
+ */
+
+/*
+ * Copyright (C) 2014 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__IO_PORT_H_
+#define _LX_EMUL__IMPL__INTERNAL__IO_PORT_H_
+
+/* Genode includes */
+#include
+#include
+
+namespace Lx { class Io_port; }
+
+class Lx::Io_port
+{
+ private:
+
+ unsigned _base = 0;
+ unsigned _size = 0;
+ Genode::Io_port_session_capability _cap;
+ Genode::Lazy_volatile_object _port;
+
+ bool _valid(unsigned port) {
+ return _cap.valid() && port >= _base && port < _base + _size; }
+
+ public:
+
+ ~Io_port()
+ {
+ if (_cap.valid())
+ _port.destruct();
+ }
+
+ void session(unsigned base, unsigned size, Genode::Io_port_session_capability cap)
+ {
+ _base = base;
+ _size = size;
+ _cap = cap;
+ _port.construct(_cap);
+ }
+
+ template
+ bool out(unsigned port, POD val)
+ {
+ if (!_valid(port))
+ return false;
+
+ switch (sizeof(POD)) {
+ case 1: _port->outb(port, val); break;
+ case 2: _port->outw(port, val); break;
+ case 4: _port->outl(port, val); break;
+ }
+
+ return true;
+ }
+
+ template
+ bool in(unsigned port, POD *val)
+ {
+ if (!_valid(port))
+ return false;;
+
+ switch (sizeof(POD)) {
+ case 1: *val = _port->inb(port); break;
+ case 2: *val = _port->inw(port); break;
+ case 4: *val = _port->inl(port); break;
+ }
+
+ return true;
+ }
+};
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__IO_PORT_H_ */
diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/list.h b/repos/dde_linux/src/include/lx_emul/impl/internal/list.h
new file mode 100644
index 0000000000..e01913ece1
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/list.h
@@ -0,0 +1,102 @@
+/*
+ * \brief Slightly improved list
+ * \author Christian Helmuth
+ * \date 2014-09-25
+ */
+
+/*
+ * Copyright (C) 2014 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__LIST_H_
+#define _LX_EMUL__IMPL__INTERNAL__LIST_H_
+
+#include
+
+
+namespace Lx {
+ template class List;
+ template class List_element;
+}
+
+template
+class Lx::List : private Genode::List
+{
+ private:
+
+ typedef Genode::List Base;
+
+ public:
+
+ using Base::Element;
+
+ void append(LT const *le)
+ {
+ LT *at = nullptr;
+
+ for (LT *l = first(); l; l = l->next())
+ at = l;
+
+ Base::insert(le, at);
+ }
+
+ void prepend(LT const *le)
+ {
+ Base::insert(le);
+ }
+
+ void insert_before(LT const *le, LT const *at)
+ {
+ if (at == first()) {
+ prepend(le);
+ return;
+ } else if (!at) {
+ append(le);
+ return;
+ }
+
+ for (LT *l = first(); l; l = l->next())
+ if (l->next() == at)
+ at = l;
+
+ Base::insert(le, at);
+ }
+
+
+ /****************************
+ ** Genode::List interface **
+ ****************************/
+
+ LT *first() { return Base::first(); }
+ LT const *first() const { return Base::first(); }
+
+ void insert(LT const *le, LT const *at = 0)
+ {
+ Base::insert(le, at);
+ }
+
+ void remove(LT const *le)
+ {
+ Base::remove(le);
+ }
+};
+
+
+template
+class Lx::List_element : public Lx::List >::Element
+{
+ private:
+
+ T *_object;
+
+ public:
+
+ List_element(T *object) : _object(object) { }
+
+ T *object() const { return _object; }
+};
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__LIST_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
new file mode 100644
index 0000000000..5d5bf576a6
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/malloc.h
@@ -0,0 +1,208 @@
+/*
+ * \brief Linux kernel memory allocator
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \author Norman Feske
+ * \date 2014-10-10
+ */
+
+/*
+ * Copyright (C) 2014 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__MALLOC_H_
+#define _LX_EMUL__IMPL__INTERNAL__MALLOC_H_
+
+#include
+#include
+
+namespace Lx { class Malloc; }
+
+
+class Lx::Malloc
+{
+ private:
+
+ enum {
+ SLAB_START_LOG2 = 3, /* 8 B */
+ SLAB_STOP_LOG2 = 16, /* 64 KiB */
+ NUM_SLABS = (SLAB_STOP_LOG2 - SLAB_START_LOG2) + 1,
+ };
+
+ typedef Genode::addr_t addr_t;
+ typedef Lx::Slab_alloc Slab_alloc;
+ typedef Lx::Slab_backend_alloc Slab_backend_alloc;
+
+ Slab_backend_alloc &_back_allocator;
+ Slab_alloc *_allocator[NUM_SLABS];
+ Genode::Cache_attribute _cached; /* cached or un-cached memory */
+ addr_t _start; /* VM region of this allocator */
+ addr_t _end;
+
+ /**
+ * Set 'value' at 'addr'
+ */
+ void _set_at(addr_t addr, addr_t value) { *((addr_t *)addr) = value; }
+
+ /**
+ * Retrieve slab index belonging to given address
+ */
+ unsigned _slab_index(Genode::addr_t **addr)
+ {
+ using namespace Genode;
+ /* get index */
+ addr_t index = *(*addr - 1);
+
+ /*
+ * If index large, we use aligned memory, retrieve beginning of slab entry
+ * and read index from there
+ */
+ if (index > 32) {
+ *addr = (addr_t *)*(*addr - 1);
+ index = *(*addr - 1);
+ }
+
+ return index;
+ }
+
+ /**
+ * Get the originally requested size of the allocation
+ */
+ size_t _get_orig_size(Genode::addr_t **addr)
+ {
+ using namespace Genode;
+
+ addr_t index = *(*addr - 1);
+ if (index > 32) {
+ *addr = (addr_t *) * (*addr - 1);
+ }
+
+ return *(*addr - 2);
+ }
+
+ public:
+
+ Malloc(Slab_backend_alloc &alloc, Genode::Cache_attribute cached)
+ :
+ _back_allocator(alloc), _cached(cached), _start(alloc.start()),
+ _end(alloc.end())
+ {
+ /* init slab allocators */
+ for (unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++)
+ _allocator[i - SLAB_START_LOG2] = new (Genode::env()->heap())
+ Slab_alloc(1U << i, alloc);
+ }
+
+ /**
+ * Alloc in slabs
+ */
+ void *alloc(Genode::size_t size, int align = 0, Genode::addr_t *phys = 0)
+ {
+ using namespace Genode;
+
+ /* save requested size */
+ size_t orig_size = size;
+ size += sizeof(addr_t);
+
+ /* += slab index + aligment size */
+ size += sizeof(addr_t) + (align > 2 ? (1 << align) : 0);
+
+ int msb = Genode::log2(size);
+
+ if (size > (1U << msb))
+ msb++;
+
+ if (size < (1U << SLAB_START_LOG2))
+ msb = SLAB_STOP_LOG2;
+
+ if (msb > SLAB_STOP_LOG2) {
+ // PERR("Slab too large %u reqested %zu cached %d", 1U << msb, size, _cached);
+ return 0;
+ }
+
+ addr_t addr = _allocator[msb - SLAB_START_LOG2]->alloc();
+ if (!addr) {
+ PERR("Failed to get slab for %u", 1 << msb);
+ return 0;
+ }
+
+ _set_at(addr, orig_size);
+ addr += sizeof(addr_t);
+
+ _set_at(addr, msb - SLAB_START_LOG2);
+ addr += sizeof(addr_t);
+
+ if (align > 2) {
+ /* save */
+ addr_t ptr = addr;
+ addr_t align_val = (1U << align);
+ addr_t align_mask = align_val - 1;
+ /* align */
+ addr = (addr + align_val) & ~align_mask;
+ /* write start address before aligned address */
+ _set_at(addr - sizeof(addr_t), ptr);
+ }
+
+ if (phys)
+ *phys = _back_allocator.phys_addr(addr);
+ return (addr_t *)addr;
+ }
+
+ void free(void const *a)
+ {
+ using namespace Genode;
+ addr_t *addr = (addr_t *)a;
+
+ /* XXX changes addr */
+ unsigned nr = _slab_index(&addr);
+ /* we need to decrease addr by 2, orig_size and index come first */
+ _allocator[nr]->free((void *)(addr - 2));
+ }
+
+ size_t size(void const *a)
+ {
+ using namespace Genode;
+ addr_t *addr = (addr_t *)a;
+
+ /* XXX changes addr */
+ return _get_orig_size(&addr);
+ }
+
+ Genode::addr_t phys_addr(void *a)
+ {
+ return _back_allocator.phys_addr((addr_t)a);
+ }
+
+ Genode::addr_t virt_addr(Genode::addr_t phys)
+ {
+ return _back_allocator.virt_addr(phys);
+ }
+
+ /**
+ * Belongs given address to this allocator
+ */
+ bool inside(addr_t const addr) const { return (addr > _start) && (addr <= _end); }
+
+ /**
+ * Cached memory allocator
+ */
+ static Malloc & mem()
+ {
+ static Malloc inst(Slab_backend_alloc::mem(), Genode::CACHED);
+ return inst;
+ }
+
+ /**
+ * DMA memory allocator
+ */
+ static Malloc & dma()
+ {
+ static Malloc inst(Slab_backend_alloc::dma(), Genode::UNCACHED);
+ return inst;
+ }
+};
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__MALLOC_H_ */
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
new file mode 100644
index 0000000000..3039d172a8
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/mapped_io_mem_range.h
@@ -0,0 +1,112 @@
+/*
+ * \brief Representation of a locally-mapped MMIO range
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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__MAPPED_IO_MEM_RANGE_H_
+#define _LX_EMUL__IMPL__INTERNAL__MAPPED_IO_MEM_RANGE_H_
+
+/* Genode includes */
+#include
+#include
+
+/* Linux emulation environment includes */
+#include
+
+namespace Lx {
+
+ class Mapped_io_mem_range;
+
+ void *ioremap(resource_size_t, unsigned long, Genode::Cache_attribute);
+}
+
+/**
+ * Representation of a locally-mapped MMIO range
+ *
+ * This class is supposed to be a private utility to support 'ioremap'.
+ */
+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;
+
+ 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::addr_t phys() const { return _phys; }
+ Genode::addr_t virt() const { return _virt; }
+
+ /**
+ * Return true if the mapped range contains the specified sub range
+ */
+ bool contains(Genode::addr_t phys, Genode::size_t size) const
+ {
+ return (phys >= _phys) && (phys + size - 1 <= _phys + _size - 1);
+ }
+};
+
+
+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)) {
+ 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);
+ return virt;
+ }
+ }
+
+ Io_mem_dataspace_capability ds_cap =
+ Lx::pci_dev_registry()->io_mem(phys_addr, cache_attribute, size);
+
+ 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);
+
+ ranges.insert(io_mem);
+
+ PLOG("ioremap: mapped phys 0x%lx (size %lx) to virt 0x%lx",
+ (long)phys_addr, (long)size, (long)io_mem->virt());
+
+ addr_t const sub_page_offset = phys_addr & 0xfff;
+ return (void *)(io_mem->virt() + sub_page_offset);
+}
+
+#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
new file mode 100644
index 0000000000..df2804dad5
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/pci_backend_alloc.h
@@ -0,0 +1,110 @@
+/*
+ * \brief Backend allocator for DMA-capable memory
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \author Norman Feske
+ * \date 2014-10-10
+ */
+
+/*
+ * Copyright (C) 2014 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__PCI_BACKEND_ALLOC_H_
+#define _LX_EMUL__IMPL__INTERNAL__PCI_BACKEND_ALLOC_H_
+
+/* Genode includes */
+#include
+#include
+
+/* Linux emulation environment includes */
+#include
+
+namespace Lx {
+
+ struct Memory_object_base;
+ struct Ram_object;
+ struct Dma_object;
+
+ extern Genode::Object_pool memory_pool;
+};
+
+
+struct Lx::Memory_object_base : Genode::Object_pool::Entry
+{
+ Memory_object_base(Genode::Ram_dataspace_capability cap)
+ : Genode::Object_pool::Entry(cap) {}
+ virtual ~Memory_object_base() {};
+
+ virtual void free() = 0;
+
+ Genode::Ram_dataspace_capability ram_cap()
+ {
+ using namespace Genode;
+ return reinterpret_cap_cast(cap());
+ }
+};
+
+
+struct Lx::Ram_object : Memory_object_base
+{
+ Ram_object(Genode::Ram_dataspace_capability cap)
+ : Memory_object_base(cap) {}
+
+ void free() { Genode::env()->ram_session()->free(ram_cap()); }
+};
+
+
+struct Lx::Dma_object : Memory_object_base
+{
+ Dma_object(Genode::Ram_dataspace_capability cap)
+ : Memory_object_base(cap) {}
+
+ void free() { Lx::pci()->free_dma_buffer(ram_cap()); }
+};
+
+
+Genode::Ram_dataspace_capability
+Lx::backend_alloc(Genode::addr_t size, Genode::Cache_attribute cached)
+{
+ using namespace Genode;
+
+ Memory_object_base *o;
+ Genode::Ram_dataspace_capability cap;
+ if (cached == 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);
+
+ cap = Lx::pci()->alloc_dma_buffer(size);
+ o = new (env()->heap()) Dma_object(cap);
+ }
+
+ memory_pool.insert(o);
+ return cap;
+}
+
+
+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;
+
+ o->free();
+ memory_pool.remove_locked(o);
+ destroy(env()->heap(), o);
+}
+
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__PCI_BACKEND_ALLOC_H_ */
+
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
new file mode 100644
index 0000000000..8d882b6ea2
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/pci_dev.h
@@ -0,0 +1,241 @@
+/*
+ * \brief Emulate 'pci_dev' structure
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \author Norman Feske
+ * \date 2014-10-10
+ */
+
+/*
+ * Copyright (C) 2014 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__PCI_DEV_H_
+#define _LX_EMUL__IMPL__INTERNAL__PCI_DEV_H_
+
+/* Genode includes */
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* Linux emulation environment includes */
+#include
+#include
+#include
+
+namespace Lx {
+
+ class Pci_dev;
+
+ /**
+ * Return singleton 'Platform::Connection'
+ *
+ * Implementation must be privided by the driver.
+ */
+ Platform::Connection *pci();
+
+ template
+ static inline void for_each_pci_device(FUNC const &func);
+}
+
+
+class Lx::Pci_dev : public pci_dev, public Lx::List::Element
+{
+ private:
+
+ bool const verbose = true;
+
+ Platform::Device_client _client;
+
+ Io_port _io_port;
+
+ /* offset used in PCI config space */
+ enum Pci_config { IRQ = 0x3c, REV = 0x8, CMD = 0x4,
+ STATUS = 0x4, CAP = 0x34 };
+ enum Pci_cap { CAP_LIST = 0x10, CAP_EXP = 0x10,
+ CAP_EXP_FLAGS = 0x2, CAP_EXP_DEVCAP = 0x4 };
+
+ template
+ Platform::Device::Access_size _access_size(T t)
+ {
+ switch (sizeof(T))
+ {
+ case 1:
+ return Platform::Device::ACCESS_8BIT;
+ case 2:
+ return Platform::Device::ACCESS_16BIT;
+ default:
+ return Platform::Device::ACCESS_32BIT;
+ }
+ }
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Pci_dev(Platform::Device_capability cap)
+ :
+ _client(cap)
+ {
+ using namespace Platform;
+
+ Genode::memset(static_cast(this), 0, sizeof(pci_dev));
+
+ this->vendor = _client.vendor_id();
+ this->device = _client.device_id();
+ this->class_ = _client.class_code();
+ this->revision = _client.config_read(REV, Device::ACCESS_8BIT);
+
+ /* dummy dma mask used to mark device as DMA capable */
+ this->dev._dma_mask_buf = ~(u64)0;
+ this->dev.dma_mask = &this->dev._dma_mask_buf;
+ this->dev.coherent_dma_mask = ~0;
+
+ /* read interrupt line */
+ this->irq = _client.config_read(IRQ, Device::ACCESS_8BIT);
+
+ /* hide ourselfs in bus structure */
+ this->bus = (struct pci_bus *)this;
+
+ /* setup resources */
+ bool io = false;
+ for (int i = 0; i < Device::NUM_RESOURCES; i++) {
+ Device::Resource res = _client.resource(i);
+ if (res.type() == Device::Resource::INVALID)
+ continue;
+
+ this->resource[i].start = res.base();
+ this->resource[i].end = res.base() + res.size() - 1;
+
+ unsigned flags = 0;
+ if (res.type() == Device::Resource::IO) flags |= IORESOURCE_IO;
+ if (res.type() == Device::Resource::MEMORY) flags |= IORESOURCE_MEM;
+ this->resource[i].flags = flags;
+
+ PDBGV("this=%p base: %x size: %x type: %u",
+ this, res.base(), res.size(), res.type());
+
+ /* request port I/O session */
+ if (res.type() == Device::Resource::IO) {
+ uint8_t const virt_bar = _client.phys_bar_to_virt(i);
+ _io_port.session(res.base(), res.size(), _client.io_port(virt_bar));
+ io = true;
+ PDBGV("I/O [%u-%u)",
+ res.base(), res.base() + res.size());
+ }
+
+ /* request I/O memory (write combined) */
+ if (res.type() == Device::Resource::MEMORY)
+ PDBGV("I/O memory [%x-%x)", res.base(),
+ res.base() + res.size());
+ }
+
+ /* enable bus master and io bits */
+ uint16_t cmd = _client.config_read(CMD, Device::ACCESS_16BIT);
+ cmd |= io ? 0x1 : 0;
+
+ /* enable bus master */
+ cmd |= 0x4;
+ _client.config_write(CMD, cmd, Device::ACCESS_16BIT);
+
+ /* get pci express capability */
+ this->pcie_cap = 0;
+ uint16_t status = _client.config_read(STATUS, Device::ACCESS_32BIT) >> 16;
+ if (status & CAP_LIST) {
+ uint8_t offset = _client.config_read(CAP, Device::ACCESS_8BIT);
+ while (offset != 0x00) {
+ uint8_t value = _client.config_read(offset, Device::ACCESS_8BIT);
+
+ if (value == CAP_EXP)
+ this->pcie_cap = offset;
+
+ offset = _client.config_read(offset + 1, Device::ACCESS_8BIT);
+ }
+ }
+
+ if (this->pcie_cap) {
+ uint16_t reg_val = _client.config_read(this->pcie_cap, Device::ACCESS_16BIT);
+ this->pcie_flags_reg = reg_val;
+ }
+ }
+
+ /**
+ * Read/write data from/to config space
+ */
+ template
+ void config_read(unsigned int devfn, T *val)
+ {
+ *val = _client.config_read(devfn, _access_size(*val));
+ }
+
+ template
+ void config_write(unsigned int devfn, T val)
+ {
+ _client.config_write(devfn, val, _access_size(val));
+ }
+
+ Platform::Device &client() { return _client; }
+
+ Io_port &io_port() { return _io_port; }
+};
+
+
+/**
+ * Call functor for each available physical PCI device
+ *
+ * The functor is called with the device capability as argument. If
+ * returns true if we can stop iterating. In this case, the device
+ * is expected to be acquired by the driver. All other devices are
+ * released at the platform driver.
+ */
+template
+void Lx::for_each_pci_device(FUNC const &func)
+{
+ /*
+ * Functor that is called if the platform driver throws a
+ * 'Quota_exceeded' exception.
+ */
+ auto handler = [&] () {
+ Genode::env()->parent()->upgrade(Lx::pci()->cap(),
+ "ram_quota=4096"); };
+
+ /*
+ * Obtain first device, the operation may exceed the session quota.
+ * So we use the 'retry' mechanism.
+ */
+ Platform::Device_capability cap;
+ auto attempt = [&] () { cap = Lx::pci()->first_device(); };
+ Genode::retry(attempt, handler);
+
+ /*
+ * Iterate over the devices of the platform session.
+ */
+ while (cap.valid()) {
+
+ /*
+ * Call functor, stop iterating depending on its return value.
+ */
+ if (func(cap))
+ break;
+
+ /*
+ * Release current device and try next one. Upgrade session
+ * quota on demand.
+ */
+ auto attempt = [&] () {
+ Platform::Device_capability next_cap = pci()->next_device(cap);
+ Lx::pci()->release_device(cap);
+ cap = next_cap;
+ };
+ Genode::retry(attempt, handler);
+ }
+}
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__PCI_DEV_H_ */
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
new file mode 100644
index 0000000000..12d23fa19d
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/pci_dev_registry.h
@@ -0,0 +1,111 @@
+/*
+ * \brief Registry of PCI devices
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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__PCI_DEV_REGISTRY_H_
+#define _LX_EMUL__IMPL__INTERNAL__PCI_DEV_REGISTRY_H_
+
+/* Linux emulation environment includes */
+#include
+
+namespace Lx {
+
+ class Pci_dev_registry;
+
+ /**
+ * Return singleton 'Pci_dev_registry' object
+ *
+ * Implementation must be provided by the driver.
+ */
+ Pci_dev_registry *pci_dev_registry();
+}
+
+class Lx::Pci_dev_registry
+{
+ private:
+
+ List _devs;
+
+ public:
+
+ void insert(Pci_dev *pci_dev)
+ {
+ PDBG("insert pci_dev %p", pci_dev);
+ _devs.insert(pci_dev);
+ }
+
+ Genode::Io_mem_dataspace_capability io_mem(resource_size_t phys,
+ Genode::Cache_attribute cache_attribute,
+ Genode::size_t size)
+ {
+ enum { PCI_ROM_RESOURCE = 6 };
+
+ for (Pci_dev *d = _devs.first(); d; d = d->next()) {
+
+ unsigned bar = 0;
+ for (; bar < PCI_ROM_RESOURCE; bar++) {
+ if ((pci_resource_flags(d, bar) & IORESOURCE_MEM) &&
+ (pci_resource_start(d, bar) == phys))
+ 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);
+
+ Genode::Io_mem_session_capability io_mem_cap =
+ device.io_mem(resource_id, cache_attribute, offset, size);
+
+ return Genode::Io_mem_session_client(io_mem_cap).dataspace();
+ }
+
+ PERR("Device using i/o memory of address %zx is unknown", phys);
+ return Genode::Io_mem_dataspace_capability();
+ }
+
+ 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;
+ if (d->io_port().in(port, &value))
+ return value;
+ }
+
+ PWRN("I/O port(%u) read failed", port);
+ return (T)~0;
+ }
+
+ 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))
+ return;
+
+ PWRN("I/O port(%u) write failed", port);
+ }
+};
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__PCI_DEV_REGISTRY_H_ */
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
new file mode 100644
index 0000000000..65358dedb5
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/scheduler.h
@@ -0,0 +1,230 @@
+/*
+ * \brief Scheduler for executing Lx::Task objects
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \author Norman Feske
+ * \date 2014-10-10
+ */
+
+/*
+ * Copyright (C) 2014 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__SCHEDULER_H_
+#define _LX_EMUL__IMPL__INTERNAL__SCHEDULER_H_
+
+/* Genode includes */
+#include
+#include
+#include
+#include
+#include
+
+/* Linux emulation environment includes */
+#include
+#include
+
+namespace Lx {
+
+ class Scheduler;
+
+ /**
+ * Return singleton instance of the scheduler
+ *
+ * Implementation must be provided by the driver.
+ */
+ Scheduler &scheduler();
+
+ /**
+ * Called each time when a scheduling decision is taken
+ *
+ * Must be provided by the compilation unit that includes 'scheduler.h',
+ * e.g., by also including 'timer.h'.
+ */
+ static inline void timer_update_jiffies();
+}
+
+
+class Lx::Scheduler
+{
+ private:
+
+ bool verbose = true;
+
+ Lx::List _present_list;
+ Genode::Lock _present_list_mutex;
+
+ Task *_current = nullptr; /* currently scheduled task */
+
+ bool _run_task(Task *);
+
+ /*
+ * Support for logging
+ */
+
+ static inline char const *_ansi_esc_reset() { return "\033[00m"; }
+ static inline char const *_ansi_esc_black() { return "\033[30m"; }
+ static inline char const *_ansi_esc_red() { return "\033[31m"; }
+ static inline char const *_ansi_esc_yellow() { return "\033[33m"; }
+
+ static inline char const *_state_color(Lx::Task::State state)
+ {
+ switch (state) {
+ case Lx::Task::STATE_INIT: return _ansi_esc_reset();
+ case Lx::Task::STATE_RUNNING: return _ansi_esc_red();
+ case Lx::Task::STATE_BLOCKED: return _ansi_esc_yellow();
+ case Lx::Task::STATE_MUTEX_BLOCKED: return _ansi_esc_yellow();
+ case Lx::Task::STATE_WAIT_BLOCKED: return _ansi_esc_yellow();
+ }
+
+ return _ansi_esc_black();
+ }
+
+ struct Logger : Genode::Thread<0x4000>
+ {
+ Timer::Connection _timer;
+ Lx::Scheduler &_scheduler;
+ unsigned const _interval;
+
+ Logger(Lx::Scheduler &scheduler, unsigned interval_seconds)
+ :
+ Genode::Thread<0x4000>("logger"),
+ _scheduler(scheduler), _interval(interval_seconds)
+ {
+ start();
+ }
+
+ void entry()
+ {
+ PWRN("Scheduler::Logger is up");
+ _timer.msleep(1000 * _interval);
+ while (true) {
+ _scheduler.log_state("LOGGER");
+ _timer.msleep(2000);
+ }
+ }
+ };
+
+ public:
+
+ Scheduler()
+ {
+ if (verbose)
+ new (Genode::env()->heap()) Logger(*this, 10);
+ }
+
+ /**
+ * Return currently scheduled task
+ */
+ Task *current()
+ {
+ if (!_current) {
+ PERR("BUG: _current is zero!");
+ Genode::sleep_forever();
+ }
+
+ return _current;
+ }
+
+ /**
+ * Add new task to the present list
+ */
+ void add(Task *task)
+ {
+ Lx::Task *p = _present_list.first();
+ for ( ; p; p = p->next()) {
+ if (p->priority() <= task->priority()) {
+ _present_list.insert_before(task, p);
+ break;
+ }
+ }
+ if (!p)
+ _present_list.append(task);
+ }
+
+ /**
+ * Schedule all present tasks
+ *
+ * Returns if no task is runnable.
+ */
+ void schedule()
+ {
+ bool at_least_one = false;
+
+ /*
+ * Iterate over all tasks and run first runnable.
+ *
+ * (1) If one runnable tasks was run start over from beginning of
+ * list.
+ *
+ * (2) If no task is runnable quit scheduling (break endless
+ * loop).
+ */
+ while (true) {
+ /* update jiffies before running task */
+ Lx::timer_update_jiffies();
+
+ bool was_run = false;
+ for (Task *t = _present_list.first(); t; t = t->next()) {
+ /* update current before running task */
+ _current = t;
+
+ if ((was_run = t->run())) {
+ at_least_one = true;
+ break;
+ }
+ }
+ if (!was_run)
+ break;
+ }
+
+ if (!at_least_one) {
+ PWRN("schedule() called without runnable tasks");
+ log_state("SCHEDULE");
+ }
+
+ /* clear current as no task is running */
+ _current = nullptr;
+ }
+
+ /**
+ * Log current state of tasks in present list (debug)
+ *
+ * Log lines are prefixed with 'prefix'.
+ */
+ void log_state(char const *prefix)
+ {
+ unsigned i;
+ Lx::Task *t;
+ for (i = 0, t = _present_list.first(); t; t = t->next(), ++i) {
+ Genode::printf("%s [%u] prio: %u state: %s%u%s %s\n",
+ prefix, i, t->priority(), _state_color(t->state()),
+ t->state(), _ansi_esc_reset(), t->name());
+ }
+ }
+};
+
+
+Lx::Task::Task(void (*func)(void*), void *arg, char const *name,
+ Priority priority, Scheduler &scheduler)
+:
+ _priority(priority), _scheduler(scheduler),
+ _func(func), _arg(arg), _name(name)
+{
+ scheduler.add(this);
+
+ PDBGV("name: '%s' func: %p arg: %p prio: %u t: %p", name, func, arg, priority, this);
+}
+
+
+void Lx::Task::_deinit()
+{
+ if (_stack)
+ Genode::Thread_base::myself()->free_secondary_stack(_stack);
+}
+
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__SCHEDULER_H_ */
diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/slab_alloc.h b/repos/dde_linux/src/include/lx_emul/impl/internal/slab_alloc.h
new file mode 100644
index 0000000000..7aaa1ccc75
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/slab_alloc.h
@@ -0,0 +1,58 @@
+/*
+ * \brief Slab allocator using our back-end allocator
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \author Norman Feske
+ * \date 2014-10-10
+ */
+
+/*
+ * Copyright (C) 2014 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__SLAB_ALLOC_H_
+#define _LX_EMUL__IMPL__INTERNAL__SLAB_ALLOC_H_
+
+/* Genode includes */
+#include
+
+/* Linux emulation environment includes */
+#include
+
+namespace Lx { class Slab_alloc; }
+
+class Lx::Slab_alloc : public Genode::Slab
+{
+ private:
+
+ /*
+ * Each slab block in the slab contains about 8 objects (slab entries)
+ * as proposed in the paper by Bonwick and block sizes are multiples of
+ * page size.
+ */
+ static size_t _calculate_block_size(size_t object_size)
+ {
+ size_t block_size = 8 * (object_size + sizeof(Genode::Slab_entry))
+ + sizeof(Genode::Slab_block);
+ return Genode::align_addr(block_size, 12);
+ }
+
+ public:
+
+ Slab_alloc(size_t object_size, Slab_backend_alloc &allocator)
+ : Slab(object_size, _calculate_block_size(object_size), 0, &allocator) { }
+
+ /**
+ * Convenience slabe-entry allocation
+ */
+ Genode::addr_t alloc()
+ {
+ Genode::addr_t result;
+ return (Slab::alloc(slab_size(), (void **)&result) ? result : 0);
+ }
+};
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__SLAB_ALLOC_H_ */
diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/slab_backend_alloc.h b/repos/dde_linux/src/include/lx_emul/impl/internal/slab_backend_alloc.h
new file mode 100644
index 0000000000..f0c5450ff3
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/slab_backend_alloc.h
@@ -0,0 +1,173 @@
+
+/*
+ * \brief Back-end allocator for Genode's slab allocator
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \author Norman Feske
+ * \date 2014-10-10
+ */
+
+/*
+ * Copyright (C) 2014 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__SLAB_BACKEND_ALLOC_H_
+#define _LX_EMUL__IMPL__INTERNAL__SLAB_BACKEND_ALLOC_H_
+
+/* Genode includes */
+#include
+#include
+#include
+#include
+
+namespace Lx {
+
+ Genode::Ram_dataspace_capability
+ backend_alloc(Genode::addr_t size, Genode::Cache_attribute cached);
+
+ void backend_free(Genode::Ram_dataspace_capability cap);
+ class Slab_backend_alloc;
+}
+
+class Lx::Slab_backend_alloc : public Genode::Allocator,
+ public Genode::Rm_connection
+{
+ private:
+
+ typedef Genode::addr_t addr_t;
+
+ enum {
+ VM_SIZE = 24 * 1024 * 1024, /* size of VM region to reserve */
+ BLOCK_SIZE = 1024 * 1024, /* 1 MiB */
+ ELEMENTS = VM_SIZE / BLOCK_SIZE, /* MAX number of dataspaces in VM */
+ };
+
+ addr_t _base; /* virt. base address */
+ Genode::Cache_attribute _cached; /* non-/cached RAM */
+ Genode::Ram_dataspace_capability _ds_cap[ELEMENTS]; /* dataspaces to put in VM */
+ addr_t _ds_phys[ELEMENTS]; /* physical bases of dataspaces */
+ int _index; /* current index in ds_cap */
+ Genode::Allocator_avl _range; /* manage allocations */
+
+ bool _alloc_block()
+ {
+ if (_index == ELEMENTS) {
+ PERR("Slab-backend exhausted!");
+ return false;
+ }
+
+ try {
+ _ds_cap[_index] = Lx::backend_alloc(BLOCK_SIZE, _cached);
+ /* attach at index * BLOCK_SIZE */
+ Rm_connection::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0);
+
+ /* lookup phys. address */
+ _ds_phys[_index] = Genode::Dataspace_client(_ds_cap[_index]).phys_addr();
+ } catch (...) { return false; }
+
+ /* return base + offset in VM area */
+ addr_t block_base = _base + (_index * BLOCK_SIZE);
+ ++_index;
+
+ _range.add_range(block_base, BLOCK_SIZE);
+ return true;
+ }
+
+ public:
+
+ Slab_backend_alloc(Genode::Cache_attribute cached)
+ :
+ Rm_connection(0, VM_SIZE),
+ _cached(cached), _index(0), _range(Genode::env()->heap())
+ {
+ /* reserver attach us, anywere */
+ _base = Genode::env()->rm_session()->attach(dataspace());
+ }
+
+ /**
+ * Allocate
+ */
+ bool alloc(size_t size, void **out_addr) override
+ {
+ bool done = _range.alloc(size, out_addr);
+
+ if (done)
+ return done;
+
+ done = _alloc_block();
+ if (!done) {
+ PERR("Backend allocator exhausted\n");
+ return false;
+ }
+
+ return _range.alloc(size, out_addr);
+ }
+
+ void free(void *addr, size_t /* size */) override { }
+ size_t overhead(size_t size) const override { return 0; }
+ bool need_size_for_free() const override { return false; }
+
+ /**
+ * Return phys address for given virtual addr.
+ */
+ addr_t phys_addr(addr_t addr)
+ {
+ if (addr < _base || addr >= (_base + VM_SIZE))
+ return ~0UL;
+
+ int index = (addr - _base) / BLOCK_SIZE;
+
+ /* physical base of dataspace */
+ addr_t phys = _ds_phys[index];
+
+ if (!phys)
+ return ~0UL;
+
+ /* add offset */
+ phys += (addr - _base - (index * BLOCK_SIZE));
+ return phys;
+ }
+
+ /**
+ * Translate given physical address to virtual address
+ *
+ * \return virtual address, or 0 if no translation exists
+ */
+ addr_t virt_addr(addr_t phys)
+ {
+ for (unsigned i = 0; i < ELEMENTS; i++) {
+ if (_ds_cap[i].valid() &&
+ phys >= _ds_phys[i] && phys < _ds_phys[i] + BLOCK_SIZE)
+ return _base + i*BLOCK_SIZE + phys - _ds_phys[i];
+ }
+
+ PWRN("virt_addr(0x%lx) - no translation", phys);
+ return 0;
+ }
+
+ addr_t start() const { return _base; }
+ addr_t end() const { return _base + VM_SIZE - 1; }
+
+ /**
+ * Cached memory backend allocator
+ */
+ static Slab_backend_alloc & mem()
+ {
+ static Slab_backend_alloc inst(Genode::CACHED);
+ return inst;
+ }
+
+ /**
+ * DMA memory backend allocator
+ */
+ static Slab_backend_alloc & dma()
+ {
+ static Slab_backend_alloc inst(Genode::UNCACHED);
+ return inst;
+ }
+};
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__SLAB_BACKEND_ALLOC_H_ */
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
new file mode 100644
index 0000000000..bcac85d43b
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/task.h
@@ -0,0 +1,255 @@
+/*
+ * \brief Lx::Task represents a cooperatively scheduled thread of control
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \author Norman Feske
+ * \date 2014-10-10
+ */
+
+/*
+ * Copyright (C) 2014 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__TASK_H_
+#define _LX_EMUL__IMPL__INTERNAL__TASK_H_
+
+/* libc includes */
+#include
+
+/* Genode includes */
+#include
+
+/* Linux emulation environment includes */
+#include
+#include
+
+namespace Lx {
+
+ class Scheduler;
+ class Task;
+}
+
+/**
+ * Allows pseudo-parallel execution of functions
+ */
+class Lx::Task : public Lx::List::Element
+{
+ public:
+
+ /**
+ * TODO generalize - higher is more important
+ */
+ enum Priority { PRIORITY_0, PRIORITY_1, PRIORITY_2, PRIORITY_3 };
+
+ /**
+ * Runtime state
+ *
+ * INIT
+ * |
+ * [run]
+ * v
+ * BLOCKED <--[block]--- RUNNING ---[mutex_block]--> MUTEX_BLOCKED
+ * --[unblock]-> <-[mutex_unblock]--
+ *
+ * Transitions between BLOCKED and MUTEX_BLOCKED are not possible.
+ */
+ enum State { STATE_INIT, STATE_RUNNING, STATE_BLOCKED, STATE_MUTEX_BLOCKED, STATE_WAIT_BLOCKED };
+
+ /**
+ * List element type
+ */
+ typedef Lx::List_element List_element;
+
+ /**
+ * List type
+ */
+ typedef Lx::List List;
+
+ private:
+
+ bool verbose = true;
+
+ State _state = STATE_INIT;
+
+ /* sub-classes may overwrite the runnable condition */
+ virtual bool _runnable() const
+ {
+ switch (_state) {
+ case STATE_INIT: return true;
+ case STATE_RUNNING: return true;
+ case STATE_BLOCKED: return false;
+ case STATE_MUTEX_BLOCKED: return false;
+ case STATE_WAIT_BLOCKED: return false;
+ }
+
+ PERR("state %d not handled by switch", _state);
+ Genode::sleep_forever();
+ }
+
+ void *_stack = nullptr; /* stack pointer */
+ jmp_buf _env; /* execution state */
+ jmp_buf _saved_env; /* saved state of thread calling run() */
+
+ Priority _priority;
+ Scheduler &_scheduler; /* scheduler this task is attached to */
+
+ void (*_func)(void *); /* function to call*/
+ void *_arg; /* argument for function */
+ char const *_name; /* name of task */
+
+ List_element _mutex_le { this }; /* list element for mutex_blocked state */
+
+ List *_wait_list { 0 };
+ List_element _wait_le { this };
+ bool _wait_le_enqueued { false };
+
+ inline void _deinit();
+
+ public:
+
+ inline Task(void (*func)(void*), void *arg, char const *name,
+ Priority priority, Scheduler &scheduler);
+
+ virtual ~Task() { _deinit(); }
+
+ State state() const { return _state; }
+ Priority priority() const { return _priority; }
+
+ void wait_enqueue(List *list)
+ {
+ if (_wait_le_enqueued) {
+ PERR("%p already queued in %p", this, _wait_list);
+ Genode::sleep_forever();
+ }
+
+ _wait_le_enqueued = true;
+ _wait_list = list;
+ _wait_list->append(&_wait_le);
+ }
+
+ void wait_dequeue(List *list)
+ {
+ if (!_wait_le_enqueued) {
+ PERR("%p not queued", this);
+ Genode::sleep_forever();
+ }
+
+ if (_wait_list != list) {
+ PERR("especially not in list %p", list);
+ Genode::sleep_forever();
+ }
+
+ _wait_list->remove(&_wait_le);
+ _wait_list = 0;
+ _wait_le_enqueued = false;
+ }
+
+ /*******************************
+ ** Runtime state transitions **
+ *******************************/
+
+ void block()
+ {
+ if (_state == STATE_RUNNING) {
+ _state = STATE_BLOCKED;
+ }
+ }
+
+ void unblock()
+ {
+ if (_state == STATE_BLOCKED) {
+ _state = STATE_RUNNING;
+ }
+ }
+
+ void mutex_block(List *list)
+ {
+ if (_state == STATE_RUNNING) {
+ _state = STATE_MUTEX_BLOCKED;
+ list->append(&_mutex_le);
+ }
+ }
+
+ void mutex_unblock(List *list)
+ {
+ if (_state == STATE_MUTEX_BLOCKED) {
+ _state = STATE_RUNNING;
+ list->remove(&_mutex_le);
+ }
+ }
+
+ /**
+ * Run task until next preemption point
+ *
+ * \return true if run, false if not runnable
+ */
+ bool run()
+ {
+ if (!_runnable())
+ return false;
+
+ /*
+ * Save the execution environment. The scheduled task returns to this point
+ * after execution, i.e., at the next preemption point.
+ */
+ if (_setjmp(_saved_env))
+ return true;
+
+ if (_state == STATE_INIT) {
+ /* setup execution environment and call task's function */
+ _state = STATE_RUNNING;
+ Genode::Thread_base *th = Genode::Thread_base::myself();
+
+ enum { STACK_SIZE = 32 * 1024 }; /* FIXME make stack size configurable */
+ _stack = th->alloc_secondary_stack(_name, STACK_SIZE);
+
+ /* switch stack and call '_func(_arg)' */
+ arch_execute(_stack, (void *)_func, _arg);
+ } else {
+ /* restore execution environment */
+ _longjmp(_env, 1);
+ }
+
+ /* never reached */
+ PERR("Unexpected return of Task");
+ Genode::sleep_forever();
+ }
+
+ /**
+ * Request scheduling (of other tasks)
+ *
+ * Note, this task may not be blocked when calling schedule() depending
+ * on the use case.
+ */
+ void schedule()
+ {
+ /*
+ * Save the execution environment. The task will resume from here on next
+ * schedule.
+ */
+ if (_setjmp(_env))
+ return;
+
+ /* return to thread calling run() */
+ _longjmp(_saved_env, 1);
+ }
+
+ /**
+ * Shortcut to enter blocking state and request scheduling
+ */
+ void block_and_schedule()
+ {
+ block();
+ schedule();
+ }
+
+ /**
+ * Return the name of the task (mainly for debugging purposes)
+ */
+ char const *name() { return _name; }
+};
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__TASK_H_ */
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
new file mode 100644
index 0000000000..6ea712168f
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/internal/timer.h
@@ -0,0 +1,313 @@
+/*
+ * \brief Timer
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \author Norman Feske
+ * \date 2014-10-10
+ */
+
+/*
+ * Copyright (C) 2014 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__TIMER_H_
+#define _LX_EMUL__IMPL__INTERNAL__TIMER_H_
+
+/* Genode includes */
+#include
+#include
+#include
+
+/* Linux emulation environment includes */
+#include
+
+namespace Lx {
+
+ class Timer;
+
+ /**
+ * Return singleton instance of timer
+ *
+ * \param ep entrypoint used handle timeout signals,
+ * to be specified at the first call of the function,
+ * which implicitly initializes the timer
+ * \param jiffies_ptr pointer to jiffies counter to be periodically
+ * updated
+ */
+ Timer &timer(Server::Entrypoint *ep = nullptr,
+ unsigned long *jiffies_ptr = nullptr);
+
+ /**
+ * Blue-print implementation of 'timer' function
+ */
+ static inline Timer &_timer_impl(Server::Entrypoint *ep,
+ unsigned long *jiffies_ptr);
+
+ static inline void timer_update_jiffies();
+
+ static inline void run_timer(void *);
+}
+
+
+class Lx::Timer
+{
+ public:
+
+ /**
+ * Context encapsulates a regular linux timer_list
+ */
+ struct Context : public Lx::List::Element
+ {
+ enum { INVALID_TIMEOUT = ~0UL };
+
+ struct timer_list *timer;
+ bool pending { false };
+ unsigned long timeout { INVALID_TIMEOUT }; /* absolute in jiffies */
+ bool programmed { false };
+
+ Context(struct timer_list *timer) : timer(timer) { }
+ };
+
+ private:
+
+
+ unsigned long &_jiffies;
+ ::Timer::Connection _timer_conn;
+ Lx::List _list;
+ Lx::Task _timer_task;
+ Genode::Signal_rpc_member _dispatcher;
+ Genode::Tslab _timer_alloc;
+
+ /**
+ * Lookup local timer
+ */
+ Context *_find_context(struct timer_list const *timer)
+ {
+ for (Context *c = _list.first(); c; c = c->next())
+ if (c->timer == timer)
+ return c;
+
+ return 0;
+ }
+
+ /**
+ * Program the first timer in the list
+ *
+ * The first timer is programmed if the 'programmed' flag was not set
+ * before. The second timer is flagged as not programmed as
+ * 'Timer::trigger_once' invalidates former registered one-shot
+ * timeouts.
+ */
+ void _program_first_timer()
+ {
+ Context *ctx = _list.first();
+ if (!ctx)
+ return;
+
+ if (ctx->programmed)
+ return;
+
+ /* calculate relative microseconds for trigger */
+ unsigned long us = ctx->timeout > _jiffies ?
+ jiffies_to_msecs(ctx->timeout - _jiffies) * 1000 : 0;
+ _timer_conn.trigger_once(us);
+
+ ctx->programmed = true;
+
+ /* possibly programmed successor must be reprogrammed later */
+ if (Context *next = ctx->next())
+ next->programmed = false;
+ }
+
+ /**
+ * Schedule timer
+ *
+ * Add the context to the scheduling list depending on its timeout
+ * and reprogram the first timer.
+ */
+ void _schedule_timer(Context *ctx, unsigned long expires)
+ {
+ _list.remove(ctx);
+
+ ctx->timeout = expires;
+ ctx->pending = true;
+ ctx->programmed = false;
+ /*
+ * Also write the timeout value to the expires field in
+ * struct timer_list because the wireless stack checks
+ * it directly.
+ */
+ ctx->timer->expires = expires;
+
+ Context *c;
+ for (c = _list.first(); c; c = c->next())
+ if (ctx->timeout <= c->timeout)
+ break;
+ _list.insert_before(ctx, c);
+
+ _program_first_timer();
+ }
+
+ /**
+ * Handle trigger_once signal
+ */
+ void _handle(unsigned)
+ {
+ _timer_task.unblock();
+
+ Lx::scheduler().schedule();
+ }
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Timer(Server::Entrypoint &ep, unsigned long &jiffies)
+ :
+ _jiffies(jiffies),
+ _timer_task(run_timer, nullptr, "timer", Lx::Task::PRIORITY_2,
+ Lx::scheduler()),
+ _dispatcher(ep, *this, &Lx::Timer::_handle),
+ _timer_alloc(Genode::env()->heap())
+ {
+ _timer_conn.sigh(_dispatcher);
+ }
+
+ /**
+ * Add new linux timer
+ */
+ void add(struct timer_list *timer)
+ {
+ Context *t = new (&_timer_alloc) Context(timer);
+ _list.append(t);
+ }
+
+ /**
+ * Delete linux timer
+ */
+ int del(struct timer_list *timer)
+ {
+ Context *ctx = _find_context(timer);
+
+ /**
+ * If the timer expired it was already cleaned up after its
+ * execution.
+ */
+ if (!ctx)
+ return 0;
+
+ int rv = ctx->timeout != Context::INVALID_TIMEOUT ? 1 : 0;
+
+ _list.remove(ctx);
+ destroy(&_timer_alloc, ctx);
+
+ return rv;
+ }
+
+ /**
+ * Initial scheduling of linux timer
+ */
+ int schedule(struct timer_list *timer, unsigned long expires)
+ {
+ Context *ctx = _find_context(timer);
+ if (!ctx) {
+ PERR("schedule unknown timer %p", timer);
+ return -1; /* XXX better use 0 as rv? */
+ }
+
+ /*
+ * If timer was already active return 1, otherwise 0. The return
+ * value is needed by mod_timer().
+ */
+ int rv = ctx->timeout != Context::INVALID_TIMEOUT ? 1 : 0;
+
+ _schedule_timer(ctx, expires);
+
+ return rv;
+ }
+
+ /**
+ * Schedule next linux timer
+ */
+ void schedule_next() { _program_first_timer(); }
+
+ /**
+ * Check if the timer is currently pending
+ */
+ bool pending(struct timer_list const *timer)
+ {
+ Context *ctx = _find_context(timer);
+ if (!ctx) {
+ return false;
+ }
+
+ return ctx->pending;
+ }
+
+ Context *find(struct timer_list const *timer) {
+ return _find_context(timer); }
+
+ /**
+ * Update jiffie counter
+ */
+ void update_jiffies()
+ {
+ _jiffies = msecs_to_jiffies(_timer_conn.elapsed_ms());
+ }
+
+ /**
+ * Get first timer context
+ */
+ Context* first() { return _list.first(); }
+
+ unsigned long jiffies() const { return _jiffies; }
+};
+
+
+void Lx::timer_update_jiffies()
+{
+ timer().update_jiffies();
+}
+
+
+void Lx::run_timer(void *)
+{
+ Timer &t = timer();
+
+ while (1) {
+ Lx::scheduler().current()->block_and_schedule();
+
+ while (Lx::Timer::Context *ctx = t.first()) {
+ if (ctx->timeout > t.jiffies())
+ break;
+
+ ctx->timer->function(ctx->timer->data);
+ t.del(ctx->timer);
+ }
+
+ t.schedule_next();
+ }
+}
+
+
+Lx::Timer &Lx::_timer_impl(Server::Entrypoint *ep, unsigned long *jiffies_ptr)
+{
+ static bool initialized = false;
+
+ if (!initialized && !ep) {
+ PERR("attempt to use Lx::Timer before its construction");
+ class Lx_timer_not_constructed { };
+ throw Lx_timer_not_constructed();
+ }
+
+ static Lx::Timer inst(*ep, *jiffies_ptr);
+ initialized = true;
+ return inst;
+}
+
+
+#endif /* _LX_EMUL__IMPL__INTERNAL__TIMER_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
new file mode 100644
index 0000000000..3ace39c8dc
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/io.h
@@ -0,0 +1,40 @@
+/*
+ * \brief Implementation of linux/io.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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
+#include
+
+
+void *ioremap(resource_size_t phys_addr, unsigned long size)
+{
+ return Lx::ioremap(phys_addr, size, Genode::UNCACHED);
+}
+
+
+void *ioremap_wc(resource_size_t phys_addr, unsigned long size)
+{
+ return Lx::ioremap(phys_addr, size, Genode::WRITE_COMBINED);
+}
+
+
+/**********************
+ ** asm-generic/io.h **
+ **********************/
+
+void outb(u8 value, u32 port) { Lx::pci_dev_registry()->io_write (port, value); }
+void outw(u16 value, u32 port) { Lx::pci_dev_registry()->io_write(port, value); }
+void outl(u32 value, u32 port) { Lx::pci_dev_registry()->io_write(port, value); }
+
+u8 inb(u32 port) { return Lx::pci_dev_registry()->io_read (port); }
+u16 inw(u32 port) { return Lx::pci_dev_registry()->io_read(port); }
+u32 inl(u32 port) { return Lx::pci_dev_registry()->io_read(port); }
diff --git a/repos/dde_linux/src/include/lx_emul/impl/kernel.h b/repos/dde_linux/src/include/lx_emul/impl/kernel.h
new file mode 100644
index 0000000000..3dbbe1d121
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/kernel.h
@@ -0,0 +1,42 @@
+/*
+ * \brief Implementation of linux/kernel.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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.
+ */
+
+/* Genode includes */
+#include
+
+
+int sprintf(char *str, const char *format, ...)
+{
+ enum { BUFFER_LEN = 128 };
+ va_list list;
+
+ va_start(list, format);
+ Genode::String_console sc(str, BUFFER_LEN);
+ sc.vprintf(format, list);
+ va_end(list);
+
+ return sc.len();
+}
+
+
+int snprintf(char *buf, size_t size, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ Genode::String_console sc(buf, size);
+ sc.vprintf(fmt, args);
+ va_end(args);
+
+ return sc.len();
+}
diff --git a/repos/dde_linux/src/include/lx_emul/impl/mutex.h b/repos/dde_linux/src/include/lx_emul/impl/mutex.h
new file mode 100644
index 0000000000..bb188853a7
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/mutex.h
@@ -0,0 +1,104 @@
+/*
+ * \brief Implementation of linux/mutex.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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
+
+
+enum { MUTEX_UNLOCKED = 1, MUTEX_LOCKED = 0, MUTEX_WAITERS = -1 };
+
+void mutex_init(struct mutex *m)
+{
+ static unsigned id = 0;
+
+ m->state = MUTEX_UNLOCKED;
+ m->holder = nullptr;
+ m->waiters = new (Genode::env()->heap()) Lx::Task::List;
+ m->id = ++id;
+}
+
+
+void mutex_destroy(struct mutex *m)
+{
+ /* FIXME potentially blocked tasks are not unblocked */
+
+ Genode::destroy(Genode::env()->heap(), static_cast(m->waiters));
+
+ m->holder = nullptr;
+ m->waiters = nullptr;
+ m->id = 0;
+}
+
+
+void mutex_lock(struct mutex *m)
+{
+ while (1) {
+ if (m->state == MUTEX_UNLOCKED) {
+ m->state = MUTEX_LOCKED;
+ m->holder = Lx::scheduler().current();
+
+ break;
+ }
+
+ Lx::Task *t = reinterpret_cast(m->holder);
+
+ if (t == Lx::scheduler().current()) {
+ PERR("Bug: mutex does not support recursive locking");
+ Genode::sleep_forever();
+ }
+
+ /* notice that a task waits for the mutex to be released */
+ m->state = MUTEX_WAITERS;
+
+ /* block until the mutex is released (and retry then) */
+ Lx::scheduler().current()->mutex_block(static_cast(m->waiters));
+ Lx::scheduler().current()->schedule();
+ }
+}
+
+
+void mutex_unlock(struct mutex *m)
+{
+ if (m->state == MUTEX_UNLOCKED) {
+ PERR("Bug: multiple mutex unlock detected");
+ Genode::sleep_forever();
+ }
+ if (m->holder != Lx::scheduler().current()) {
+ PERR("Bug: mutex unlock by task not holding the mutex");
+ Genode::sleep_forever();
+ }
+
+ Lx::Task::List *waiters = static_cast(m->waiters);
+
+ if (m->state == MUTEX_WAITERS)
+ while (Lx::Task::List_element *le = waiters->first())
+ le->object()->mutex_unblock(waiters);
+
+ m->state = MUTEX_UNLOCKED;
+ m->holder = nullptr;
+}
+
+
+int mutex_is_locked(struct mutex *m)
+{
+ return m->state != MUTEX_UNLOCKED;
+}
+
+
+int mutex_trylock(struct mutex *m)
+{
+ if (mutex_is_locked(m))
+ return false;
+
+ mutex_lock(m);
+ return true;
+}
diff --git a/repos/dde_linux/src/include/lx_emul/impl/pci.h b/repos/dde_linux/src/include/lx_emul/impl/pci.h
new file mode 100644
index 0000000000..8ef3d162e7
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/pci.h
@@ -0,0 +1,194 @@
+/*
+ * \brief Implementation of linux/pci.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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
+
+#include
+#include
+
+
+extern void pci_dev_put(struct pci_dev *pci_dev)
+{
+ Genode::destroy(Genode::env()->heap(), pci_dev);
+}
+
+
+extern "C" int pci_register_driver(struct pci_driver *driver)
+{
+ driver->driver.name = driver->name;
+
+ pci_device_id const *id_table = driver->id_table;
+ if (!id_table)
+ return -ENODEV;
+
+ using namespace Genode;
+
+ Lx::Pci_dev *pci_dev = nullptr;
+
+ auto lamda = [&] (Platform::Device_capability cap) {
+
+ Platform::Device_client client(cap);
+
+ /* request device ID from platform driver */
+ unsigned const device_id = client.device_id();
+
+ /* 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++)
+ if (id->device == device_id)
+ matching_id = id;
+
+ /* skip device that is not handled by driver */
+ if (!matching_id)
+ return false;
+
+ /* create 'pci_dev' struct for matching device */
+ pci_dev = new (env()->heap()) Lx::Pci_dev(cap);
+
+ /* enable ioremap to work */
+ Lx::pci_dev_registry()->insert(pci_dev);
+
+ /* register driver at the 'pci_dev' struct */
+ pci_dev->dev.driver = &driver->driver;
+
+ /* call probe function of the Linux driver */
+ if (!driver->probe(pci_dev, matching_id)) {
+
+ /* if the probing failed, revert the creation of 'pci_dev' */
+ pci_dev_put(pci_dev);
+ pci_dev = nullptr;
+ return false;
+ }
+
+ /* aquire the device, stop iterating */
+ return true;
+ };
+
+ Lx::for_each_pci_device(lamda);
+
+ return pci_dev ? 0 : -ENODEV;
+}
+
+
+extern "C" size_t pci_resource_start(struct pci_dev *dev, unsigned bar)
+{
+ if (bar >= DEVICE_COUNT_RESOURCE)
+ return 0;
+
+ return dev->resource[bar].start;
+}
+
+
+extern "C" size_t pci_resource_len(struct pci_dev *dev, unsigned bar)
+{
+ size_t start = pci_resource_start(dev, bar);
+
+ if (!start)
+ return 0;
+
+ return (dev->resource[bar].end - start) + 1;
+}
+
+
+extern "C" void *pci_ioremap_bar(struct pci_dev *dev, int bar)
+{
+ using namespace Genode;
+
+ if (bar >= DEVICE_COUNT_RESOURCE || bar < 0)
+ return 0;
+
+ return Lx::ioremap(pci_resource_start(dev, bar),
+ pci_resource_len(dev, bar),
+ Genode::UNCACHED);
+}
+
+
+extern "C" unsigned int pci_resource_flags(struct pci_dev *dev, unsigned bar)
+{
+ if (bar >= DEVICE_COUNT_RESOURCE)
+ return 0;
+
+ return dev->resource[bar].flags;
+}
+
+
+extern "C" int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int, int where, u8 *val)
+{
+ Lx::Pci_dev *dev = (Lx::Pci_dev *)bus;
+ dev->config_read(where, val);
+ return 0;
+}
+
+
+extern "C" int pci_bus_read_config_word(struct pci_bus *bus, unsigned int, int where, u16 *val)
+{
+ Lx::Pci_dev *dev = (Lx::Pci_dev *)bus;
+ dev->config_read(where, val);
+ return 0;
+}
+
+
+extern "C" int pci_bus_read_config_dword(struct pci_bus *bus, unsigned int, int where, u32 *val)
+{
+ Lx::Pci_dev *dev = (Lx::Pci_dev *)bus;
+ dev->config_read(where, val);
+ return 0;
+}
+
+
+extern "C" int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int, int where, u8 val)
+{
+ Lx::Pci_dev *dev = (Lx::Pci_dev *)bus;
+ dev->config_write(where, val);
+ return 0;
+}
+
+
+extern "C" int pci_bus_write_config_word(struct pci_bus *bus, unsigned int, int where, u16 val)
+{
+ Lx::Pci_dev *dev = (Lx::Pci_dev *)bus;
+ dev->config_write(where, val);
+ return 0;
+}
+
+
+extern "C" int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int, int where, u32 val)
+{
+ Lx::Pci_dev *dev = (Lx::Pci_dev *)bus;
+ dev->config_write(where, val);
+ return 0;
+}
+
+
+extern "C" const char *pci_name(const struct pci_dev *pdev)
+{
+ /* simply return driver name */
+ return "dummy";
+}
+
+
+extern "C" int pcie_capability_read_word(struct pci_dev *pdev, int pos, u16 *val)
+{
+ Lx::Pci_dev *dev = (Lx::Pci_dev *)pdev->bus;
+ switch (pos) {
+ case PCI_EXP_LNKCTL:
+ dev->config_read(pdev->pcie_cap + PCI_EXP_LNKCTL, val);
+ return 0;
+ break;
+ default:
+ break;
+ }
+
+ return 1;
+}
+//
diff --git a/repos/dde_linux/src/include/lx_emul/impl/sched.h b/repos/dde_linux/src/include/lx_emul/impl/sched.h
new file mode 100644
index 0000000000..5c17033d05
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/sched.h
@@ -0,0 +1,39 @@
+/*
+ * \brief Implementation of linux/sched.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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
+
+
+static void unblock_task(unsigned long task)
+{
+ Lx::Task *t = (Lx::Task *)task;
+
+ t->unblock();
+}
+
+
+signed long schedule_timeout(signed long timeout)
+{
+ struct timer_list timer;
+
+ setup_timer(&timer, unblock_task, (unsigned long)Lx::scheduler().current());
+ mod_timer(&timer, timeout);
+
+ Lx::scheduler().current()->block_and_schedule();
+
+ del_timer(&timer);
+
+ timeout = (timeout - jiffies);
+
+ return timeout < 0 ? 0 : timeout;
+}
diff --git a/repos/dde_linux/src/include/lx_emul/impl/slab.h b/repos/dde_linux/src/include/lx_emul/impl/slab.h
new file mode 100644
index 0000000000..8d37e7fb04
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/slab.h
@@ -0,0 +1,175 @@
+/*
+ * \brief Implementation of linux/slab.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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
+
+
+void *kmalloc(size_t size, gfp_t flags)
+{
+ if (flags & __GFP_DMA)
+ PWRN("GFP_DMA memory (below 16 MiB) requested (%p)", __builtin_return_address(0));
+ if (flags & __GFP_DMA32)
+ PWRN("GFP_DMA32 memory (below 4 GiB) requested (%p)", __builtin_return_address(0));
+
+ void *addr = flags & GFP_LX_DMA ? Lx::Malloc::dma().alloc(size, 12)
+ : Lx::Malloc::mem().alloc(size);
+
+ if ((Genode::addr_t)addr & 0x3)
+ PERR("unaligned kmalloc %lx", (Genode::addr_t)addr);
+
+ if (flags & __GFP_ZERO)
+ Genode::memset(addr, 0, size);
+
+ return addr;
+}
+
+
+void *kzalloc(size_t size, gfp_t flags)
+{
+ return kmalloc(size, flags | __GFP_ZERO);
+}
+
+
+void *kzalloc_node(size_t size, gfp_t flags, int node)
+{
+ return kzalloc(size, 0);
+}
+
+
+void *kcalloc(size_t n, size_t size, gfp_t flags)
+{
+ if (size != 0 && n > (~0UL / size))
+ return 0;
+
+ return kzalloc(n * size, flags);
+}
+
+
+void kfree(void const *p)
+{
+ if (!p) return;
+
+ if (Lx::Malloc::mem().inside((Genode::addr_t)p))
+ Lx::Malloc::mem().free(p);
+ else if (Lx::Malloc::dma().inside((Genode::addr_t)p))
+ Lx::Malloc::dma().free(p);
+ else
+ PERR("%s: unknown block at %p, called from %p", __func__,
+ p, __builtin_return_address(0));
+}
+
+
+static size_t _ksize(void *p)
+{
+ size_t size = 0;
+
+ if (Lx::Malloc::mem().inside((Genode::addr_t)p))
+ size = Lx::Malloc::mem().size(p);
+ else if (Lx::Malloc::dma().inside((Genode::addr_t)p))
+ size = Lx::Malloc::dma().size(p);
+ else
+ PERR("%s: unknown block at %p", __func__, p);
+
+ return size;
+}
+
+
+size_t ksize(void *p)
+{
+ return _ksize(p);
+}
+
+
+void kzfree(void const *p)
+{
+ if (!p) return;
+
+ size_t len = ksize(const_cast(p));
+
+ Genode::memset((void*)p, 0, len);
+
+ kfree(p);
+}
+
+
+void *kmalloc_node_track_caller(size_t size, gfp_t flags, int node)
+{
+ return kmalloc(size, flags);
+}
+
+
+void *krealloc(void *p, size_t size, gfp_t flags)
+{
+ /* XXX handle short-cut where size == old_size */
+ void *addr = kmalloc(size, flags);
+
+ if (addr && p) {
+ size_t old_size = _ksize(p);
+
+ Genode::memcpy(addr, p, old_size);
+ kfree(p);
+ }
+
+ return addr;
+}
+
+
+void *kmemdup(const void *src, size_t size, gfp_t flags)
+{
+ void *addr = kmalloc(size, flags);
+
+ if (addr)
+ Genode::memcpy(addr, src, size);
+
+ return addr;
+}
+
+
+struct kmem_cache : Lx::Slab_alloc
+{
+ kmem_cache(size_t object_size, bool dma)
+ :
+ Lx::Slab_alloc(object_size, dma ? Lx::Slab_backend_alloc::dma()
+ : Lx::Slab_backend_alloc::mem())
+ { }
+};
+
+
+struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align,
+ unsigned long flags, void (*ctor)(void *))
+{
+ if (ctor) {
+ PERR("%s: ctor not supported", __func__);
+ return nullptr;
+ }
+
+ /*
+ * Copied from wifi_drv.
+ *
+ * XXX SLAB_LX_DMA is never used anywhere else, remove it?
+ */
+ enum { SLAB_LX_DMA = 0x80000000ul, };
+ return new (Genode::env()->heap()) kmem_cache(size, flags & SLAB_LX_DMA);
+}
+
+
+void * kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags)
+{
+ return (void *)cache->alloc();
+}
+
+
+void kmem_cache_free(struct kmem_cache *cache, void *objp)
+{
+ cache->free(objp);
+}
diff --git a/repos/dde_linux/src/include/lx_emul/impl/spinlock.h b/repos/dde_linux/src/include/lx_emul/impl/spinlock.h
new file mode 100644
index 0000000000..e77dd3cb59
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/spinlock.h
@@ -0,0 +1,17 @@
+/*
+ * \brief Implementation of linux/spinlock.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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.
+ */
+
+void spin_lock_init(spinlock_t *lock) { TRACE; }
+void spin_lock_irqsave(spinlock_t *lock, unsigned long flags) { }
+void spin_unlock(spinlock_t *lock) { TRACE; }
+void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) { }
diff --git a/repos/dde_linux/src/include/lx_emul/impl/timer.h b/repos/dde_linux/src/include/lx_emul/impl/timer.h
new file mode 100644
index 0000000000..13a922464a
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/timer.h
@@ -0,0 +1,52 @@
+/*
+ * \brief Implementation of linux/timer.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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
+
+
+void init_timer(struct timer_list *timer) { }
+
+
+int mod_timer(struct timer_list *timer, unsigned long expires)
+{
+ if (!Lx::timer().find(timer))
+ Lx::timer().add(timer);
+
+ return Lx::timer().schedule(timer, expires);
+}
+
+
+void setup_timer(struct timer_list *timer,void (*function)(unsigned long),
+ unsigned long data)
+{
+ timer->function = function;
+ timer->data = data;
+ init_timer(timer);
+}
+
+
+int timer_pending(const struct timer_list *timer)
+{
+ bool pending = Lx::timer().pending(timer);
+
+ return pending;
+}
+
+
+int del_timer(struct timer_list *timer)
+{
+ int rv = Lx::timer().del(timer);
+ Lx::timer().schedule_next();
+
+ return rv;
+}
diff --git a/repos/dde_linux/src/include/lx_emul/impl/wait.h b/repos/dde_linux/src/include/lx_emul/impl/wait.h
new file mode 100644
index 0000000000..df0f74053d
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/impl/wait.h
@@ -0,0 +1,47 @@
+/*
+ * \brief Implementation of linux/wait.h
+ * \author Norman Feske
+ * \date 2015-09-09
+ */
+
+/*
+ * 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.
+ */
+
+void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *w, int state)
+{
+ if (!q) {
+ PWRN("prepare_to_wait: wait_queue_head_t is 0, ignore, called from: %p",
+ __builtin_return_address(0));
+ return;
+ }
+
+ Wait_list *list = static_cast(q->list);
+ Lx::Task *task = Lx::scheduler().current();
+
+ task->wait_enqueue(list);
+}
+
+
+void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *w, int state)
+{
+ prepare_to_wait(q, w, state);
+}
+
+
+void finish_wait(wait_queue_head_t *q, wait_queue_t *w)
+{
+ if (!q) {
+ PWRN("finish_wait: wait_queue_head_t is 0, ignore, called from: %p",
+ __builtin_return_address(0));
+ return;
+ }
+
+ Wait_list *list = static_cast(q->list);
+ Lx::Task *task = Lx::scheduler().current();
+
+ task->wait_dequeue(list);
+}
diff --git a/repos/dde_linux/src/include/lx_emul/ioport.h b/repos/dde_linux/src/include/lx_emul/ioport.h
new file mode 100644
index 0000000000..1c94ec450f
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/ioport.h
@@ -0,0 +1,47 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/********************
+ ** linux/ioport.h **
+ ********************/
+
+#define IORESOURCE_IO 0x00000100
+#define IORESOURCE_MEM 0x00000200
+#define IORESOURCE_IRQ 0x00000400
+
+struct resource
+{
+ resource_size_t start;
+ resource_size_t end;
+ const char *name;
+ unsigned long flags;
+};
+
+struct device;
+
+struct resource *request_region(resource_size_t start, resource_size_t n,
+ const char *name);
+struct resource *request_mem_region(resource_size_t start, resource_size_t n,
+ const char *name);
+struct resource * devm_request_mem_region(struct device *dev, resource_size_t start,
+ resource_size_t n, const char *name);
+
+
+void release_region(resource_size_t start, resource_size_t n);
+void release_mem_region(resource_size_t start, resource_size_t n);
+
+resource_size_t resource_size(const struct resource *res);
diff --git a/repos/dde_linux/src/include/lx_emul/irq.h b/repos/dde_linux/src/include/lx_emul/irq.h
new file mode 100644
index 0000000000..ad3e43e88a
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/irq.h
@@ -0,0 +1,26 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/***********************
+ ** linux/irqreturn.h **
+ ***********************/
+
+typedef enum irqreturn {
+ IRQ_NONE = 0,
+ IRQ_HANDLED = 1,
+ IRQ_WAKE_THREAD = 2,
+} irqreturn_t;
diff --git a/repos/dde_linux/src/include/lx_emul/jiffies.h b/repos/dde_linux/src/include/lx_emul/jiffies.h
new file mode 100644
index 0000000000..168936cb94
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/jiffies.h
@@ -0,0 +1,46 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*********************
+ ** linux/jiffies.h **
+ *********************/
+
+#define MAX_JIFFY_OFFSET ((LONG_MAX >> 1)-1)
+
+extern unsigned long jiffies;
+
+enum {
+ JIFFIES_TICK_MS = 1000/HZ,
+ JIFFIES_TICK_US = 1000*1000/HZ,
+};
+
+static inline unsigned long msecs_to_jiffies(const unsigned int m) { return m / JIFFIES_TICK_MS; }
+static inline unsigned int jiffies_to_msecs(const unsigned long j) { return j * JIFFIES_TICK_MS; }
+static inline unsigned long usecs_to_jiffies(const unsigned int u) { return u / JIFFIES_TICK_US; }
+
+clock_t jiffies_to_clock_t(unsigned long x);
+static inline clock_t jiffies_delta_to_clock_t(long delta)
+{
+ return jiffies_to_clock_t(max(0L, delta));
+}
+
+#define time_after(a,b) ((long)((b) - (a)) < 0)
+#define time_after_eq(a,b) ((long)((a) - (b)) >= 0)
+#define time_before(a,b) time_after(b,a)
+#define time_before_eq(a,b) time_after_eq(b,a)
+
+#define time_is_after_jiffies(a) time_before(jiffies, a)
diff --git a/repos/dde_linux/src/include/lx_emul/kernel.h b/repos/dde_linux/src/include/lx_emul/kernel.h
new file mode 100644
index 0000000000..7ec001ad68
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/kernel.h
@@ -0,0 +1,172 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*********************
+ ** linux/kconfig.h **
+ *********************/
+
+#define IS_ENABLED(x) x
+
+
+/********************
+ ** linux/kernel.h **
+ ********************/
+
+/*
+ * Log tags
+ */
+#define KERN_ALERT "ALERT: "
+#define KERN_CRIT "CRTITCAL: "
+#define KERN_DEBUG "DEBUG: "
+#define KERN_EMERG "EMERG: "
+#define KERN_ERR "ERROR: "
+#define KERN_INFO "INFO: "
+#define KERN_NOTICE "NOTICE: "
+#define KERN_WARNING "WARNING: "
+#define KERN_WARN "WARNING: "
+
+/*
+ * Debug macros
+ */
+#if DEBUG_LINUX_PRINTK
+#define printk _printk
+#define vprintk lx_vprintf
+#else
+#define printk(...)
+#define vprintk(...)
+#endif
+
+static inline __printf(1, 2) void panic(const char *fmt, ...) __noreturn;
+static inline void panic(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ lx_vprintf(fmt, args);
+ va_end(args);
+ lx_printf("panic()");
+ while (1) ;
+}
+
+/*
+ * Bits and types
+ */
+
+/* needed by linux/list.h */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+/* normally provided by linux/stddef.h, needed by linux/list.h */
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+#define max_t(type, x, y) ({ \
+ type __max1 = (x); \
+ type __max2 = (y); \
+ __max1 > __max2 ? __max1: __max2; })
+
+/**
+ * Return minimum of two given values
+ *
+ * XXX check how this function is used (argument types)
+ */
+static inline size_t min(size_t a, size_t b) {
+ return a < b ? a : b; }
+
+/**
+ * Return maximum of two given values
+ *
+ * XXX check how this function is used (argument types)
+ */
+#define max(x, y) ({ \
+ typeof(x) _max1 = (x); \
+ typeof(y) _max2 = (y); \
+ (void) (&_max1 == &_max2); \
+ _max1 > _max2 ? _max1 : _max2; })
+
+#define min_t(type, x, y) ({ \
+ type __min1 = (x); \
+ type __min2 = (y); \
+ __min1 < __min2 ? __min1: __min2; })
+
+#define abs(x) ( { \
+ typeof (x) _x = (x); \
+ _x < 0 ? -_x : _x; })
+
+#define lower_32_bits(n) ((u32)(n))
+#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
+
+#define roundup(x, y) ( \
+{ \
+ const typeof(y) __y = y; \
+ (((x) + (__y - 1)) / __y) * __y; \
+})
+
+#define __round_mask(x, y) ((__typeof__(x))((y)-1))
+#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
+#define round_down(x, y) ((x) & ~__round_mask(x, y))
+
+#define clamp_val(val, min, max) ({ \
+ typeof(val) __val = (val); \
+ typeof(val) __min = (min); \
+ typeof(val) __max = (max); \
+ __val = __val < __min ? __min: __val; \
+ __val > __max ? __max: __val; })
+
+#define clamp_t(type, val, min, max) ({ \
+ type __val = (val); \
+ type __min = (min); \
+ type __max = (max); \
+ __val = __val < __min ? __min: __val; \
+ __val > __max ? __max: __val; })
+
+#define DIV_ROUND_CLOSEST(x, divisor)( \
+{ \
+ typeof(x) __x = x; \
+ typeof(divisor) __d = divisor; \
+ (((typeof(x))-1) > 0 || \
+ ((typeof(divisor))-1) > 0 || (__x) > 0) ? \
+ (((__x) + ((__d) / 2)) / (__d)) : \
+ (((__x) - ((__d) / 2)) / (__d)); \
+})
+
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
+#define ALIGN(x, a) __ALIGN_KERNEL((x), (a))
+#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
+#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+#define BUILD_BUG_ON(condition)
+
+#define _RET_IP_ (unsigned long)__builtin_return_address(0)
+
+void might_sleep();
+#define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0)
+
+#define INT_MAX ((int)(~0U>>1))
+#define UINT_MAX (~0U)
+#define INT_MIN (-INT_MAX - 1)
+#define USHRT_MAX ((u16)(~0U))
+#define LONG_MAX ((long)(~0UL>>1))
+#define SHRT_MAX ((s16)(USHRT_MAX>>1))
+#define SHRT_MIN ((s16)(-SHRT_MAX - 1))
+#define ULONG_MAX (~0UL)
+
+#define swap(a, b) \
+ do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
+
diff --git a/repos/dde_linux/src/include/lx_emul/kobject.h b/repos/dde_linux/src/include/lx_emul/kobject.h
new file mode 100644
index 0000000000..e01981868b
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/kobject.h
@@ -0,0 +1,44 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/******************
+ ** linux/kref.h **
+ ******************/
+
+struct kref { atomic_t refcount; };
+
+void kref_init(struct kref *kref);
+void kref_get(struct kref *kref);
+int kref_put(struct kref *kref, void (*release) (struct kref *kref));
+
+
+/*********************
+ ** linux/kobject.h **
+ *********************/
+
+struct kobject { struct kobject *parent; };
+struct kobj_uevent_env
+{
+ char buf[32];
+ int buflen;
+};
+
+struct kobj_uevent_env;
+
+int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
+char *kobject_name(const struct kobject *kobj);
+char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask);
diff --git a/repos/dde_linux/src/include/lx_emul/list.h b/repos/dde_linux/src/include/lx_emul/list.h
new file mode 100644
index 0000000000..86835f6707
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/list.h
@@ -0,0 +1,43 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/********************
+ ** linux/poison.h **
+ ********************/
+
+/*
+ * In list.h, LIST_POISON1 and LIST_POISON2 are assigned to 'struct list_head
+ * *' as well as 'struct hlist_node *' pointers. Consequently, C++ compiler
+ * produces an error "cannot convert... in assignment". To compile 'list.h'
+ * included by C++ source code, we have to define these macros to the only
+ * value universally accepted for pointer assigments.h
+ */
+
+#ifdef __cplusplus
+#define LIST_POISON1 nullptr
+#define LIST_POISON2 nullptr
+#else
+#define LIST_POISON1 ((void *)0x00100100)
+#define LIST_POISON2 ((void *)0x00200200)
+#endif /* __cplusplus */
+
+
+/******************
+ ** linux/list.h **
+ ******************/
+
+#include
diff --git a/repos/dde_linux/src/include/lx_emul/mmio.h b/repos/dde_linux/src/include/lx_emul/mmio.h
new file mode 100644
index 0000000000..4e79927c2e
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/mmio.h
@@ -0,0 +1,30 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/**********************
+ ** asm-generic/io.h **
+ **********************/
+
+#define writeq(value, addr) (*(volatile uint64_t *)(addr) = (value))
+#define writel(value, addr) (*(volatile uint32_t *)(addr) = (value))
+#define writew(value, addr) (*(volatile uint16_t *)(addr) = (value))
+#define writeb(value, addr) (*(volatile uint8_t *)(addr) = (value))
+
+#define readq(addr) (*(volatile uint64_t *)(addr))
+#define readl(addr) (*(volatile uint32_t *)(addr))
+#define readw(addr) (*(volatile uint16_t *)(addr))
+#define readb(addr) (*(volatile uint8_t *)(addr))
diff --git a/repos/dde_linux/src/include/lx_emul/module.h b/repos/dde_linux/src/include/lx_emul/module.h
new file mode 100644
index 0000000000..f719929ec1
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/module.h
@@ -0,0 +1,70 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/******************
+ ** linux/init.h **
+ ******************/
+
+#define __init
+#define __exit
+#define __devinitconst
+
+#define _SETUP_CONCAT(a, b) __##a##b
+#define SETUP_CONCAT(a, b) _SETUP_CONCAT(a, b)
+#define __setup(str, fn) static void SETUP_CONCAT(fn, SETUP_SUFFIX)(void *addrs) { fn(addrs); }
+
+#define core_initcall(fn) void core_##fn(void) { fn(); }
+#define subsys_initcall(fn) void subsys_##fn(void) { fn(); }
+#define pure_initcall(fd) void pure_##fn(void) { printk("PURE_INITCALL"); fn(); }
+
+
+/********************
+ ** linux/module.h **
+ ********************/
+
+#define EXPORT_SYMBOL(x)
+#define EXPORT_SYMBOL_GPL(x)
+#define MODULE_LICENSE(x)
+#define MODULE_NAME_LEN (64 - sizeof(long))
+#define MODULE_ALIAS(name)
+#define MODULE_AUTHOR(name)
+#define MODULE_DESCRIPTION(desc)
+#define MODULE_VERSION(version)
+#define THIS_MODULE 0
+#define MODULE_FIRMWARE(_firmware)
+#define MODULE_DEVICE_TABLE(type, name)
+
+
+struct module;
+#define module_init(fn) void module_##fn(void) { fn(); }
+#define module_exit(fn) void module_exit_##fn(void) { fn(); }
+void module_put_and_exit(int);
+
+void module_put(struct module *);
+void __module_get(struct module *module);
+int try_module_get(struct module *);
+
+
+/*************************
+ ** linux/moduleparam.h **
+ *************************/
+
+#define module_param(name, type, perm)
+#define module_param_named(name, value, type, perm)
+#define MODULE_PARM_DESC(_parm, desc)
+#define kparam_block_sysfs_write(name)
+#define kparam_unblock_sysfs_write(name)
diff --git a/repos/dde_linux/src/include/lx_emul/mutex.h b/repos/dde_linux/src/include/lx_emul/mutex.h
new file mode 100644
index 0000000000..caf5686b30
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/mutex.h
@@ -0,0 +1,43 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*******************
+ ** linux/mutex.h **
+ *******************/
+
+struct mutex
+{
+ int state;
+ void *holder;
+ void *waiters;
+ unsigned id; /* for debugging */
+};
+
+#define DEFINE_MUTEX(mutexname) \
+ struct mutex mutexname; \
+ static void __attribute__((constructor)) mutex_init_ ## mutexname(void) \
+ { mutex_init(&mutexname); }
+
+void mutex_init(struct mutex *m);
+void mutex_destroy(struct mutex *m);
+void mutex_lock(struct mutex *m);
+void mutex_unlock(struct mutex *m);
+int mutex_trylock(struct mutex *m);
+int mutex_is_locked(struct mutex *m);
+
+/* special case in net/wireless/util.c:1357 */
+#define mutex_lock_nested(lock, subclass) mutex_lock(lock)
diff --git a/repos/dde_linux/src/include/lx_emul/pci.h b/repos/dde_linux/src/include/lx_emul/pci.h
new file mode 100644
index 0000000000..cbbd6fb29b
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/pci.h
@@ -0,0 +1,149 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*****************
+ ** linux/pci.h **
+ *****************/
+
+#include
+#include
+
+enum {
+ PCI_DMA_BIDIRECTIONAL = 0,
+ PCI_DMA_TODEVICE,
+ PCI_DMA_FROMDEVICE,
+ PCI_DMA_NONE
+};
+
+
+enum { PCI_ANY_ID = ~0U };
+
+
+typedef enum {
+ PCI_D0 = 0,
+ PCI_D1 = 1,
+ PCI_D3hot = 3,
+ PCI_D3cold = 4,
+} pci_power_t;
+
+
+/*
+ * PCI types
+ */
+struct pci_bus;
+struct pci_dev;
+
+struct pci_driver {
+ char *name;
+ const struct pci_device_id *id_table;
+ int (*probe) (struct pci_dev *dev,
+ const struct pci_device_id *id);
+ void (*remove) (struct pci_dev *dev);
+ struct device_driver driver;
+};
+
+
+static inline uint32_t PCI_DEVFN(unsigned slot, unsigned func) {
+ return ((slot & 0x1f) << 3) | (func & 0x07); }
+
+static inline uint32_t PCI_FUNC(unsigned devfn) { return devfn & 0x07; }
+static inline uint32_t PCI_SLOT(unsigned devfn) { return ((devfn) >> 3) & 0x1f; }
+
+int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
+int pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
+int pci_bus_read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 *val);
+int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val);
+int pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val);
+int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val);
+
+static inline
+int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val) {
+return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val); }
+
+static inline
+int pci_read_config_word(struct pci_dev *dev, int where, u16 *val) {
+return pci_bus_read_config_word(dev->bus, dev->devfn, where, val); }
+
+static inline
+int pci_read_config_dword(struct pci_dev *dev, int where, u32 *val) {
+return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val); }
+
+static inline
+int pci_write_config_byte(struct pci_dev *dev, int where, u8 val) {
+return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val); }
+
+static inline
+int pci_write_config_word(struct pci_dev *dev, int where, u16 val) {
+return pci_bus_write_config_word(dev->bus, dev->devfn, where, val); }
+
+static inline
+int pci_write_config_dword(struct pci_dev *dev, int where, u32 val) {
+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);
+void pci_dev_put(struct pci_dev *dev);
+struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from);
+
+int pci_enable_device(struct pci_dev *dev);
+void pci_disable_device(struct pci_dev *dev);
+int pci_register_driver(struct pci_driver *driver);
+void pci_unregister_driver(struct pci_driver *driver);
+const char *pci_name(const struct pci_dev *pdev);
+bool pci_dev_run_wake(struct pci_dev *dev);
+unsigned int pci_resource_flags(struct pci_dev *dev, unsigned bar);
+void pci_set_master(struct pci_dev *dev);
+int pci_set_mwi(struct pci_dev *dev);
+bool pci_pme_capable(struct pci_dev *dev, pci_power_t state);
+int pci_find_capability(struct pci_dev *dev, int cap);
+struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn);
+const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
+int pci_request_regions(struct pci_dev *dev, const char *res_name);
+void pci_release_regions(struct pci_dev *dev);
+void *pci_ioremap_bar(struct pci_dev *pdev, int bar);
+void pci_disable_link_state(struct pci_dev *pdev, int state);
+
+int pci_enable_msi(struct pci_dev *dev);
+void pci_disable_msi(struct pci_dev *dev);
+
+#define DEFINE_PCI_DEVICE_TABLE(_table) \
+ const struct pci_device_id _table[] __devinitconst
+
+#define to_pci_dev(n) container_of(n, struct pci_dev, dev)
+
+int pci_register_driver(struct pci_driver *driver);
+
+int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val);
+
+void *pci_get_drvdata(struct pci_dev *pdev);
+
+
+#define dev_is_pci(d) (1)
+
+int pci_num_vf(struct pci_dev *dev);
+
+/* XXX will this cast ever work? */
+#define dev_num_vf(d) ((dev_is_pci(d) ? pci_num_vf((struct pci_dev *)d) : 0))
+
+
+/**********************
+ ** linux/pci-aspm.h **
+ **********************/
+
+#define PCIE_LINK_STATE_L0S 1
+#define PCIE_LINK_STATE_L1 2
+#define PCIE_LINK_STATE_CLKPM 4
diff --git a/repos/dde_linux/src/include/lx_emul/pm.h b/repos/dde_linux/src/include/lx_emul/pm.h
new file mode 100644
index 0000000000..314a96cb62
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/pm.h
@@ -0,0 +1,43 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/****************
+ ** linux/pm.h **
+ ****************/
+
+struct device;
+
+typedef struct pm_message { int event; } pm_message_t;
+
+struct dev_pm_info { pm_message_t power_state; };
+
+struct dev_pm_ops {
+ int (*suspend)(struct device *dev);
+ int (*resume)(struct device *dev);
+ int (*freeze)(struct device *dev);
+ int (*thaw)(struct device *dev);
+ int (*poweroff)(struct device *dev);
+ int (*restore)(struct device *dev);
+ int (*runtime_suspend)(struct device *dev);
+ int (*runtime_resume)(struct device *dev);
+};
+
+#define PMSG_IS_AUTO(msg) 0
+
+enum { PM_EVENT_AUTO_SUSPEND = 0x402 };
+
+#define PM_EVENT_SUSPEND 0x0002
diff --git a/repos/dde_linux/src/include/lx_emul/printf.h b/repos/dde_linux/src/include/lx_emul/printf.h
new file mode 100644
index 0000000000..2a9d78071a
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/printf.h
@@ -0,0 +1,32 @@
+/*
+ * \brief Debugging utilities
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+void lx_printf(char const *, ...) __attribute__((format(printf, 1, 2)));
+void lx_vprintf(char const *, va_list);
+
+#define lx_printfln(args...) \
+ do { \
+ lx_printf(args); \
+ lx_printf("\n"); \
+ } while (0);
+
+#define lx_log(doit, msg...) \
+ do { \
+ if (doit) { \
+ lx_printf("%s(): ", __func__); \
+ lx_printf(msg); \
+ lx_printf("\n"); \
+ } \
+ } while(0)
diff --git a/repos/dde_linux/src/include/lx_emul/scatterlist.h b/repos/dde_linux/src/include/lx_emul/scatterlist.h
new file mode 100644
index 0000000000..f9f4b657d9
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/scatterlist.h
@@ -0,0 +1,91 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*************************
+ ** linux/scatterlist.h **
+ *************************/
+
+enum {
+ SG_MITER_TO_SG = 2,
+ SG_MITER_FROM_SG = 4,
+};
+
+struct scatterlist {
+ unsigned long page_link;
+ unsigned int offset;
+ unsigned int length;
+ dma_addr_t dma_address;
+ int last;
+};
+
+struct sg_table
+{
+ struct scatterlist *sgl; /* the list */
+ unsigned int nents; /* number of mapped entries */
+};
+
+struct sg_page_iter
+{
+ struct scatterlist *sg;
+ unsigned int sg_pgoffset; /* page offset within the sg */
+};
+
+struct sg_mapping_iter
+{
+ void *addr;
+ size_t length;
+
+ struct sg_page_iter piter;
+};
+
+struct page;
+
+void sg_init_table(struct scatterlist *, unsigned int);
+void sg_set_buf(struct scatterlist *sg, const void *buf, unsigned int buflen);
+void sg_set_page(struct scatterlist *sg, struct page *page,
+ unsigned int len, unsigned int offset);
+
+struct page *sg_page(struct scatterlist *sg);
+void *sg_virt(struct scatterlist *sg);
+struct scatterlist *sg_next(struct scatterlist *);
+
+int sg_nents(struct scatterlist *sg);
+size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,
+ void *buf, size_t buflen);
+size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents,
+ void *buf, size_t buflen);
+
+bool __sg_page_iter_next(struct sg_page_iter *piter);
+void __sg_page_iter_start(struct sg_page_iter *piter,
+ struct scatterlist *sglist, unsigned int nents,
+ unsigned long pgoffset);
+
+#define for_each_sg(sglist, sg, nr, __i) \
+ for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
+
+#define for_each_sg_page(sglist, piter, nents, pgoffset) \
+ for (__sg_page_iter_start((piter), (sglist), (nents), (pgoffset)); \
+ __sg_page_iter_next(piter);)
+
+#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_dma_len(sg) ((sg)->length)
+
+void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl,
+ unsigned int nents, unsigned int flags);
+bool sg_miter_skip(struct sg_mapping_iter *miter, off_t offset);
+bool sg_miter_next(struct sg_mapping_iter *miter);
+void sg_miter_stop(struct sg_mapping_iter *miter);
diff --git a/repos/dde_linux/src/include/lx_emul/semaphore.h b/repos/dde_linux/src/include/lx_emul/semaphore.h
new file mode 100644
index 0000000000..030b25ab77
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/semaphore.h
@@ -0,0 +1,34 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*******************
+ ** linux/rwsem.h **
+ *******************/
+
+struct rw_semaphore { int dummy; };
+
+#define DECLARE_RWSEM(name) \
+ struct rw_semaphore name = { 0 }
+
+#define init_rwsem(sem) do { (void)sem; } while (0)
+
+void down_read(struct rw_semaphore *sem);
+void up_read(struct rw_semaphore *sem);
+void down_write(struct rw_semaphore *sem);
+void up_write(struct rw_semaphore *sem);
+
+#define __RWSEM_INITIALIZER(name) { 0 }
diff --git a/repos/dde_linux/src/include/lx_emul/spinlock.h b/repos/dde_linux/src/include/lx_emul/spinlock.h
new file mode 100644
index 0000000000..ee63414b1e
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/spinlock.h
@@ -0,0 +1,44 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/**********************
+ ** linux/spinlock.h **
+ **********************/
+
+typedef struct spinlock { unsigned unused; } spinlock_t;
+#define DEFINE_SPINLOCK(name) spinlock_t name
+
+void spin_lock(spinlock_t *lock);
+void spin_lock_nested(spinlock_t *lock, int subclass);
+void spin_unlock(spinlock_t *lock);
+void spin_lock_init(spinlock_t *lock);
+void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);
+void spin_lock_irqrestore(spinlock_t *lock, unsigned long flags);
+void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);
+void spin_lock_irq(spinlock_t *lock);
+void spin_unlock_irq(spinlock_t *lock);
+void assert_spin_locked(spinlock_t *lock);
+void spin_lock_bh(spinlock_t *lock);
+void spin_unlock_bh(spinlock_t *lock);
+int spin_trylock(spinlock_t *lock);
+
+
+/****************************
+ ** linux/spinlock_types.h **
+ ****************************/
+
+#define __SPIN_LOCK_UNLOCKED(x) 0
diff --git a/repos/dde_linux/src/include/lx_emul/string.h b/repos/dde_linux/src/include/lx_emul/string.h
new file mode 100644
index 0000000000..a4f2ff4f1d
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/string.h
@@ -0,0 +1,43 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/********************
+ ** linux/string.h **
+ ********************/
+#undef memcpy
+
+void *memcpy(void *d, const void *s, size_t n);
+void *memset(void *s, int c, size_t n);
+int memcmp(const void *, const void *, size_t);
+void *memscan(void *addr, int c, size_t size);
+char *strcat(char *dest, const char *src);
+int strcmp(const char *s1, const char *s2);
+int strncmp(const char *cs, const char *ct, size_t count);
+char *strcpy(char *to, const char *from);
+char *strncpy(char *, const char *, size_t);
+char *strchr(const char *, int);
+char *strrchr(const char *,int);
+size_t strlcat(char *dest, const char *src, size_t n);
+size_t strlcpy(char *dest, const char *src, size_t size);
+size_t strlen(const char *);
+size_t strnlen(const char *, size_t);
+char * strsep(char **,const char *);
+char *strstr(const char *, const char *);
+char *kstrdup(const char *s, gfp_t gfp);
+void *kmemdup(const void *src, size_t len, gfp_t gfp);
+void *memmove(void *, const void *, size_t);
+void * memchr(const void *, int, size_t);
diff --git a/repos/dde_linux/src/include/lx_emul/time.h b/repos/dde_linux/src/include/lx_emul/time.h
new file mode 100644
index 0000000000..80b1bcd4f1
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/time.h
@@ -0,0 +1,82 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/******************
+ ** linux/time.h **
+ ******************/
+
+struct timespec {
+ __kernel_time_t tv_sec;
+ long tv_nsec;
+};
+
+struct timeval { };
+struct timespec current_kernel_time(void);
+void do_gettimeofday(struct timeval *tv);
+
+#define CURRENT_TIME (current_kernel_time())
+
+
+
+enum {
+ CLOCK_REALTIME = 0,
+ CLOCK_MONOTONIC = 1,
+ NSEC_PER_USEC = 1000L,
+ NSEC_PER_MSEC = 1000000L,
+ NSEC_PER_SEC = 1000L * NSEC_PER_MSEC,
+};
+
+
+/*******************
+ ** linux/ktime.h **
+ *******************/
+
+union ktime { s64 tv64; };
+
+typedef union ktime ktime_t;
+
+ktime_t ktime_add_ns(const ktime_t kt, u64 nsec);
+
+static inline ktime_t ktime_add_us(const ktime_t kt, const u64 usec)
+{
+ return ktime_add_ns(kt, usec * 1000);
+}
+
+static inline ktime_t ktime_get(void)
+{
+ return (ktime_t){ .tv64 = (s64)jiffies * HZ * NSEC_PER_MSEC /* ns */ };
+}
+
+static inline ktime_t ktime_set(const long sec, const unsigned long nsec)
+{
+ return (ktime_t){ .tv64 = (s64)sec * NSEC_PER_SEC + (s64)nsec /* ns */ };
+}
+
+static inline ktime_t ktime_add(const ktime_t a, const ktime_t b)
+{
+ return (ktime_t){ .tv64 = a.tv64 + b.tv64 /* ns */ };
+}
+
+
+s64 ktime_us_delta(const ktime_t later, const ktime_t earlier);
+
+struct timeval ktime_to_timeval(const ktime_t);
+
+ktime_t ktime_get_real(void);
+ktime_t ktime_sub(const ktime_t, const ktime_t);
+ktime_t ktime_get_monotonic_offset(void);
+
diff --git a/repos/dde_linux/src/include/lx_emul/timer.h b/repos/dde_linux/src/include/lx_emul/timer.h
new file mode 100644
index 0000000000..90990447e3
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/timer.h
@@ -0,0 +1,50 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*******************
+ ** linux/timer.h **
+ *******************/
+
+struct tvec_base;
+extern struct tvec_base boot_tvec_bases; /* needed by 'dwc_common_linux.c' */
+
+struct timer_list
+{
+ void (*function)(unsigned long);
+ unsigned long data;
+ void *timer;
+ unsigned long expires;
+ struct tvec_base *base; /* needed by 'dwc_common_linux.c' */
+};
+
+void init_timer(struct timer_list *);
+void init_timer_deferrable(struct timer_list *);
+int mod_timer(struct timer_list *timer, unsigned long expires);
+int del_timer(struct timer_list * timer);
+void setup_timer(struct timer_list *timer, void (*function)(unsigned long),
+ unsigned long data);
+
+int timer_pending(const struct timer_list * timer);
+unsigned long round_jiffies(unsigned long j);
+unsigned long round_jiffies_relative(unsigned long j);
+unsigned long round_jiffies_up(unsigned long j);
+
+void set_timer_slack(struct timer_list *time, int slack_hz);
+static inline void add_timer(struct timer_list *timer) { mod_timer(timer, timer->expires); }
+
+static inline
+int del_timer_sync(struct timer_list * timer) { return del_timer(timer); }
diff --git a/repos/dde_linux/src/include/lx_emul/types.h b/repos/dde_linux/src/include/lx_emul/types.h
new file mode 100644
index 0000000000..d60d0310ff
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/types.h
@@ -0,0 +1,106 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*******************
+ ** linux/types.h **
+ *******************/
+
+typedef genode_int8_t int8_t;
+typedef genode_uint8_t uint8_t;
+typedef genode_int16_t int16_t;
+typedef genode_uint16_t uint16_t;
+typedef genode_int32_t int32_t;
+typedef genode_uint32_t uint32_t;
+typedef __SIZE_TYPE__ size_t;
+typedef genode_int64_t int64_t;
+typedef genode_uint64_t uint64_t;
+
+typedef uint32_t uint;
+typedef unsigned long ulong;
+
+typedef int8_t s8;
+typedef uint8_t u8;
+typedef int16_t s16;
+typedef uint16_t u16;
+typedef int32_t s32;
+typedef uint32_t u32;
+typedef int64_t s64;
+typedef uint64_t u64;
+
+typedef int8_t __s8;
+typedef uint8_t __u8;
+typedef int16_t __s16;
+typedef uint16_t __u16;
+typedef int32_t __s32;
+typedef uint32_t __u32;
+typedef int64_t __s64;
+typedef uint64_t __u64;
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+struct hlist_head {
+ struct hlist_node *first;
+};
+
+struct hlist_node {
+ struct hlist_node *next, **pprev;
+};
+
+#ifndef __cplusplus
+typedef _Bool bool;
+enum { true = 1, false = 0 };
+#endif /* __cplusplus */
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL nullptr
+#else
+#define NULL ((void *)0)
+#endif /* __cplusplus */
+#endif /* NULL */
+
+typedef unsigned gfp_t;
+typedef unsigned long dma_addr_t;
+typedef unsigned long pgoff_t;
+typedef long long loff_t;
+typedef long ssize_t;
+typedef unsigned long uintptr_t;
+typedef int dev_t;
+typedef size_t resource_size_t;
+typedef long off_t;
+typedef int pid_t;
+typedef unsigned fmode_t;
+typedef u32 uid_t;
+typedef u32 gid_t;
+typedef unsigned kuid_t;
+typedef unsigned kgid_t;
+typedef long __kernel_time_t;
+typedef unsigned short umode_t;
+typedef __u16 __be16;
+typedef __u32 __be32;
+typedef long clock_t;
+
+#ifndef __cplusplus
+typedef u16 wchar_t;
+#endif
+
+/*
+ * XXX 'mode_t' is 'unsigned int' on x86_64
+ */
+typedef unsigned short mode_t;
diff --git a/repos/dde_linux/src/include/lx_emul/work.h b/repos/dde_linux/src/include/lx_emul/work.h
new file mode 100644
index 0000000000..072d01bde1
--- /dev/null
+++ b/repos/dde_linux/src/include/lx_emul/work.h
@@ -0,0 +1,203 @@
+/*
+ * \brief Linux kernel API
+ * \author Norman Feske
+ * \author Sebastian Sumpf
+ * \author Josef Soentgen
+ * \date 2014-08-21
+ *
+ * Based on the prototypes found in the Linux kernel's 'include/'.
+ */
+
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/***********************
+ ** linux/workqueue.h **
+ ***********************/
+
+enum {
+ WQ_MEM_RECLAIM,
+ WQ_CPU_INTENSIVE,
+};
+
+struct work_struct;
+typedef void (*work_func_t)(struct work_struct *work);
+
+struct work_struct {
+ atomic_long_t data;
+ work_func_t func;
+ struct list_head entry;
+};
+
+struct delayed_work {
+ struct timer_list timer;
+ struct work_struct work;
+};
+
+bool cancel_work_sync(struct work_struct *work);
+bool cancel_delayed_work_sync(struct delayed_work *work);
+bool cancel_delayed_work(struct delayed_work *dwork);
+int schedule_delayed_work(struct delayed_work *work, unsigned long delay);
+int schedule_work(struct work_struct *work);
+void flush_scheduled_work(void);
+
+bool flush_work(struct work_struct *work);
+bool flush_work_sync(struct work_struct *work);
+
+
+#define PREPARE_WORK(_work, _func) \
+ do { (_work)->func = (_func); } while (0)
+
+#define PREPARE_DELAYED_WORK(_work, _func) \
+ PREPARE_WORK(&(_work)->work, (_func))
+
+#define __INIT_WORK(_work, _func, on_stack) \
+ do { \
+ INIT_LIST_HEAD(&(_work)->entry); \
+ PREPARE_WORK((_work), (_func)); \
+ } while (0)
+
+#define INIT_WORK(_work, _func)\
+ do { __INIT_WORK((_work), (_func), 0); } while (0)
+
+#define INIT_DELAYED_WORK(_work, _func) \
+ do { \
+ INIT_WORK(&(_work)->work, (_func)); \
+ init_timer(&(_work)->timer); \
+ } while (0)
+
+
+/* dummy for queue_delayed_work call in storage/usb.c */
+#define system_freezable_wq 0
+struct workqueue_struct { unsigned unused; };
+
+struct workqueue_struct *create_singlethread_workqueue(const char *name);
+struct workqueue_struct *alloc_ordered_workqueue(const char *fmt, unsigned int flags, ...) __printf(1, 3);
+struct workqueue_struct *alloc_workqueue(const char *fmt, unsigned int flags,
+ int max_active, ...) __printf(1, 4);
+void destroy_workqueue(struct workqueue_struct *wq);
+void flush_workqueue(struct workqueue_struct *wq);
+bool queue_delayed_work(struct workqueue_struct *, struct delayed_work *, unsigned long);
+bool flush_delayed_work(struct delayed_work *dwork);
+bool queue_work(struct workqueue_struct *wq, struct work_struct *work);
+
+#define DECLARE_DELAYED_WORK(n, f) \
+ struct delayed_work n
+
+bool mod_delayed_work(struct workqueue_struct *, struct delayed_work *,
+ unsigned long);
+
+static inline struct delayed_work *to_delayed_work(struct work_struct *work)
+{
+ return container_of(work, struct delayed_work, work);
+}
+
+extern struct workqueue_struct *system_wq;
+
+enum {
+ WORK_STRUCT_STATIC = 0,
+
+ WORK_STRUCT_COLOR_SHIFT = 4,
+ WORK_STRUCT_COLOR_BITS = 4,
+ WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + WORK_STRUCT_COLOR_BITS,
+ WORK_OFFQ_FLAG_BASE = WORK_STRUCT_FLAG_BITS,
+
+ WORK_OFFQ_FLAG_BITS = 1,
+ WORK_OFFQ_POOL_SHIFT = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS,
+ WORK_OFFQ_LEFT = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT,
+ WORK_OFFQ_POOL_BITS = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31,
+ WORK_OFFQ_POOL_NONE = (1LU << WORK_OFFQ_POOL_BITS) - 1,
+
+ WORK_STRUCT_NO_POOL = (unsigned long)WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT,
+};
+
+#define WORK_DATA_STATIC_INIT() \
+ ATOMIC_LONG_INIT(WORK_STRUCT_NO_POOL | WORK_STRUCT_STATIC)
+
+#define __WORK_INIT_LOCKDEP_MAP(n, k)
+
+#define __WORK_INITIALIZER(n, f) { \
+ .data = WORK_DATA_STATIC_INIT(), \
+ .entry = { &(n).entry, &(n).entry }, \
+ .func = (f), \
+ __WORK_INIT_LOCKDEP_MAP(#n, &(n)) \
+}
+
+#define DECLARE_WORK(n, f) \
+ struct work_struct n = __WORK_INITIALIZER(n, f)
+
+
+/******************
+ ** linux/wait.h **
+ ******************/
+
+typedef struct wait_queue_head { void *list; } wait_queue_head_t;
+typedef struct wait_queue { unsigned unused; } wait_queue_t;
+
+#define DEFINE_WAIT(name) \
+ wait_queue_t name;
+
+#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { 0 }
+
+#define DECLARE_WAITQUEUE(name, tsk) \
+ wait_queue_t name
+
+#define DECLARE_WAIT_QUEUE_HEAD(name) \
+ wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
+
+#define DEFINE_WAIT_FUNC(name, function) \
+ wait_queue_t name
+
+/* simplified signature */
+void __wake_up(wait_queue_head_t *q, bool all);
+
+#define wake_up(x) __wake_up(x, false)
+#define wake_up_all(x) __wake_up(x, true)
+#define wake_up_interruptible(x) __wake_up(x, false)
+#define wake_up_interruptible_all(x) __wake_up(x, true)
+
+void init_waitqueue_head(wait_queue_head_t *);
+int waitqueue_active(wait_queue_head_t *);
+
+/* void wake_up_interruptible(wait_queue_head_t *); */
+void wake_up_interruptible_sync_poll(wait_queue_head_t *, int);
+void wake_up_interruptible_poll(wait_queue_head_t *, int);
+
+void prepare_to_wait(wait_queue_head_t *, wait_queue_t *, int);
+void prepare_to_wait_exclusive(wait_queue_head_t *, wait_queue_t *, int);
+void finish_wait(wait_queue_head_t *, wait_queue_t *);
+
+int autoremove_wake_function(wait_queue_t *, unsigned, int, void *);
+void add_wait_queue(wait_queue_head_t *, wait_queue_t *);
+void add_wait_queue_exclusive(wait_queue_head_t *, wait_queue_t *);
+void remove_wait_queue(wait_queue_head_t *, wait_queue_t *);
+
+/* our wait event implementation - it's okay as value */
+void __wait_event(wait_queue_head_t);
+
+#define _wait_event(wq, condition) while (!(condition)) { __wait_event(wq); }
+#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 ret = _wait_event_timeout(wq, (condition), timeout); \
+ ret; \
+ })
diff --git a/repos/dde_linux/src/include/spec/x86_32/lx_emul/impl/internal/arch_execute.h b/repos/dde_linux/src/include/spec/x86_32/lx_emul/impl/internal/arch_execute.h
new file mode 100644
index 0000000000..134c9f484b
--- /dev/null
+++ b/repos/dde_linux/src/include/spec/x86_32/lx_emul/impl/internal/arch_execute.h
@@ -0,0 +1,27 @@
+/*
+ * \brief Architecture-specific code
+ * \author Sebastian Sumpf
+ * \date 2012-06-10
+ */
+
+/*
+ * Copyright (C) 2012-2013 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 _ARCH_EXECUTE_H_
+#define _ARCH_EXECUTE_H_
+
+static inline
+void arch_execute(void *sp, void *func, void *arg)
+{
+ asm volatile ("movl %2, 0(%0);"
+ "movl %1, -0x4(%0);"
+ "movl %0, %%esp;"
+ "call *-4(%%esp);"
+ : : "r" (sp), "r" (func), "r" (arg));
+}
+
+#endif /* _ARCH_EXECUTE_H_ */
diff --git a/repos/dde_linux/src/include/spec/x86_64/lx_emul/impl/internal/arch_execute.h b/repos/dde_linux/src/include/spec/x86_64/lx_emul/impl/internal/arch_execute.h
new file mode 100644
index 0000000000..eb96ce8f6c
--- /dev/null
+++ b/repos/dde_linux/src/include/spec/x86_64/lx_emul/impl/internal/arch_execute.h
@@ -0,0 +1,28 @@
+/*
+ * \brief Architecture-specific code
+ * \author Sebastian Sumpf
+ * \author Alexander Boettcher
+ * \date 2012-06-10
+ */
+
+/*
+ * Copyright (C) 2012-2013 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 _ARCH_EXECUTE_H_
+#define _ARCH_EXECUTE_H_
+
+static inline
+void arch_execute(void *sp, void *func, void *arg)
+{
+ asm volatile ("movq %2, %%rdi;"
+ "movq %1, 0(%0);"
+ "movq %0, %%rsp;"
+ "call *0(%%rsp);"
+ : "+r" (sp), "+r" (func), "+r" (arg) : : "memory");
+}
+
+#endif /* _ARCH_EXECUTE_H_ */
diff --git a/repos/dde_linux/src/include/x86/lx_emul/barrier.h b/repos/dde_linux/src/include/x86/lx_emul/barrier.h
new file mode 100644
index 0000000000..d0575003d4
--- /dev/null
+++ b/repos/dde_linux/src/include/x86/lx_emul/barrier.h
@@ -0,0 +1,19 @@
+
+/*******************
+ ** asm/barrier.h **
+ *******************/
+
+#define mb() asm volatile ("mfence": : :"memory")
+#define rmb() asm volatile ("lfence": : :"memory")
+#define wmb() asm volatile ("sfence": : :"memory")
+
+/*
+ * This is the "safe" implementation as needed for a configuration
+ * with SMP enabled.
+ */
+
+#define smp_mb() mb()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+
+static inline void barrier() { asm volatile ("": : :"memory"); }