mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 14:37:50 +00:00
fae63f4fa9
This patch simplifies the way of how Genode's base libraries are organized. Originally, the base API was implemented in the form of many small libraries such as 'thread', 'env', 'server', etc. Most of them used to consist of only a small number of files. Because those libraries are incorporated in any build, the checking of their inter-dependencies made the build process more verbose than desired. Also, the number of libraries and their roles (core only, non-core only, shared by both core and non-core) were not easy to capture. Hereby, the base libraries have been reduced to the following few libraries: - startup.mk contains the startup code for normal Genode processes. On some platform, core is able to use the library as well. - base-common.mk contains the parts of the base library that are identical by core and non-core processes. - base.mk contains the complete base API implementation for non-core processes Consequently, the 'LIBS' declaration in 'target.mk' files becomes simpler as well. In the most simple case, only the 'base' library must be mentioned. Fixes #18
3080 lines
81 KiB
Diff
3080 lines
81 KiB
Diff
diff -urNpB kernel-2.6.23-v2/Kbuild contrib/Kbuild
|
|
--- kernel-2.6.23-v2/Kbuild
|
|
+++ contrib/Kbuild
|
|
@@ -57,4 +57,5 @@ quiet_cmd_syscalls = CALL $<
|
|
|
|
PHONY += missing-syscalls
|
|
missing-syscalls: scripts/checksyscalls.sh FORCE
|
|
- $(call cmd,syscalls)
|
|
+ @echo Ignoring $@
|
|
+# $(call cmd,syscalls)
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/Kconfig contrib/arch/l4/Kconfig
|
|
--- kernel-2.6.23-v2/arch/l4/Kconfig
|
|
+++ contrib/arch/l4/Kconfig
|
|
@@ -1,3 +1,5 @@
|
|
+mainmenu "OKLinux Kernel Configuration"
|
|
+
|
|
config L4
|
|
bool
|
|
default y
|
|
@@ -23,7 +25,7 @@ config RWSEM_GENERIC_SPINLOCK
|
|
bool
|
|
default y
|
|
|
|
-mainmenu "L4/Linux Kernel Configuration"
|
|
+#mainmenu "L4/Linux Kernel Configuration"
|
|
|
|
menu "L4/Linux-specific options"
|
|
|
|
@@ -33,19 +35,19 @@ config L4KDB_CONSOLE
|
|
|
|
config IG_SERIAL
|
|
bool "Compile Iguana virtual serial driver"
|
|
- default y
|
|
+ default n
|
|
|
|
config IG_INPUT
|
|
bool "Compile Iguana virtual input driver"
|
|
- default y
|
|
+ default n
|
|
|
|
config IG_MMC
|
|
bool "Compile Iguana virtual mmc/sd driver"
|
|
- default y
|
|
+ default n
|
|
|
|
config IG_NET
|
|
bool "Compile Iguana virtual net driver"
|
|
- default y
|
|
+ default n
|
|
|
|
config MTD_IGMTD
|
|
tristate "Iguana virtual MTD device"
|
|
@@ -69,13 +71,30 @@ config IG_AUDIO
|
|
config IG_TOUCH
|
|
bool "Compile Iguana virtual touch screen driver"
|
|
depends on INPUT && INPUT_TOUCHSCREEN
|
|
- default y
|
|
+ default n
|
|
|
|
config FB_IGVIRTUAL
|
|
tristate "Iguana Virtual Frame buffer support (ONLY FOR TESTING!)"
|
|
depends on FB
|
|
default n
|
|
|
|
+config SCREEN_GENODE
|
|
+ bool
|
|
+ select FB_CFB_FILLRECT
|
|
+ select FB_CFB_COPYAREA
|
|
+ select FB_CFB_IMAGEBLIT
|
|
+ default y
|
|
+
|
|
+config BLOCK_GENODE
|
|
+ bool
|
|
+ select BLOCK
|
|
+ default y
|
|
+
|
|
+config NET_GENODE
|
|
+ bool
|
|
+ select NET
|
|
+ default y
|
|
+
|
|
endmenu
|
|
|
|
config GENERIC_HWEIGHT
|
|
@@ -212,12 +231,12 @@ bool "Support for PLEB2 platform"
|
|
endchoice
|
|
|
|
config NODES_SHIFT
|
|
- int
|
|
- default 4
|
|
+ int "NODES_SHIFT"
|
|
+ default 5
|
|
# default "7" if MPENTIUM4 || X86_GENERIC
|
|
|
|
config L4_ZONE_SIZE
|
|
- int
|
|
+ int "L4_ZONE_SIZE"
|
|
default 22
|
|
# default "7" if MPENTIUM4 || X86_GENERIC
|
|
|
|
@@ -273,7 +292,7 @@ config CPU_HAS_LLDSCD
|
|
|
|
config GENERIC_CALIBRATE_DELAY
|
|
bool
|
|
- default y
|
|
+ default n
|
|
|
|
config ISA
|
|
bool
|
|
@@ -311,7 +330,7 @@ source "net/Kconfig"
|
|
source "fs/Kconfig"
|
|
config OKL4FS
|
|
bool
|
|
- default m
|
|
+ default n
|
|
|
|
source "drivers/mmc/Kconfig"
|
|
|
|
@@ -360,17 +379,17 @@ source "drivers/mca/Kconfig"
|
|
|
|
endmenu
|
|
|
|
-source "drivers/scsi/Kconfig"
|
|
+source "drivers/parport/Kconfig"
|
|
|
|
-source "drivers/ata/Kconfig"
|
|
+source "drivers/pnp/Kconfig"
|
|
|
|
-#source "security/Kconfig"
|
|
+source "drivers/misc/Kconfig"
|
|
|
|
-#source "crypto/Kconfig"
|
|
+source "drivers/scsi/Kconfig"
|
|
|
|
-source "lib/Kconfig"
|
|
+source "drivers/ata/Kconfig"
|
|
|
|
-#source "drivers/md/Kconfig"
|
|
+source "drivers/md/Kconfig"
|
|
|
|
source "drivers/mtd/Kconfig"
|
|
|
|
@@ -384,12 +403,24 @@ source "drivers/net/Kconfig"
|
|
|
|
source "drivers/hid/Kconfig"
|
|
|
|
+source "drivers/hwmon/Kconfig"
|
|
+
|
|
+source "drivers/media/Kconfig"
|
|
+
|
|
source "drivers/usb/Kconfig"
|
|
|
|
+source "drivers/leds/Kconfig"
|
|
+
|
|
source "sound/Kconfig"
|
|
|
|
source "drivers/i2c/Kconfig"
|
|
|
|
+source "security/Kconfig"
|
|
+
|
|
+source "crypto/Kconfig"
|
|
+
|
|
+source "lib/Kconfig"
|
|
+
|
|
menu "Kernel hacking"
|
|
|
|
source "lib/Kconfig.debug"
|
|
@@ -397,7 +428,7 @@ source "lib/Kconfig.debug"
|
|
config EARLY_PRINTK
|
|
bool "Early printk" if EMBEDDED
|
|
depends on L4KDB_CONSOLE
|
|
- default n
|
|
+ default y
|
|
help
|
|
Write kernel log output directly to L4 KDB.
|
|
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/Makefile contrib/arch/l4/Makefile
|
|
--- kernel-2.6.23-v2/arch/l4/Makefile
|
|
+++ contrib/arch/l4/Makefile
|
|
@@ -105,12 +105,21 @@ CFLAGS += -DCONFIG_HYBRID_MUTEXES
|
|
core-y += $(ARCH_DIR)/kernel/ \
|
|
$(ARCH_DIR)/mm/ \
|
|
$(ARCH_DIR)/lib/ \
|
|
- $(ARCH_DIR)/sys-$(SYSTEM)/ \
|
|
- $(ARCH_DIR)/kernel/fs/okl4fs/
|
|
+ $(ARCH_DIR)/sys-$(SYSTEM)/
|
|
+
|
|
+# $(ARCH_DIR)/kernel/fs/okl4fs
|
|
|
|
drivers-y += $(ARCH_DIR)/drivers/
|
|
|
|
-libs-y += -lvtimer -lvserial -ll4e -lll -liguana -ll4 -lgcc -lmutex -lcircular_buffer -lc -latomic_ops -lfs
|
|
+#libs-y += -lvtimer -lvserial -ll4e -lll -liguana -ll4 -lgcc -lmutex -lcircular_buffer -lc -latomic_ops -lfs
|
|
+
|
|
+GENODE_LIBS = base base-common cxx startup \
|
|
+ oklx
|
|
+
|
|
+libs-y += $(addprefix $(GENODE_LIBS_DIR)/,$(foreach l,$(GENODE_LIBS),$l/$l.lib.a))
|
|
+
|
|
+# link libgcc
|
|
+libs-y += $(shell $(CC) $(WOMBAT_CFLAGS) -print-libgcc-file-name)
|
|
|
|
#libs-$(CONFIG_ARCH_PXA) += -lpxa
|
|
|
|
@@ -128,7 +137,7 @@ AFLAGS += -D__arch_l4__ -D__SYSTEM__=$(S
|
|
|
|
CFLAGS += -Iarch/l4/include -Iinclude/asm-l4
|
|
CFLAGS += -I../include
|
|
-CFLAGS += -I../../../tools/magpie/include
|
|
+#CFLAGS += -I../../../tools/magpie/include
|
|
CFLAGS += $(WOMBAT_CFLAGS)
|
|
|
|
AFLAGS += -Iarch/l4/include
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/drivers/Makefile contrib/arch/l4/drivers/Makefile
|
|
--- kernel-2.6.23-v2/arch/l4/drivers/Makefile
|
|
+++ contrib/arch/l4/drivers/Makefile
|
|
@@ -1,4 +1,6 @@
|
|
-obj-y := ig_ramdisk.o
|
|
+obj-$(CONFIG_SCREEN_GENODE) += genode_fb.o
|
|
+obj-$(CONFIG_BLOCK_GENODE) += genode_block.o
|
|
+obj-$(CONFIG_NET_GENODE) += genode_net.o
|
|
obj-$(CONFIG_FB_IGVIRTUAL) += ig_fb.o cfbcopyarea.o cfbfillrect.o cfbimgblt.o
|
|
obj-$(CONFIG_L4KDB_CONSOLE) += l4kdb_console.o
|
|
obj-$(CONFIG_IG_SERIAL) += ig_serial.o
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/drivers/genode_block.c contrib/arch/l4/drivers/genode_block.c
|
|
--- kernel-2.6.23-v2/arch/l4/drivers/genode_block.c
|
|
+++ contrib/arch/l4/drivers/genode_block.c
|
|
@@ -0,0 +1,273 @@
|
|
+/*
|
|
+ * \brief Block driver to access Genode's block service
|
|
+ * \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
|
|
+ * \date 2010-07-08
|
|
+ *
|
|
+ * This file is based on the sbull block driver from
|
|
+ * Linux Device Drivers, 3rd edition chapter 16 "Block Drivers".
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Copyright (C) 2006-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.
|
|
+ */
|
|
+
|
|
+/* Linux includes */
|
|
+#include <linux/module.h>
|
|
+#include <linux/moduleparam.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/fs.h>
|
|
+#include <linux/errno.h>
|
|
+#include <linux/types.h>
|
|
+#include <linux/genhd.h>
|
|
+#include <linux/blkdev.h>
|
|
+#include <linux/hdreg.h>
|
|
+#include <asm/semaphore.h>
|
|
+
|
|
+/* Genode support library includes */
|
|
+#include <genode/config.h>
|
|
+#include <genode/block.h>
|
|
+
|
|
+enum Geometry {
|
|
+ KERNEL_SECTOR_SIZE = 512, /* sector size used by kernel */
|
|
+ GENODE_BLK_MINORS = 16 /* number of minor numbers */
|
|
+};
|
|
+
|
|
+
|
|
+/*
|
|
+ * The internal representation of our device.
|
|
+ */
|
|
+static struct genode_blk_device {
|
|
+ unsigned blk_cnt; /* Total block count */
|
|
+ unsigned long blk_sz; /* Single block size */
|
|
+ spinlock_t lock; /* For mutual exclusion */
|
|
+ struct gendisk *gd; /* Generic disk structure */
|
|
+ struct request_queue *queue; /* The device request queue */
|
|
+ struct semaphore queue_wait; /* Used to block, when queue is full */
|
|
+ short stopped; /* Indicates queue availability */
|
|
+} blk_dev;
|
|
+
|
|
+
|
|
+/*
|
|
+ * Handle an I/O request.
|
|
+ */
|
|
+static void genode_blk_request(struct request_queue *q)
|
|
+{
|
|
+ struct request *req;
|
|
+ unsigned long queue_offset;
|
|
+
|
|
+ while ((req = elv_next_request(q)) != NULL) {
|
|
+ void *buf = 0;
|
|
+ unsigned long offset = req->sector * KERNEL_SECTOR_SIZE;
|
|
+ unsigned long nbytes = req->nr_sectors * KERNEL_SECTOR_SIZE;
|
|
+ short write = rq_data_dir(req);
|
|
+
|
|
+ if (!blk_fs_request(req)) {
|
|
+ printk (KERN_NOTICE "Skip non-fs request\n");
|
|
+ end_request(req, 0);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ blkdev_dequeue_request(req);
|
|
+
|
|
+ while (!buf) {
|
|
+ if ((buf = genode_block_request(nbytes, req, &queue_offset)))
|
|
+ break;
|
|
+
|
|
+ /* stop_queue needs disabled interrupts */
|
|
+ isr_irq_disable();
|
|
+ blk_stop_queue(q);
|
|
+ isr_irq_enable();
|
|
+
|
|
+ /* block until new responses are available */
|
|
+ blk_dev.stopped = 1;
|
|
+ down(&blk_dev.queue_wait);
|
|
+
|
|
+ /* start_queue needs disabled interrupts */
|
|
+ isr_irq_disable();
|
|
+ blk_start_queue(q);
|
|
+ isr_irq_enable();
|
|
+ }
|
|
+
|
|
+ if (write) {
|
|
+ struct bio *bio;
|
|
+ struct bio_vec *bvec;
|
|
+ int idx;
|
|
+ char *ptr = (char*) buf;
|
|
+
|
|
+ rq_for_each_bio(bio, req) {
|
|
+ bio_for_each_segment(bvec, bio, idx) {
|
|
+ void *buffer = __bio_kmap_atomic(bio, idx, KM_USER0);
|
|
+ unsigned long sz = bio_cur_sectors(bio) * KERNEL_SECTOR_SIZE;
|
|
+ memcpy((void*)ptr, buffer, sz);
|
|
+ __bio_kunmap_atomic(buffer, KM_USER0);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ genode_block_submit(queue_offset, nbytes, offset, write);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+static void genode_end_request(void *request, short write,
|
|
+ void *buf, unsigned long sz) {
|
|
+ struct request *req = (struct request*) request;
|
|
+ char *ptr = (char*) buf;
|
|
+
|
|
+ if (!write) {
|
|
+ struct bio *bio;
|
|
+ struct bio_vec *bvec;
|
|
+ int idx;
|
|
+ rq_for_each_bio(bio, req) {
|
|
+ bio_for_each_segment(bvec, bio, idx) {
|
|
+ void *buffer = __bio_kmap_atomic(bio, idx, KM_USER0);
|
|
+ unsigned long nbytes = bio_cur_sectors(bio) * KERNEL_SECTOR_SIZE;
|
|
+ memcpy(buffer, (void*)ptr, nbytes);
|
|
+ ptr += nbytes;
|
|
+ __bio_kunmap_atomic(buffer, KM_USER0);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!end_that_request_first(req, 1, req->nr_sectors))
|
|
+ end_that_request_last(req, 1);
|
|
+
|
|
+ if (blk_dev.stopped) {
|
|
+ blk_dev.stopped = 0;
|
|
+ up(&blk_dev.queue_wait);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * Ioctl method.
|
|
+ */
|
|
+int genode_blk_ioctl (struct inode *inode, struct file *filp,
|
|
+ unsigned int cmd, unsigned long arg)
|
|
+{
|
|
+ struct hd_geometry geo;
|
|
+ struct genode_blk_device *dev = inode->i_bdev->bd_disk->private_data;
|
|
+
|
|
+ switch(cmd) {
|
|
+ case HDIO_GETGEO:
|
|
+ {
|
|
+ /*
|
|
+ * Get geometry: since we cannot access the real geometry of the
|
|
+ * device, we have to make up something plausible. So we claim
|
|
+ * 16 sectors, four heads, and calculate the corresponding number
|
|
+ * of cylinders. We set the start of data at sector four.
|
|
+ */
|
|
+ unsigned long size = dev->blk_cnt * dev->blk_sz *
|
|
+ (dev->blk_sz / KERNEL_SECTOR_SIZE);
|
|
+ geo.cylinders = (size & ~0x3f) >> 6;
|
|
+ geo.heads = 4;
|
|
+ geo.sectors = 16;
|
|
+ geo.start = 4;
|
|
+ if (copy_to_user((void *) arg, &geo, sizeof(geo)))
|
|
+ return -EFAULT;
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ return -ENOTTY; /* unknown command */
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * The device operations structure.
|
|
+ */
|
|
+static struct block_device_operations genode_blk_ops = {
|
|
+ .owner = THIS_MODULE,
|
|
+ .ioctl = genode_blk_ioctl
|
|
+};
|
|
+
|
|
+static int __init genode_blk_init(void)
|
|
+{
|
|
+ int major_num;
|
|
+ int writeable = 0;
|
|
+ unsigned long req_queue_sz = 0;
|
|
+
|
|
+ if (!genode_config_block())
|
|
+ return 0;
|
|
+
|
|
+ /* Initialize device structure */
|
|
+ memset (&blk_dev, 0, sizeof (struct genode_blk_device));
|
|
+ spin_lock_init(&blk_dev.lock);
|
|
+
|
|
+ genode_block_geometry((unsigned long*)&blk_dev.blk_cnt,
|
|
+ &blk_dev.blk_sz, &writeable, &req_queue_sz);
|
|
+
|
|
+ genode_block_register_callback(genode_end_request);
|
|
+
|
|
+ /*
|
|
+ * Get a request queue.
|
|
+ */
|
|
+ if(!(blk_dev.queue = blk_init_queue(genode_blk_request, &blk_dev.lock)))
|
|
+ return -ENOMEM;
|
|
+
|
|
+ /*
|
|
+ * Align queue requests to hardware sector size.
|
|
+ */
|
|
+ blk_queue_hardsect_size(blk_dev.queue, blk_dev.blk_sz);
|
|
+
|
|
+ /*
|
|
+ * Important, limit number of sectors per request,
|
|
+ * as Genode's block-session has a limited request-transmit-queue.
|
|
+ */
|
|
+ blk_queue_max_sectors(blk_dev.queue, req_queue_sz / KERNEL_SECTOR_SIZE);
|
|
+ blk_dev.queue->queuedata = &blk_dev;
|
|
+
|
|
+ sema_init(&blk_dev.queue_wait, 0);
|
|
+ blk_dev.stopped = 0;
|
|
+
|
|
+ /*
|
|
+ * Register block device and gain major number.
|
|
+ */
|
|
+ if((major_num = register_blkdev(0, "genode_blk")) < 0) {
|
|
+ printk(KERN_WARNING "genode_blk: unable to get major number\n");
|
|
+ return -EBUSY;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Allocate and setup generic disk structure.
|
|
+ */
|
|
+ if(!(blk_dev.gd = alloc_disk(GENODE_BLK_MINORS))) {
|
|
+ unregister_blkdev(major_num, "genode_blk");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ blk_dev.gd->major = major_num;
|
|
+ blk_dev.gd->first_minor = 0;
|
|
+ blk_dev.gd->fops = &genode_blk_ops;
|
|
+ blk_dev.gd->private_data = &blk_dev;
|
|
+ blk_dev.gd->queue = blk_dev.queue;
|
|
+ strncpy(blk_dev.gd->disk_name, "sda", sizeof(blk_dev.gd->disk_name));
|
|
+ set_capacity(blk_dev.gd, blk_dev.blk_cnt *
|
|
+ (blk_dev.blk_sz / KERNEL_SECTOR_SIZE));
|
|
+
|
|
+ /* Set it read-only or writeable */
|
|
+ if(!writeable)
|
|
+ set_disk_ro(blk_dev.gd, 1);
|
|
+
|
|
+ /* Make the block device available to the system */
|
|
+ add_disk(blk_dev.gd);
|
|
+ printk("Genode blk-file driver initialized\n");
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static void __exit
|
|
+genode_blk_exit(void)
|
|
+{
|
|
+ del_gendisk(blk_dev.gd);
|
|
+ put_disk(blk_dev.gd);
|
|
+ unregister_blkdev(blk_dev.gd->major, "genode_blk");
|
|
+ blk_cleanup_queue(blk_dev.queue);
|
|
+}
|
|
+
|
|
+module_init(genode_blk_init);
|
|
+module_exit(genode_blk_exit);
|
|
+
|
|
+MODULE_LICENSE("GPL");
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/drivers/genode_fb.c contrib/arch/l4/drivers/genode_fb.c
|
|
--- kernel-2.6.23-v2/arch/l4/drivers/genode_fb.c
|
|
+++ contrib/arch/l4/drivers/genode_fb.c
|
|
@@ -0,0 +1,511 @@
|
|
+/*
|
|
+ * \brief Genode screen driver
|
|
+ * \author Stefan Kalkowski <kalkowski@genode-labs.com>
|
|
+ * \date 2010-04-20
|
|
+ *
|
|
+ * This driver enables usage of any of Genode's framebuffer, input
|
|
+ * and nitpicker sessions, as defined in Linux corresponding XML config stub.
|
|
+ * The implementation is based on virtual (vfb.c) and
|
|
+ * L4 (l4fb.c) framebuffer driver of L4Linux from TU-Dresden.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Copyright (C) 2010-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.
|
|
+ */
|
|
+
|
|
+/* Linux includes */
|
|
+#include <linux/module.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/errno.h>
|
|
+#include <linux/string.h>
|
|
+#include <linux/mm.h>
|
|
+#include <linux/tty.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/delay.h>
|
|
+#include <linux/fb.h>
|
|
+#include <linux/proc_fs.h>
|
|
+#include <linux/input.h>
|
|
+#include <linux/platform_device.h>
|
|
+#include <linux/screen_info.h>
|
|
+
|
|
+/* Platform includes */
|
|
+#include <asm/uaccess.h>
|
|
+
|
|
+/* Genode support lib includes */
|
|
+#include <genode/framebuffer.h>
|
|
+#include <genode/input.h>
|
|
+#include <oklx/ioctl.h>
|
|
+
|
|
+
|
|
+/**********************************
|
|
+ ** Datastructure declarations **
|
|
+ **********************************/
|
|
+
|
|
+/**
|
|
+ * List of available framebuffers (used by device->driver_data)
|
|
+ */
|
|
+struct genodefb_infolist {
|
|
+ struct fb_info *info;
|
|
+ struct genodefb_infolist *next;
|
|
+};
|
|
+
|
|
+
|
|
+/**********************
|
|
+ ** Global variables **
|
|
+ **********************/
|
|
+
|
|
+static const char GENODEFB_DRV_NAME[] = "genodefb";
|
|
+
|
|
+static struct fb_var_screeninfo genodefb_var __initdata = {
|
|
+ .activate = FB_ACTIVATE_NOW,
|
|
+ .height = -1,
|
|
+ .width = -1,
|
|
+ .right_margin = 32,
|
|
+ .upper_margin = 16,
|
|
+ .lower_margin = 4,
|
|
+ .vsync_len = 4,
|
|
+ .vmode = FB_VMODE_NONINTERLACED,
|
|
+ .bits_per_pixel = 16, // Genode only supports RGB565 by now */
|
|
+ .red.length = 5,
|
|
+ .red.offset = 11,
|
|
+ .green.length = 6,
|
|
+ .green.offset = 5,
|
|
+ .blue.length = 5,
|
|
+ .blue.offset = 0,
|
|
+ .transp.length = 0,
|
|
+ .transp.offset = 0,
|
|
+};
|
|
+
|
|
+static struct fb_fix_screeninfo genodefb_fix __initdata = {
|
|
+ .id = "genode_fb",
|
|
+ .type = FB_TYPE_PACKED_PIXELS,
|
|
+ .accel = FB_ACCEL_NONE,
|
|
+ .visual = FB_VISUAL_TRUECOLOR,
|
|
+ .ypanstep = 0,
|
|
+ .ywrapstep = 0,
|
|
+};
|
|
+
|
|
+static u32 pseudo_palette[17];
|
|
+
|
|
+
|
|
+/*************************
|
|
+ ** Device operations **
|
|
+ *************************/
|
|
+
|
|
+/*
|
|
+ * Set a single color register. The values supplied are
|
|
+ * already rounded down to the hardware's capabilities
|
|
+ * (according to the entries in the `var' structure). Return
|
|
+ * != 0 for invalid regno and pixel formats.
|
|
+ */
|
|
+static int genodefb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
|
+ unsigned blue, unsigned transp,
|
|
+ struct fb_info *info)
|
|
+{
|
|
+ if (regno >= info->cmap.len || info->var.bits_per_pixel != 16)
|
|
+ return 1;
|
|
+
|
|
+ if (regno < 16)
|
|
+ ((u32*) (info->pseudo_palette))[regno] =
|
|
+ ((red >> (16 - info->var.red.length)) << info->var.red.offset) |
|
|
+ ((green >> (16 - info->var.green.length)) << info->var.green.offset) |
|
|
+ ((blue >> (16 - info->var.blue.length)) << info->var.blue.offset);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * Pan or Wrap the Display
|
|
+ *
|
|
+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
|
|
+ */
|
|
+static int genodefb_pan_display(struct fb_var_screeninfo *var,
|
|
+ struct fb_info *info)
|
|
+{
|
|
+ if (var->vmode & FB_VMODE_YWRAP) {
|
|
+ if (var->yoffset < 0
|
|
+ || var->yoffset >= info->var.yres_virtual
|
|
+ || var->xoffset)
|
|
+ return -EINVAL;
|
|
+ } else {
|
|
+ if (var->xoffset + var->xres > info->var.xres_virtual ||
|
|
+ var->yoffset + var->yres > info->var.yres_virtual)
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ info->var.xoffset = var->xoffset;
|
|
+ info->var.yoffset = var->yoffset;
|
|
+ if (var->vmode & FB_VMODE_YWRAP)
|
|
+ info->var.vmode |= FB_VMODE_YWRAP;
|
|
+ else
|
|
+ info->var.vmode &= ~FB_VMODE_YWRAP;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static void genodefb_copyarea(struct fb_info *info,
|
|
+ const struct fb_copyarea *region)
|
|
+{
|
|
+ cfb_copyarea(info, region);
|
|
+ genode_fb_refresh(info->node, region->dx, region->dy,
|
|
+ region->width, region->height);
|
|
+}
|
|
+
|
|
+
|
|
+static void genodefb_fillrect(struct fb_info *info,
|
|
+ const struct fb_fillrect *rect)
|
|
+{
|
|
+ cfb_fillrect(info, rect);
|
|
+ genode_fb_refresh(info->node, rect->dx, rect->dy,
|
|
+ rect->width, rect->height);
|
|
+}
|
|
+
|
|
+
|
|
+static void genodefb_imageblit(struct fb_info *info,
|
|
+ const struct fb_image *image)
|
|
+{
|
|
+ cfb_imageblit(info, image);
|
|
+ genode_fb_refresh(info->node, image->dx, image->dy,
|
|
+ image->width, image->height);
|
|
+}
|
|
+
|
|
+
|
|
+static int genodefb_open(struct fb_info *info, int user)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static int genodefb_release(struct fb_info *info, int user)
|
|
+{
|
|
+ genode_nit_close_all_views(info->node);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static int genodefb_ioctl(struct fb_info *info, unsigned int cmd,
|
|
+ unsigned long arg)
|
|
+{
|
|
+ void __user *argp = (void __user *)arg;
|
|
+ switch (cmd) {
|
|
+ case NITPICKER_IOCTL_CREATE_VIEW:
|
|
+ {
|
|
+ genode_nit_view_create(info->node, (int)arg);
|
|
+ break;
|
|
+ }
|
|
+ case NITPICKER_IOCTL_DESTROY_VIEW:
|
|
+ {
|
|
+ genode_nit_view_destroy(info->node, (int)arg);
|
|
+ break;
|
|
+ }
|
|
+ case NITPICKER_IOCTL_BACK_VIEW:
|
|
+ {
|
|
+ genode_nit_view_back(info->node, (int)arg);
|
|
+ break;
|
|
+ }
|
|
+ case NITPICKER_IOCTL_PLACE_VIEW:
|
|
+ {
|
|
+ struct genode_view_place val;
|
|
+ if (copy_from_user(&val, argp, sizeof(val)))
|
|
+ return -EFAULT;
|
|
+ genode_nit_view_place(info->node, val.view, val.reg.x,
|
|
+ val.reg.y, val.reg.w, val.reg.h);
|
|
+ break;
|
|
+ }
|
|
+ case NITPICKER_IOCTL_STACK_VIEW:
|
|
+ {
|
|
+ struct genode_view_stack val;
|
|
+ if (copy_from_user(&val, argp, sizeof(val)))
|
|
+ return -EFAULT;
|
|
+ genode_nit_view_stack(info->node, val.view,
|
|
+ val.neighbor, val.behind);
|
|
+ break;
|
|
+ }
|
|
+ case FRAMEBUFFER_IOCTL_REFRESH:
|
|
+ {
|
|
+ struct genode_screen_region val;
|
|
+ if (copy_from_user(&val, argp, sizeof(val)))
|
|
+ return -EFAULT;
|
|
+ genode_fb_refresh(info->node, val.x, val.y, val.w, val.h);
|
|
+ break;
|
|
+ }
|
|
+ default:
|
|
+ printk(KERN_INFO "Unknown ioctl command: %d\n", cmd);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static struct fb_ops genodefb_ops = {
|
|
+ .owner = THIS_MODULE,
|
|
+ .fb_open = genodefb_open,
|
|
+ .fb_release = genodefb_release,
|
|
+ .fb_setcolreg = genodefb_setcolreg,
|
|
+ .fb_pan_display = genodefb_pan_display,
|
|
+ .fb_fillrect = genodefb_fillrect,
|
|
+ .fb_ioctl = genodefb_ioctl,
|
|
+ .fb_copyarea = genodefb_copyarea,
|
|
+ .fb_imageblit = genodefb_imageblit,
|
|
+};
|
|
+
|
|
+
|
|
+/***********************
|
|
+ ** Input callbacks **
|
|
+ ***********************/
|
|
+
|
|
+void input_event_callback (void *dev, unsigned int type,
|
|
+ unsigned int code, int value)
|
|
+{
|
|
+ struct input_dev *input_dev = (struct input_dev*) dev;
|
|
+ input_event(input_dev, type, code, value);
|
|
+ input_sync(input_dev);
|
|
+}
|
|
+
|
|
+
|
|
+/***************************************
|
|
+ ** Device initialization / removal **
|
|
+ ***************************************/
|
|
+
|
|
+static int __init genodefb_register_input_devices(unsigned int idx,
|
|
+ unsigned int xres,
|
|
+ unsigned int yres)
|
|
+{
|
|
+ int i;
|
|
+ struct input_dev *mouse_dev = input_allocate_device();
|
|
+ struct input_dev *keyb_dev = input_allocate_device();
|
|
+ if (!keyb_dev || !mouse_dev)
|
|
+ return -ENOMEM;
|
|
+
|
|
+
|
|
+ /****************
|
|
+ ** Keyboard **
|
|
+ ****************/
|
|
+
|
|
+ keyb_dev->name = "Genode input key";
|
|
+ keyb_dev->phys = "Genode fb key";
|
|
+ keyb_dev->id.bustype = BUS_USB;
|
|
+ keyb_dev->id.vendor = 0;
|
|
+ keyb_dev->id.product = 0;
|
|
+ keyb_dev->id.version = 0;
|
|
+
|
|
+ /* We generate key events */
|
|
+ set_bit(EV_KEY, keyb_dev->evbit);
|
|
+ set_bit(EV_REP, keyb_dev->evbit);
|
|
+
|
|
+ /* We can generate every key */
|
|
+ for (i = 0; i < 0x100; i++)
|
|
+ set_bit(i, keyb_dev->keybit);
|
|
+
|
|
+ /* Register keyboard device */
|
|
+ input_register_device(keyb_dev);
|
|
+ genode_input_register_keyb(idx, (void*) keyb_dev);
|
|
+
|
|
+
|
|
+ /*************
|
|
+ ** Mouse **
|
|
+ *************/
|
|
+
|
|
+ mouse_dev->name = "Genode input mouse";
|
|
+ mouse_dev->phys = "Genode mouse";
|
|
+ mouse_dev->id.bustype = BUS_USB;
|
|
+ mouse_dev->id.vendor = 0;
|
|
+ mouse_dev->id.product = 0;
|
|
+ mouse_dev->id.version = 0;
|
|
+
|
|
+ /* We generate key and relative mouse events */
|
|
+ set_bit(EV_KEY, mouse_dev->evbit);
|
|
+ set_bit(EV_REP, mouse_dev->evbit);
|
|
+ set_bit(EV_REL, mouse_dev->evbit);
|
|
+ set_bit(EV_ABS, mouse_dev->evbit);
|
|
+
|
|
+ /* Buttons */
|
|
+ set_bit(BTN_0, mouse_dev->keybit);
|
|
+ set_bit(BTN_1, mouse_dev->keybit);
|
|
+ set_bit(BTN_2, mouse_dev->keybit);
|
|
+ set_bit(BTN_3, mouse_dev->keybit);
|
|
+ set_bit(BTN_4, mouse_dev->keybit);
|
|
+ set_bit(BTN_LEFT, mouse_dev->keybit);
|
|
+ set_bit(BTN_RIGHT, mouse_dev->keybit);
|
|
+ set_bit(BTN_MIDDLE, mouse_dev->keybit);
|
|
+
|
|
+ /* Movements */
|
|
+ set_bit(REL_X, mouse_dev->relbit);
|
|
+ set_bit(REL_Y, mouse_dev->relbit);
|
|
+ set_bit(ABS_X, mouse_dev->absbit);
|
|
+ set_bit(ABS_Y, mouse_dev->absbit);
|
|
+
|
|
+ /* Coordinates are 1:1 pixel in frame buffer */
|
|
+ mouse_dev->absmax[ABS_X] = xres;
|
|
+ mouse_dev->absmax[ABS_Y] = yres;
|
|
+ mouse_dev->absmin[ABS_X] = 0;
|
|
+ mouse_dev->absmin[ABS_Y] = 0;
|
|
+
|
|
+ /* We are precise */
|
|
+ mouse_dev->absfuzz[ABS_X] = 0;
|
|
+ mouse_dev->absfuzz[ABS_Y] = 0;
|
|
+ mouse_dev->absflat[ABS_X] = 0;
|
|
+ mouse_dev->absflat[ABS_Y] = 0;
|
|
+
|
|
+ /* Register mouse device */
|
|
+ input_register_device(mouse_dev);
|
|
+ genode_input_register_mouse(idx, (void*) mouse_dev);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static int __init genodefb_probe(struct platform_device *dev)
|
|
+{
|
|
+ struct genodefb_infolist *pred=0, *succ;
|
|
+ int i, ret, cnt = genode_screen_count();
|
|
+
|
|
+ /*
|
|
+ * Iterate through all available framebuffers
|
|
+ */
|
|
+ for (i=0; i < cnt; i++) {
|
|
+
|
|
+ /* Allocate new framebuffer list entry */
|
|
+ if(!(succ = kmalloc(sizeof(struct genodefb_infolist), GFP_KERNEL)))
|
|
+ return -ENOMEM;
|
|
+ succ->next = 0;
|
|
+
|
|
+ /* Set first entry as driver's private data, else concatenate it */
|
|
+ if (!i)
|
|
+ platform_set_drvdata(dev, succ);
|
|
+ else
|
|
+ pred->next = succ;
|
|
+ pred = succ;
|
|
+
|
|
+ /* Allocate new framebuffer info struct */
|
|
+ pred->info = framebuffer_alloc(0, &dev->dev);
|
|
+ if (!pred->info)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ /* Copy default values */
|
|
+ pred->info->var = genodefb_var;
|
|
+ pred->info->fix = genodefb_fix;
|
|
+
|
|
+ /* Get framebuffer dimensions from Genode's support lib */
|
|
+ pred->info->screen_base = genode_fb_attach(i);
|
|
+ pred->info->screen_size = genode_fb_size(i);
|
|
+ pred->info->fix.smem_start = (unsigned long) pred->info->screen_base;
|
|
+ pred->info->fix.smem_len = pred->info->screen_size;
|
|
+ if (!pred->info->screen_base || !pred->info->screen_size) {
|
|
+ printk(KERN_ERR "genode_fb: abort, could not be initialized.\n");
|
|
+ framebuffer_release(pred->info);
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
+ /* Get framebuffer resolution from Genode's support lib */
|
|
+ genode_fb_info(i, &pred->info->var.xres, &pred->info->var.yres);
|
|
+
|
|
+ /* We only support 16-Bit Pixel, so line length is xres*2 */
|
|
+ pred->info->fix.line_length = pred->info->var.xres * 2;
|
|
+
|
|
+ /* Set virtual resolution to visible resolution */
|
|
+ pred->info->var.xres_virtual = pred->info->var.xres;
|
|
+ pred->info->var.yres_virtual = pred->info->screen_size
|
|
+ / pred->info->fix.line_length;
|
|
+
|
|
+ /* Some dummy values for timing to make fbset happy */
|
|
+ pred->info->var.pixclock = 10000000 / pred->info->var.xres
|
|
+ * 1000 / pred->info->var.yres;
|
|
+ pred->info->var.left_margin = (pred->info->var.xres / 8) & 0xf8;
|
|
+ pred->info->var.hsync_len = (pred->info->var.xres / 8) & 0xf8;
|
|
+
|
|
+ pred->info->fbops = &genodefb_ops;
|
|
+ pred->info->pseudo_palette = pseudo_palette;
|
|
+ pred->info->flags = FBINFO_FLAG_DEFAULT;
|
|
+
|
|
+ printk(KERN_INFO "genode_fb:framebuffer at 0x%p, size %dk\n",
|
|
+ pred->info->screen_base, (int)(pred->info->screen_size >> 10));
|
|
+ printk(KERN_INFO "genode_fb: mode is %dx%dx%d\n",
|
|
+ pred->info->var.xres, pred->info->var.yres,
|
|
+ pred->info->var.bits_per_pixel);
|
|
+
|
|
+ /* Allocate 16-Bit colormap */
|
|
+ ret = fb_alloc_cmap(&pred->info->cmap, 16, 0);
|
|
+ if (ret < 0) {
|
|
+ framebuffer_release(pred->info);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ /* Register framebuffer info structure */
|
|
+ if (register_framebuffer(pred->info) < 0) {
|
|
+ fb_dealloc_cmap(&pred->info->cmap);
|
|
+ framebuffer_release(pred->info);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ ret = genodefb_register_input_devices(i, pred->info->var.xres,
|
|
+ pred->info->var.yres);
|
|
+ if (ret) {
|
|
+ fb_dealloc_cmap(&pred->info->cmap);
|
|
+ framebuffer_release(pred->info);
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static int genodefb_remove(struct platform_device *device)
|
|
+{
|
|
+ struct genodefb_infolist *succ = platform_get_drvdata(device);
|
|
+
|
|
+ while (succ && succ->info) {
|
|
+ struct genodefb_infolist *pred = succ;
|
|
+ succ = succ->next;
|
|
+ genode_fb_close(pred->info->node);
|
|
+ unregister_framebuffer(pred->info);
|
|
+ framebuffer_release(pred->info);
|
|
+ kfree(pred);
|
|
+ }
|
|
+ platform_set_drvdata(device, 0);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+/***************************************
|
|
+ ** Module initialization / removal **
|
|
+ ***************************************/
|
|
+
|
|
+static struct platform_driver genodefb_driver = {
|
|
+ .probe = genodefb_probe,
|
|
+ .remove = genodefb_remove,
|
|
+ .driver.name = GENODEFB_DRV_NAME,
|
|
+};
|
|
+
|
|
+static struct platform_device genodefb_device = {
|
|
+ .name = GENODEFB_DRV_NAME,
|
|
+};
|
|
+
|
|
+
|
|
+static int __init genodefb_init(void)
|
|
+{
|
|
+ int ret = platform_driver_register(&genodefb_driver);
|
|
+ if (!ret) {
|
|
+ ret = platform_device_register(&genodefb_device);
|
|
+ if (ret)
|
|
+ platform_driver_unregister(&genodefb_driver);
|
|
+ }
|
|
+ genode_input_register_callback(&input_event_callback);
|
|
+ return ret;
|
|
+}
|
|
+module_init(genodefb_init);
|
|
+
|
|
+
|
|
+static void __exit genodefb_exit(void)
|
|
+{
|
|
+ platform_device_unregister(&genodefb_device);
|
|
+ platform_driver_unregister(&genodefb_driver);
|
|
+ genode_input_unregister_callback();
|
|
+}
|
|
+module_exit(genodefb_exit);
|
|
+
|
|
+
|
|
+MODULE_AUTHOR("Stefan Kalkowski <stefan.kalkowski@genode-labs.com>");
|
|
+MODULE_DESCRIPTION("Frame buffer driver for OKLinux on Genode");
|
|
+MODULE_LICENSE("GPL v2");
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/drivers/genode_net.c contrib/arch/l4/drivers/genode_net.c
|
|
--- kernel-2.6.23-v2/arch/l4/drivers/genode_net.c
|
|
+++ contrib/arch/l4/drivers/genode_net.c
|
|
@@ -0,0 +1,165 @@
|
|
+/*
|
|
+ * \brief NIC driver to access Genode's nic service
|
|
+ * \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
|
|
+ * \date 2010-09-09
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Copyright (C) 2006-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.
|
|
+ */
|
|
+
|
|
+/* Linux includes */
|
|
+#include <linux/etherdevice.h>
|
|
+#include <linux/errno.h>
|
|
+#include <linux/inet.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/jiffies.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/netdevice.h>
|
|
+#include <linux/string.h>
|
|
+#include <linux/types.h>
|
|
+
|
|
+#include <genode/net.h>
|
|
+
|
|
+static struct net_device *net_dev;
|
|
+
|
|
+
|
|
+static void genode_net_receive_packet(void* dev_addr, void *addr,
|
|
+ unsigned long size)
|
|
+{
|
|
+ struct net_device *dev = (struct net_device *) dev_addr;
|
|
+ struct net_device_stats *stats = (struct net_device_stats*) netdev_priv(dev);
|
|
+
|
|
+ /* allocate skb */
|
|
+ struct sk_buff *skb = dev_alloc_skb(size + 2);
|
|
+ if (!skb) {
|
|
+ if (printk_ratelimit())
|
|
+ printk(KERN_NOTICE "genode_net_rx: low on mem - packet dropped!\n");
|
|
+ stats->rx_dropped++;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /* copy packet */
|
|
+ memcpy(skb_put(skb, size), addr, size);
|
|
+
|
|
+ skb->dev = dev;
|
|
+ skb->protocol = eth_type_trans(skb, dev);
|
|
+ skb->ip_summed = CHECKSUM_NONE;
|
|
+ netif_rx(skb);
|
|
+
|
|
+ stats->rx_packets++;
|
|
+ stats->rx_bytes += size;
|
|
+}
|
|
+
|
|
+
|
|
+/********************************
|
|
+ ** Network driver functions **
|
|
+ ********************************/
|
|
+
|
|
+int genode_net_open(struct net_device *dev)
|
|
+{
|
|
+ genode_net_start(dev, genode_net_receive_packet);
|
|
+ netif_start_queue(dev);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int genode_net_close(struct net_device *dev)
|
|
+{
|
|
+ netif_stop_queue(dev);
|
|
+ genode_net_stop();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int genode_net_xmit_frame(struct sk_buff *skb, struct net_device *dev)
|
|
+{
|
|
+ struct net_device_stats *stats = (struct net_device_stats*) netdev_priv(dev);
|
|
+ int len = skb->len;
|
|
+ void* addr = skb->data;
|
|
+
|
|
+ /* collect acknowledgements of old packets */
|
|
+ while (genode_net_tx_ack_avail())
|
|
+ dev_kfree_skb((struct sk_buff *)genode_net_tx_ack());
|
|
+
|
|
+ /* transmit to nic-session */
|
|
+ if (genode_net_tx(addr, len, skb)) {
|
|
+ /* tx queue is full, could not enqueue packet */
|
|
+ netif_stop_queue(dev);
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ /* save timestamp */
|
|
+ dev->trans_start = jiffies;
|
|
+
|
|
+ stats->tx_packets++;
|
|
+ stats->tx_bytes += len;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+struct net_device_stats* genode_net_get_stats(struct net_device *dev)
|
|
+{
|
|
+ return (struct net_device_stats*) netdev_priv(dev);
|
|
+}
|
|
+
|
|
+
|
|
+void genode_net_tx_timeout(struct net_device *dev)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+/**************************
|
|
+ ** De-/Initialization **
|
|
+ **************************/
|
|
+
|
|
+/* Setup and register the device. */
|
|
+static int __init genode_net_init(void)
|
|
+{
|
|
+ int err = 0;
|
|
+
|
|
+ if (!genode_net_ready())
|
|
+ return 0;
|
|
+
|
|
+ /* allocate network device */
|
|
+ if (!(net_dev = alloc_etherdev(sizeof(struct net_device_stats))))
|
|
+ goto out;
|
|
+
|
|
+ net_dev->open = genode_net_open;
|
|
+ net_dev->stop = genode_net_close;
|
|
+ net_dev->hard_start_xmit = genode_net_xmit_frame;
|
|
+ net_dev->get_stats = genode_net_get_stats;
|
|
+ net_dev->tx_timeout = genode_net_tx_timeout;
|
|
+ net_dev->watchdog_timeo = 20 * HZ;
|
|
+
|
|
+ /* set MAC address */
|
|
+ genode_net_mac(net_dev->dev_addr, ETH_ALEN);
|
|
+
|
|
+ /* register network device */
|
|
+ if ((err = register_netdev(net_dev))) {
|
|
+ panic("loopback: Failed to register netdevice: %d\n", err);
|
|
+ goto out_free;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+
|
|
+out_free:
|
|
+ free_netdev(net_dev);
|
|
+out:
|
|
+ return err;
|
|
+};
|
|
+
|
|
+
|
|
+static void __exit genode_net_exit(void)
|
|
+{
|
|
+ unregister_netdev(net_dev);
|
|
+ free_netdev(net_dev);
|
|
+}
|
|
+
|
|
+
|
|
+module_init(genode_net_init);
|
|
+module_exit(genode_net_exit);
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/drivers/l4kdb_console.c contrib/arch/l4/drivers/l4kdb_console.c
|
|
--- kernel-2.6.23-v2/arch/l4/drivers/l4kdb_console.c
|
|
+++ contrib/arch/l4/drivers/l4kdb_console.c
|
|
@@ -4,28 +4,25 @@
|
|
|
|
#include <l4/kdebug.h>
|
|
|
|
+#include <genode/printf.h>
|
|
+
|
|
static void l4kdb_cons_write(struct console *co, const char *p, unsigned count)
|
|
{
|
|
- while (count-- > 0) {
|
|
- L4_KDB_PrintChar(*p++);
|
|
- }
|
|
+ char buf[count+1];
|
|
+ int i;
|
|
+ for(i=0; i<count; ++i)
|
|
+ buf[i]=p[i];
|
|
+ buf[i]=0;
|
|
+ genode_printf(buf);
|
|
}
|
|
|
|
static struct console l4kdb_cons = {
|
|
- .name = "l4con",
|
|
+ .name = "ttyKDB",
|
|
.write = l4kdb_cons_write,
|
|
.flags = CON_PRINTBUFFER,
|
|
.index = -1,
|
|
};
|
|
|
|
-static int __init l4kdb_console_init(void)
|
|
-{
|
|
- register_console(&l4kdb_cons);
|
|
- return 0;
|
|
-}
|
|
-
|
|
-console_initcall(l4kdb_console_init);
|
|
-
|
|
#ifdef CONFIG_EARLY_PRINTK
|
|
void
|
|
enable_early_printk(void)
|
|
@@ -38,5 +35,16 @@ disable_early_printk(void)
|
|
{
|
|
unregister_console(&l4kdb_cons);
|
|
}
|
|
+
|
|
+#else
|
|
+
|
|
+static int __init l4kdb_console_init(void)
|
|
+{
|
|
+ register_console(&l4kdb_cons);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+console_initcall(l4kdb_console_init);
|
|
+
|
|
#endif
|
|
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/include/wombat.h contrib/arch/l4/include/wombat.h
|
|
--- kernel-2.6.23-v2/arch/l4/include/wombat.h
|
|
+++ contrib/arch/l4/include/wombat.h
|
|
@@ -2,7 +2,7 @@
|
|
#include <linux/mm.h>
|
|
#include <asm/mmzone.h>
|
|
|
|
-#define STACK_SIZE 0x2000
|
|
+#define STACK_SIZE 0x4000
|
|
|
|
extern cap_t *first_cap;
|
|
extern bootmem_area_t bootmem_area[MAX_PHYSMEM_RANGES];
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/Makefile contrib/arch/l4/kernel/Makefile
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/Makefile
|
|
+++ contrib/arch/l4/kernel/Makefile
|
|
@@ -3,7 +3,11 @@ core-y += arch/l4/kernel/fs/
|
|
obj-y := reboot.o glue.o main.o init_task.o time.o memcpy_user.o \
|
|
syscalls.o proc.o process.o syscall_impl.o setup.o \
|
|
signal.o sys_iguana.o cache.o exit.o syscall_loop.o \
|
|
- mmap.o irq.o intervm_loop.o
|
|
+ mmap.o irq.o intervm_loop.o calibrate.o
|
|
+
|
|
+# Genode specific
|
|
+obj-y := $(filter-out intervm_loop.o sys_iguana.o,$(obj-y))
|
|
+obj-y += sys_genode.o
|
|
|
|
obj-$(CONFIG_MODULES) += syms.o
|
|
obj-$(CONFIG_ARCH_ARM) += memcpy_user_armshared.o
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/calibrate.c contrib/arch/l4/kernel/calibrate.c
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/calibrate.c
|
|
+++ contrib/arch/l4/kernel/calibrate.c
|
|
@@ -0,0 +1,179 @@
|
|
+/* calibrate.c: default delay calibration
|
|
+ *
|
|
+ * Excised from init/main.c
|
|
+ * Copyright (C) 1991, 1992 Linus Torvalds
|
|
+ */
|
|
+
|
|
+#include <linux/jiffies.h>
|
|
+#include <linux/delay.h>
|
|
+#include <linux/init.h>
|
|
+
|
|
+#include <asm/timex.h>
|
|
+
|
|
+#include <genode/lock.h>
|
|
+
|
|
+extern void* timer_main_kernel_lock;
|
|
+
|
|
+static unsigned long preset_lpj;
|
|
+static int __init lpj_setup(char *str)
|
|
+{
|
|
+ preset_lpj = simple_strtoul(str,NULL,0);
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+__setup("lpj=", lpj_setup);
|
|
+
|
|
+#ifdef ARCH_HAS_READ_CURRENT_TIMER
|
|
+
|
|
+/* This routine uses the read_current_timer() routine and gets the
|
|
+ * loops per jiffy directly, instead of guessing it using delay().
|
|
+ * Also, this code tries to handle non-maskable asynchronous events
|
|
+ * (like SMIs)
|
|
+ */
|
|
+#define DELAY_CALIBRATION_TICKS ((HZ < 100) ? 1 : (HZ/100))
|
|
+#define MAX_DIRECT_CALIBRATION_RETRIES 5
|
|
+
|
|
+static unsigned long __devinit calibrate_delay_direct(void)
|
|
+{
|
|
+ unsigned long pre_start, start, post_start;
|
|
+ unsigned long pre_end, end, post_end;
|
|
+ unsigned long start_jiffies;
|
|
+ unsigned long tsc_rate_min, tsc_rate_max;
|
|
+ unsigned long good_tsc_sum = 0;
|
|
+ unsigned long good_tsc_count = 0;
|
|
+ int i;
|
|
+
|
|
+ if (read_current_timer(&pre_start) < 0 )
|
|
+ return 0;
|
|
+
|
|
+ /*
|
|
+ * A simple loop like
|
|
+ * while ( jiffies < start_jiffies+1)
|
|
+ * start = read_current_timer();
|
|
+ * will not do. As we don't really know whether jiffy switch
|
|
+ * happened first or timer_value was read first. And some asynchronous
|
|
+ * event can happen between these two events introducing errors in lpj.
|
|
+ *
|
|
+ * So, we do
|
|
+ * 1. pre_start <- When we are sure that jiffy switch hasn't happened
|
|
+ * 2. check jiffy switch
|
|
+ * 3. start <- timer value before or after jiffy switch
|
|
+ * 4. post_start <- When we are sure that jiffy switch has happened
|
|
+ *
|
|
+ * Note, we don't know anything about order of 2 and 3.
|
|
+ * Now, by looking at post_start and pre_start difference, we can
|
|
+ * check whether any asynchronous event happened or not
|
|
+ */
|
|
+
|
|
+ for (i = 0; i < MAX_DIRECT_CALIBRATION_RETRIES; i++) {
|
|
+ pre_start = 0;
|
|
+ read_current_timer(&start);
|
|
+ start_jiffies = jiffies;
|
|
+ while (jiffies <= (start_jiffies + 1)) {
|
|
+ pre_start = start;
|
|
+ read_current_timer(&start);
|
|
+ }
|
|
+ read_current_timer(&post_start);
|
|
+
|
|
+ pre_end = 0;
|
|
+ end = post_start;
|
|
+ while (jiffies <=
|
|
+ (start_jiffies + 1 + DELAY_CALIBRATION_TICKS)) {
|
|
+ pre_end = end;
|
|
+ read_current_timer(&end);
|
|
+ }
|
|
+ read_current_timer(&post_end);
|
|
+
|
|
+ tsc_rate_max = (post_end - pre_start) / DELAY_CALIBRATION_TICKS;
|
|
+ tsc_rate_min = (pre_end - post_start) / DELAY_CALIBRATION_TICKS;
|
|
+
|
|
+ /*
|
|
+ * If the upper limit and lower limit of the tsc_rate is
|
|
+ * >= 12.5% apart, redo calibration.
|
|
+ */
|
|
+ if (pre_start != 0 && pre_end != 0 &&
|
|
+ (tsc_rate_max - tsc_rate_min) < (tsc_rate_max >> 3)) {
|
|
+ good_tsc_count++;
|
|
+ good_tsc_sum += tsc_rate_max;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (good_tsc_count)
|
|
+ return (good_tsc_sum/good_tsc_count);
|
|
+
|
|
+ printk(KERN_WARNING "calibrate_delay_direct() failed to get a good "
|
|
+ "estimate for loops_per_jiffy.\nProbably due to long platform interrupts. Consider using \"lpj=\" boot option.\n");
|
|
+ return 0;
|
|
+}
|
|
+#else
|
|
+static unsigned long __devinit calibrate_delay_direct(void) {return 0;}
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * This is the number of bits of precision for the loops_per_jiffy. Each
|
|
+ * bit takes on average 1.5/HZ seconds. This (like the original) is a little
|
|
+ * better than 1%
|
|
+ */
|
|
+#define LPS_PREC 8
|
|
+
|
|
+void __devinit calibrate_delay(void)
|
|
+{
|
|
+ unsigned long ticks, loopbit;
|
|
+ int lps_precision = LPS_PREC;
|
|
+
|
|
+ genode_unlock(timer_main_kernel_lock);
|
|
+
|
|
+ if (preset_lpj) {
|
|
+ loops_per_jiffy = preset_lpj;
|
|
+ printk("Calibrating delay loop (skipped)... "
|
|
+ "%lu.%02lu BogoMIPS preset\n",
|
|
+ loops_per_jiffy/(500000/HZ),
|
|
+ (loops_per_jiffy/(5000/HZ)) % 100);
|
|
+ } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) {
|
|
+ printk("Calibrating delay using timer specific routine.. ");
|
|
+ printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
|
|
+ loops_per_jiffy/(500000/HZ),
|
|
+ (loops_per_jiffy/(5000/HZ)) % 100,
|
|
+ loops_per_jiffy);
|
|
+ } else {
|
|
+ loops_per_jiffy = (1<<12);
|
|
+
|
|
+ printk(KERN_DEBUG "Calibrating delay loop... ");
|
|
+ while ((loops_per_jiffy <<= 1) != 0) {
|
|
+ /* wait for "start of" clock tick */
|
|
+ ticks = jiffies;
|
|
+ while (ticks == jiffies)
|
|
+ /* nothing */;
|
|
+ /* Go .. */
|
|
+ ticks = jiffies;
|
|
+ __delay(loops_per_jiffy);
|
|
+ ticks = jiffies - ticks;
|
|
+ if (ticks)
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Do a binary approximation to get loops_per_jiffy set to
|
|
+ * equal one clock (up to lps_precision bits)
|
|
+ */
|
|
+ loops_per_jiffy >>= 1;
|
|
+ loopbit = loops_per_jiffy;
|
|
+ while (lps_precision-- && (loopbit >>= 1)) {
|
|
+ loops_per_jiffy |= loopbit;
|
|
+ ticks = jiffies;
|
|
+ while (ticks == jiffies)
|
|
+ /* nothing */;
|
|
+ ticks = jiffies;
|
|
+ __delay(loops_per_jiffy);
|
|
+ if (jiffies != ticks) /* longer than 1 tick */
|
|
+ loops_per_jiffy &= ~loopbit;
|
|
+ }
|
|
+
|
|
+ /* Round the value and print it */
|
|
+ printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
|
|
+ loops_per_jiffy/(500000/HZ),
|
|
+ (loops_per_jiffy/(5000/HZ)) % 100,
|
|
+ loops_per_jiffy);
|
|
+ }
|
|
+ genode_lock(timer_main_kernel_lock);
|
|
+}
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/exit.c contrib/arch/l4/kernel/exit.c
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/exit.c
|
|
+++ contrib/arch/l4/kernel/exit.c
|
|
@@ -9,7 +9,7 @@
|
|
#include <linux/kernel.h>
|
|
|
|
#include <assert.h>
|
|
-#include <iguana/pd.h>
|
|
+#include <genode/exit.h>
|
|
|
|
/*
|
|
* Called when Linux startup fails / exit server
|
|
@@ -18,10 +18,8 @@
|
|
void
|
|
_Exit(int status)
|
|
{
|
|
- pd_delete(pd_myself());
|
|
-
|
|
- assert(!"We have exitted -- sholdn't reach here");
|
|
- while(1);
|
|
+ genode_exit(status);
|
|
+ while(1) ;
|
|
}
|
|
|
|
void __div0(void)
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/fs/okl4fs/inode.c contrib/arch/l4/kernel/fs/okl4fs/inode.c
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/fs/okl4fs/inode.c
|
|
+++ contrib/arch/l4/kernel/fs/okl4fs/inode.c
|
|
@@ -17,8 +17,8 @@
|
|
#include <unistd.h>
|
|
#include "internal.h"
|
|
|
|
-#include <iguana/env.h>
|
|
-#include <iguana/memsection.h>
|
|
+//#include <iguana/env.h>
|
|
+//#include <iguana/memsection.h>
|
|
|
|
#include <l4/kdebug.h>
|
|
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/glue.c contrib/arch/l4/kernel/glue.c
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/glue.c
|
|
+++ contrib/arch/l4/kernel/glue.c
|
|
@@ -4,9 +4,12 @@
|
|
#include <linux/syscalls.h>
|
|
#include <linux/string.h>
|
|
|
|
+#include <linux/pagemap.h> /* needed by 'asm/tlb.h' */
|
|
+
|
|
#define __KERNEL_SYSCALLS__
|
|
|
|
-#include <asm/unistd.h> /* execve */
|
|
+#include <asm/unistd.h> /* execve */
|
|
+#include <asm/tlb.h> /* 'struct mmu_gather' */
|
|
|
|
int
|
|
kernel_execve(const char *filename, char *const argv[], char *const envp[])
|
|
@@ -40,7 +43,8 @@ const char *get_system_type(void)
|
|
return "L4 Default arch";
|
|
}
|
|
|
|
-void per_cpu__mmu_gathers (void) { printk("per_cpu__mmu_gathers called\n"); }
|
|
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
|
|
+
|
|
void ptrace_disable (void) { printk("ptrace_disable called\n"); }
|
|
//void search_extable (void) { printk("search_extable called\n"); }
|
|
void show_stack(struct task_struct *task, unsigned long *sp) { printk("show_stack called\n"); }
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/irq.c contrib/arch/l4/kernel/irq.c
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/irq.c
|
|
+++ contrib/arch/l4/kernel/irq.c
|
|
@@ -78,12 +78,12 @@ show_interrupts(struct seq_file *p, void
|
|
#endif
|
|
seq_printf(p, " %14s", irq_desc[i].chip->name);
|
|
seq_printf(p, " %c%s",
|
|
- (action->flags & SA_INTERRUPT)?'+':' ',
|
|
+ (action->flags & IRQF_DISABLED)?'+':' ',
|
|
action->name);
|
|
|
|
for (action=action->next; action; action = action->next) {
|
|
seq_printf(p, ", %c%s",
|
|
- (action->flags & SA_INTERRUPT)?'+':' ',
|
|
+ (action->flags & IRQF_DISABLED)?'+':' ',
|
|
action->name);
|
|
}
|
|
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/main.c contrib/arch/l4/kernel/main.c
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/main.c
|
|
+++ contrib/arch/l4/kernel/main.c
|
|
@@ -24,12 +24,13 @@
|
|
#include <asm/setup.h>
|
|
|
|
#include <iguana/thread.h>
|
|
-#include <iguana/cap.h>
|
|
#include <iguana/memsection.h>
|
|
#include <iguana/tls.h>
|
|
-#include <iguana/env.h>
|
|
|
|
-void *__callback_buffer;
|
|
+#include <genode/memory.h>
|
|
+#include <genode/sleep.h>
|
|
+#include <genode/config.h>
|
|
+#include <genode/lock.h>
|
|
|
|
uintptr_t temp_cap_slot;
|
|
uintptr_t temp_cap_used;
|
|
@@ -39,17 +40,20 @@ uintptr_t temp_cap_addr;
|
|
uintptr_t dma_heap_base, dma_heap_phys_base;
|
|
|
|
static uintptr_t main_stack[STACK_SIZE];
|
|
-static uintptr_t intervm_stack[STACK_SIZE];
|
|
+static uintptr_t timer_stack[STACK_SIZE];
|
|
+
|
|
+void* timer_main_kernel_lock;
|
|
|
|
extern void interrupt_loop(void);
|
|
|
|
void *main_tls_area[KERNEL_THREADS][32];
|
|
|
|
extern void start_kernel(void);
|
|
-extern void intervm_loop(void);
|
|
|
|
void *console_out, *console_in;
|
|
|
|
+extern void enable_early_printk(void);
|
|
+
|
|
/* Our per cpu irq enable/disable. Where should this go? */
|
|
DEFINE_PER_CPU(irq_info_t, _l4_irq_state) = { 0 };
|
|
EXPORT_PER_CPU_SYMBOL(_l4_irq_state);
|
|
@@ -59,7 +63,6 @@ L4_Word_t start_phys_mem, end_phys_mem;
|
|
L4_ThreadId_t main_thread;
|
|
L4_ThreadId_t timer_thread;
|
|
L4_ThreadId_t timer_handle;
|
|
-L4_ThreadId_t intervm_thread;
|
|
|
|
unsigned long get_instr(unsigned long addr)
|
|
{
|
|
@@ -96,67 +99,13 @@ unsigned long set_instr(unsigned long ad
|
|
return 0;
|
|
}
|
|
|
|
-/*
|
|
-Malloc
|
|
-*/
|
|
-void *
|
|
-malloc(size_t size)
|
|
-{
|
|
- void *ret;
|
|
- //printk("malloc: %d\n", (int)size);
|
|
- ret = kmalloc(size, GFP_ATOMIC);
|
|
- //printk("malloc returned: %p\n", ret);
|
|
- return ret;
|
|
-}
|
|
-
|
|
-void *
|
|
-calloc(size_t nmemb, size_t size)
|
|
-{
|
|
- printk("calloc called\n");
|
|
- return NULL;
|
|
-}
|
|
-
|
|
-void
|
|
-free(void *ptr)
|
|
-{
|
|
- return kfree(ptr);
|
|
-}
|
|
-
|
|
-int
|
|
-puts(const char *format)
|
|
-{
|
|
- printk("puts called\n");
|
|
- return 0;
|
|
-}
|
|
-
|
|
-int
|
|
-printf(const char *format, ...)
|
|
-{
|
|
- printk("printf\n");
|
|
- return 0;
|
|
-// return printk(format);
|
|
-}
|
|
-
|
|
|
|
-
|
|
-void
|
|
-__linux_cap_init(uintptr_t cap_slot, uintptr_t cap_used, uintptr_t cap_size, uintptr_t cap_addr)
|
|
-{
|
|
-// temp_cap_slot = cap_slot;
|
|
-// temp_cap_used = cap_used;
|
|
-// temp_cap_size = cap_size;
|
|
-// temp_cap_addr = cap_addr;
|
|
-// first_cap = (cap_t*) cap_addr;
|
|
-}
|
|
-
|
|
-
|
|
-void
|
|
-__libc_setup(void *callback, void *stdin_p, void *stdout_p, void *stderr_p,
|
|
- unsigned long heap_base, unsigned long heap_end)
|
|
+void __init
|
|
+__libc_setup(void *stdin_p, void *stdout_p, void *stderr_p,
|
|
+ unsigned long heap_base, unsigned long heap_end)
|
|
{
|
|
console_out = stdout_p;
|
|
console_in = stdin_p;
|
|
- __callback_buffer = callback;
|
|
|
|
/* Setup the memory areas from iguana */
|
|
assert(heap_end > heap_base);
|
|
@@ -165,106 +114,96 @@ __libc_setup(void *callback, void *stdin
|
|
bootmem_area[0].pages = (heap_end >> PAGE_SHIFT) - bootmem_area[0].page_base;
|
|
}
|
|
|
|
-void
|
|
-__lib_init(uintptr_t *buf)
|
|
+void __init __lib_init(void)
|
|
{
|
|
- void* callback;
|
|
- void* stdin_p;
|
|
- void* stdout_p;
|
|
- void* stderr_p;
|
|
char* heap_base;
|
|
size_t heap_size;
|
|
uint32_t dma_size;
|
|
|
|
- __lib_iguana_init(buf);
|
|
-
|
|
- callback = env_memsection_base(iguana_getenv("__OKL4_CALLBACK_BUFFER"));
|
|
- stdin_p = NULL; //env_memsection_base(iguana_getenv("OKL4_SERIAL_SERVER"));
|
|
- stdout_p = NULL; //env_memsection_base(iguana_getenv("OKL4_SERIAL_SERVER"));
|
|
- stderr_p = NULL; //env_memsection_base(iguana_getenv("OKL4_SERIAL_SERVER"));
|
|
- heap_base = (char*) env_const(iguana_getenv("HEAP_BASE"));
|
|
- heap_size = env_const(iguana_getenv("HEAP_SIZE"));
|
|
-
|
|
-
|
|
- __libc_setup(callback, stdin_p, stdout_p, stderr_p,
|
|
- (unsigned long) heap_base,
|
|
- (unsigned long) (heap_base + heap_size - 1));
|
|
- __cap_init();
|
|
-
|
|
-// __linux_cap_init((uintptr_t) iguana_getenv(IGUANA_GETENV_CLIST_SLOT),
|
|
-// (uintptr_t) iguana_getenv(IGUANA_GETENV_CLIST_USED),
|
|
-// CLIST_MEMORY_SIZE / sizeof(cap_t),
|
|
-// (uintptr_t) iguana_getenv(IGUANA_GETENV_CLIST_BASE));
|
|
-//
|
|
+ heap_size = genode_quota() - genode_used_mem()
|
|
+ - 8*1024*1024; // Leave some memory left for dynamic allocations
|
|
+ heap_base = genode_malloc(heap_size);
|
|
+ __libc_setup(0, 0, 0, (unsigned long) heap_base,
|
|
+ (unsigned long) (heap_base + heap_size - 1));
|
|
dma_heap_base = (uint32_t)heap_base;
|
|
dma_heap_phys_base = memsection_virt_to_phys((uintptr_t)heap_base,
|
|
- &dma_size);
|
|
+ &dma_size);
|
|
}
|
|
|
|
-
|
|
-void __sys_entry(void *buf, int argc, char** argv);
|
|
void _Exit(int status);
|
|
|
|
int main(int argc, char** argv);
|
|
+void __sys_entry(void *buf, int argc, char** argv){}
|
|
|
|
-/* This is the entry point from the C libraries crt0 */
|
|
-void
|
|
-__sys_entry(void *buf, int argc, char** argv)
|
|
+void setup_tls(int thread_num)
|
|
{
|
|
- int result;
|
|
- __lib_init(buf);
|
|
- /* Start Linux */
|
|
- result = main(argc, argv);
|
|
- /* Exit Linux Server */
|
|
- _Exit(result);
|
|
}
|
|
|
|
-void
|
|
-setup_tls(int thread_num)
|
|
+void __init start_main_thread(void)
|
|
{
|
|
- __tls_init(main_tls_area[thread_num]);
|
|
+ /* Set me as the pager for every user process started by Linux */
|
|
+ genode_set_pager();
|
|
+ genode_lock(timer_main_kernel_lock);
|
|
+
|
|
+#ifdef CONFIG_EARLY_PRINTK
|
|
+ /* early console initialisation */
|
|
+ enable_early_printk();
|
|
+#endif
|
|
+
|
|
+ start_kernel();
|
|
}
|
|
|
|
-int
|
|
-main(int argc, char **argv)
|
|
+void __init start_timer_thread(void)
|
|
{
|
|
- int r;
|
|
- /* Start a new thread */
|
|
- assert(argc > 0 && argv[0] != NULL);
|
|
-
|
|
- strlcpy(boot_command_line, argv[1], COMMAND_LINE_SIZE);
|
|
- L4_KDB_SetThreadName(L4_myselfconst, "L_timer");
|
|
-
|
|
+ /* Create main kernel thread, doing paging, syscalls etc. */
|
|
thread_create(&main_thread);
|
|
- r = L4_Set_Priority(main_thread, 99);
|
|
- assert (r != 0);
|
|
-
|
|
- timer_thread = thread_l4tid(env_thread(iguana_getenv("MAIN")));
|
|
L4_KDB_SetThreadName(main_thread, "L_syscall");
|
|
|
|
/* Setup our TLS as well */
|
|
- setup_tls(TIMER_THREAD);
|
|
-
|
|
- thread_create(&intervm_thread);
|
|
- r = L4_Set_Priority(intervm_thread, 98);
|
|
- assert(r != 0);
|
|
- L4_KDB_SetThreadName(intervm_thread, "L_intervm");
|
|
+ __tls_init(main_tls_area[TIMER_THREAD]);
|
|
|
|
/* Thread info setup. */
|
|
/* FIXME: remember for SMP startup */
|
|
- current_tinfo(smp_processor_id()) = (unsigned long)&init_thread_union.thread_info;
|
|
+ current_tinfo(smp_processor_id()) =
|
|
+ (unsigned long)&init_thread_union.thread_info;
|
|
current_thread_info()->user_tid = L4_nilthread;
|
|
current_thread_info()->user_handle = L4_nilthread;
|
|
|
|
+ /* Start linux main thread */
|
|
L4_Start_SpIp(main_thread,
|
|
- (L4_Word_t) &main_stack[STACK_SIZE-1],
|
|
- (L4_Word_t) start_kernel);
|
|
-
|
|
- L4_Start_SpIp(intervm_thread,
|
|
- (L4_Word_t) &intervm_stack[STACK_SIZE-1],
|
|
- (L4_Word_t) intervm_loop);
|
|
+ (L4_Word_t) &main_stack[STACK_SIZE-1],
|
|
+ (L4_Word_t) start_main_thread);
|
|
|
|
- /* Now we go and do the timer stuff */
|
|
+ /* Now we go and do the timer/IRQ stuff */
|
|
interrupt_loop();
|
|
+}
|
|
+
|
|
+int __init
|
|
+main(int argc, char **argv)
|
|
+{
|
|
+ char* cmdline = genode_config_cmdline();
|
|
+
|
|
+ /* Do init stuff, especially get memory */
|
|
+ __lib_init();
|
|
+
|
|
+ /* Copy kernel commandline from the XML config */
|
|
+ if (cmdline)
|
|
+ memcpy(boot_command_line, cmdline,
|
|
+ min_t(size_t, COMMAND_LINE_SIZE,
|
|
+ sizeof(char)*strlen(cmdline)));
|
|
+
|
|
+ /* Create timer thread, which provides so to say timer interrupts */
|
|
+ thread_create(&timer_thread);
|
|
+ L4_KDB_SetThreadName(timer_thread, "L_timer");
|
|
+
|
|
+ timer_main_kernel_lock = genode_alloc_lock();
|
|
+
|
|
+ /* Start timer thread */
|
|
+ L4_Start_SpIp(timer_thread,
|
|
+ (L4_Word_t) &timer_stack[STACK_SIZE-1],
|
|
+ (L4_Word_t) start_timer_thread);
|
|
+
|
|
+ /* Now, work is done, lets go sleeping */
|
|
+ genode_sleep_forever();
|
|
return 0;
|
|
}
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/process.c contrib/arch/l4/kernel/process.c
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/process.c
|
|
+++ contrib/arch/l4/kernel/process.c
|
|
@@ -23,6 +23,10 @@
|
|
#include <iguana/eas.h>
|
|
#include <iguana/thread.h>
|
|
|
|
+#include <genode/lock.h>
|
|
+
|
|
+extern void* timer_main_kernel_lock;
|
|
+
|
|
extern void NORET_TYPE syscall_loop (void);
|
|
static void new_thread_handler(struct thread_info *prev);
|
|
static void new_process_handler(struct thread_info *prev);
|
|
@@ -144,7 +148,7 @@ __execve(char *file, char **argv, char *
|
|
void
|
|
cpu_idle (void)
|
|
{
|
|
- int r;
|
|
+ //int r;
|
|
|
|
/* Idle thread has special user_tid so we can identify it */
|
|
current_thread_info()->user_tid = L4_anythread;
|
|
@@ -152,25 +156,17 @@ cpu_idle (void)
|
|
|
|
//printk("Starting idle loop (%lx)\n", L4_Myself().raw); XXX: L4_Myself() is no longer valid - nt
|
|
|
|
- r = L4_Set_Priority(L4_myselfconst, 99);
|
|
- if (r == 0) {
|
|
- printk("Failed: %lx\n", L4_ErrorCode());
|
|
- }
|
|
- assert(r != 0);
|
|
-
|
|
atomic_inc(&init_mm.mm_count);
|
|
current->mm = &init_mm;
|
|
current->active_mm = &init_mm;
|
|
|
|
while (1) {
|
|
- while (!need_resched())
|
|
- {
|
|
- /* Wait on timer_thread */
|
|
- if (!need_resched()){
|
|
- L4_Receive(timer_thread);
|
|
- }
|
|
+ while (!need_resched()){
|
|
+ genode_unlock(timer_main_kernel_lock);
|
|
+ L4_Receive(timer_thread);
|
|
+ genode_lock(timer_main_kernel_lock);
|
|
+
|
|
}
|
|
- //printk("!");
|
|
schedule();
|
|
}
|
|
}
|
|
@@ -187,7 +183,7 @@ copy_thread(int nr, unsigned long clone_
|
|
unsigned long unused, struct task_struct * p,
|
|
struct pt_regs * regs)
|
|
{
|
|
- int r = 0;
|
|
+ //int r = 0;
|
|
//printk("%s %d %lx usp=%lx, task=%p, regs=%p\n", __func__, nr, clone_flags, usp, p, regs);
|
|
|
|
if ((task_thread_info(p)->request.op != OP_KTHREAD) &&
|
|
@@ -222,9 +218,6 @@ copy_thread(int nr, unsigned long clone_
|
|
name);
|
|
}
|
|
|
|
- r = L4_Set_Priority(task_thread_info(p)->user_tid, 98);
|
|
- assert(r != 0);
|
|
-
|
|
L4_Copy_regs (current_thread_info()->user_tid,
|
|
task_thread_info(p)->user_tid);
|
|
|
|
@@ -308,7 +301,7 @@ start_thread(struct pt_regs * regs, unsi
|
|
//printk("%s current = %p pc = %lx, sp = %lx\n", __func__, current, pc, sp);
|
|
|
|
if (current_thread_info()->user_tid.raw == L4_nilthread.raw) {
|
|
- int r;
|
|
+ //int r;
|
|
void * utcb;
|
|
|
|
if (utcb_area.raw == L4_Nilpage.raw)
|
|
@@ -328,8 +321,7 @@ start_thread(struct pt_regs * regs, unsi
|
|
utcb, &handle);
|
|
|
|
assert(thrd.raw != 0);
|
|
- r = L4_Set_Priority(thrd, 98);
|
|
- assert(r != 0);
|
|
+
|
|
/*
|
|
* This will be disabled in libl4 with NDEBUG set, so it's OK.
|
|
*/
|
|
@@ -352,7 +344,8 @@ start_thread(struct pt_regs * regs, unsi
|
|
// syscall_exit(1);
|
|
|
|
set_need_restart(current_thread_info(), pc, sp, 0);
|
|
- L4_AbortIpc_and_stop_Thread(thrd);
|
|
+ //L4_AbortIpc_and_stop_Thread(thrd);
|
|
+ L4_Stop(thrd);
|
|
set_user_ipc_cancelled(current_thread_info());
|
|
|
|
/* Setup which messages we will recieve */
|
|
@@ -385,6 +378,29 @@ __switch_to(struct task_struct *prev, st
|
|
/* XXX - is the race from here to the switch important? */
|
|
current_tinfo(smp_processor_id()) = (unsigned long)next_info;
|
|
|
|
+ /* Suspend running thread */
|
|
+ if(prev_info->user_tid.raw != 0)
|
|
+ {
|
|
+ L4_Word_t dummy;
|
|
+ L4_ThreadId_t dummy_id;
|
|
+ L4_ExchangeRegisters(prev_info->user_tid,
|
|
+ L4_ExReg_Halt + L4_ExReg_AbortSendIPC,
|
|
+ 0, 0, 0,
|
|
+ 0, L4_nilthread, &dummy, &dummy, &dummy,
|
|
+ &dummy, &dummy, &dummy_id);
|
|
+ }
|
|
+
|
|
+ /* Resume scheduled thread */
|
|
+ if(next_info->user_tid.raw != 0)
|
|
+ {
|
|
+ L4_Word_t dummy;
|
|
+ L4_ThreadId_t dummy_id;
|
|
+ L4_ExchangeRegisters(next_info->user_tid,
|
|
+ L4_ExReg_Resume, 0, 0, 0,
|
|
+ 0, L4_nilthread, &dummy, &dummy, &dummy,
|
|
+ &dummy, &dummy, &dummy_id);
|
|
+ }
|
|
+
|
|
prev_info = arch_switch(prev_info, next_info);
|
|
mb();
|
|
} else {
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/setup.c contrib/arch/l4/kernel/setup.c
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/setup.c
|
|
+++ contrib/arch/l4/kernel/setup.c
|
|
@@ -14,8 +14,6 @@
|
|
#include <asm/tlbflush.h>
|
|
#include <asm/setup.h>
|
|
|
|
-#include <iguana/memsection.h>
|
|
-#include <iguana/cap.h>
|
|
#include <iguana/thread.h>
|
|
|
|
#ifdef CONFIG_VT
|
|
@@ -25,7 +23,9 @@
|
|
#include <linux/screen_info.h>
|
|
#include <asm/io.h>
|
|
|
|
-#include <iguana/env.h>
|
|
+#include <genode/config.h>
|
|
+#include <genode/open.h>
|
|
+
|
|
unsigned long VGA_offset;
|
|
|
|
struct screen_info screen_info = {
|
|
@@ -52,15 +52,16 @@ struct screen_info screen_info = {
|
|
.orig_video_points = 16
|
|
};
|
|
#define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)
|
|
-static struct resource video_ram_resource = {
|
|
- .name = "Video RAM area",
|
|
- .start = 0xa0000,
|
|
- .end 0xbffff,
|
|
- .flags = IORESOURCE_RAM
|
|
-};
|
|
+/* static struct resource video_ram_resource = { */
|
|
+/* .name = "Video RAM area", */
|
|
+/* .start = 0xa0000, */
|
|
+/* .end = 0xbffff, */
|
|
+/* .flags = IORESOURCE_RAM */
|
|
+/* }; */
|
|
|
|
void __init __setup_vga(void)
|
|
{
|
|
+ /*
|
|
char* vga_obj;
|
|
envitem_t *ig_ref;
|
|
|
|
@@ -72,7 +73,7 @@ void __init __setup_vga(void)
|
|
|
|
VGA_offset = (unsigned long)vga_obj - video_ram_resource.start;
|
|
request_resource(&iomem_resource, &video_ram_resource);
|
|
-
|
|
+ */
|
|
}
|
|
|
|
|
|
@@ -91,8 +92,6 @@ L4_Fpage_t utcb_area;
|
|
extern unsigned long start_phys_mem, end_phys_mem;
|
|
extern void * __rd_start, * __rd_end;
|
|
|
|
-extern void enable_early_printk(void);
|
|
-
|
|
void __init
|
|
setup_machine_name(void)
|
|
{
|
|
@@ -112,7 +111,7 @@ void __init
|
|
setup_arch (char **command_line)
|
|
{
|
|
unsigned long base, area;
|
|
-
|
|
+ char* initrd_name;
|
|
setup_tls(1);
|
|
|
|
/* Return the command line to the rest of the kernel */
|
|
@@ -156,19 +155,19 @@ setup_arch (char **command_line)
|
|
task_thread_info(current)->user_tid = L4_nilthread;
|
|
task_thread_info(current)->user_handle = L4_nilthread;
|
|
|
|
-#ifdef CONFIG_EARLY_PRINTK
|
|
- /* early console initialisation */
|
|
- enable_early_printk();
|
|
-#endif
|
|
-
|
|
/* Ramdisk setup */
|
|
#ifdef CONFIG_BLK_DEV_INITRD
|
|
/* Board specific code should have set up initrd_start and initrd_end */
|
|
ROOT_DEV = Root_RAM0;
|
|
/* FIXME! */
|
|
- initrd_start = 0; //naming_lookup("ramdisk");
|
|
- initrd_end = 0; //naming_lookup("ramdisk_end");
|
|
- printk("end: %lx\n", initrd_end);
|
|
+ initrd_name = genode_config_initrd();
|
|
+ if(initrd_name) {
|
|
+ initrd_start = (unsigned long) genode_open(initrd_name, &initrd_end);
|
|
+ initrd_end = initrd_start + initrd_end;
|
|
+ } else {
|
|
+ initrd_start = 0;
|
|
+ initrd_end = 0;
|
|
+ }
|
|
initrd_below_start_ok = 1;
|
|
|
|
if (initrd_start) {
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/sys_genode.c contrib/arch/l4/kernel/sys_genode.c
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/sys_genode.c
|
|
+++ contrib/arch/l4/kernel/sys_genode.c
|
|
@@ -0,0 +1,427 @@
|
|
+#define timer_t timer_t_linux
|
|
+
|
|
+#include <l4.h>
|
|
+#include <l4/interrupt.h>
|
|
+#include <l4/utcb.h>
|
|
+#include <wombat.h>
|
|
+
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/types.h>
|
|
+#include <linux/mm.h>
|
|
+#include <linux/sched.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/module.h>
|
|
+#undef timer_t
|
|
+
|
|
+#include <iguana/memsection.h>
|
|
+#include <iguana/thread.h>
|
|
+#include <iguana/hardware.h>
|
|
+
|
|
+#include <genode/memory.h>
|
|
+#include <genode/sleep.h>
|
|
+#include <genode/lock.h>
|
|
+#ifdef CONFIG_SCREEN_GENODE
|
|
+#include <genode/input.h>
|
|
+#endif
|
|
+#ifdef CONFIG_NET_GENODE
|
|
+#include <genode/net.h>
|
|
+#endif
|
|
+#ifdef CONFIG_BLOCK_GENODE
|
|
+#include <genode/block.h>
|
|
+#endif
|
|
+
|
|
+#include "assert.h"
|
|
+#include "irq_impl.h"
|
|
+
|
|
+#include <linux/posix_types.h>
|
|
+
|
|
+
|
|
+extern L4_ThreadId_t main_thread;
|
|
+extern L4_ThreadId_t timer_thread;
|
|
+extern L4_ThreadId_t timer_handle;
|
|
+
|
|
+/*
|
|
+ * Mask is set (1) if enabled
|
|
+ */
|
|
+L4_Word_t irq_mask = 1; // Keep bit 1 reserverd for timer as it is somewhat magic
|
|
+
|
|
+#define NUM_CPUS 1
|
|
+fd_set pending_irqs[NUM_CPUS];
|
|
+#define PENDING_MASK_SIZE (NR_IRQS / 32)
|
|
+
|
|
+/*
|
|
+ * Need SMP-safe access to interrupt CSRs
|
|
+ */
|
|
+DEFINE_SPINLOCK(iguana_irq_lock);
|
|
+
|
|
+static inline void
|
|
+iguana_enable_irq(unsigned int irq)
|
|
+{
|
|
+ printk("WARN: %s does not work by now!\n",__func__);
|
|
+ spin_lock(&iguana_irq_lock);
|
|
+ if (irq < 32) {
|
|
+ irq_mask |= (1UL << 31); /* always use bit 31 for hw irqs */
|
|
+ //L4_LoadMR(0, irq);
|
|
+ //L4_AcknowledgeInterruptOnBehalf(timer_thread, 0, 0);
|
|
+ } else {
|
|
+ irq_mask |= (1UL << irq);
|
|
+ }
|
|
+ spin_unlock(&iguana_irq_lock);
|
|
+}
|
|
+
|
|
+static inline void
|
|
+iguana_disable_irq(unsigned int irq)
|
|
+{
|
|
+ printk("WARN: %s does not work by now!\n",__func__);
|
|
+ spin_lock(&iguana_irq_lock);
|
|
+ if (irq < 32) {
|
|
+ //L4_LoadMR(0, irq);
|
|
+ //L4_UnregisterInterrupt(timer_thread, 0, 0);
|
|
+ } else {
|
|
+ irq_mask &= ~(1UL << irq);
|
|
+ }
|
|
+
|
|
+ spin_unlock(&iguana_irq_lock);
|
|
+}
|
|
+
|
|
+static unsigned int
|
|
+iguana_startup_irq(unsigned int irq)
|
|
+{
|
|
+ if (irq < 32)
|
|
+ hardware_register_interrupt(timer_thread, irq);
|
|
+
|
|
+ iguana_enable_irq(irq);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void
|
|
+iguana_ack_irq(unsigned int irq)
|
|
+{
|
|
+}
|
|
+
|
|
+static void
|
|
+iguana_end_irq(unsigned int irq)
|
|
+{
|
|
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
|
+ iguana_enable_irq(irq);
|
|
+}
|
|
+
|
|
+static void
|
|
+iguana_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
|
|
+{
|
|
+ // XXX fixme
|
|
+ printk("%s called\n", __func__);
|
|
+}
|
|
+
|
|
+static void
|
|
+iguana_set_irq_affinity(unsigned int irq, cpumask_t affinity)
|
|
+{
|
|
+ spin_lock(&iguana_irq_lock);
|
|
+ iguana_cpu_set_irq_affinity(irq, affinity);
|
|
+ spin_unlock(&iguana_irq_lock);
|
|
+}
|
|
+
|
|
+static void __init
|
|
+init_iguana_irqs(struct hw_interrupt_type * ops, int imin, int imax)
|
|
+{
|
|
+ long i;
|
|
+ for (i = imin; i <= imax; ++i) {
|
|
+ irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
|
|
+ irq_desc[i].chip = ops;
|
|
+ }
|
|
+}
|
|
+
|
|
+static struct hw_interrupt_type iguana_irq_type = {
|
|
+ .typename = "iguana",
|
|
+ .startup = iguana_startup_irq,
|
|
+ .shutdown = iguana_disable_irq,
|
|
+ .enable = iguana_enable_irq,
|
|
+ .disable = iguana_disable_irq,
|
|
+ .ack = iguana_ack_irq,
|
|
+ .end = iguana_end_irq,
|
|
+ .set_affinity = iguana_set_irq_affinity,
|
|
+};
|
|
+
|
|
+static void __init
|
|
+iguana_init_irq(void)
|
|
+{
|
|
+ init_iguana_irqs(&iguana_irq_type, 0, NR_IRQS-1);
|
|
+}
|
|
+
|
|
+void __init
|
|
+init_IRQ(void)
|
|
+{
|
|
+ iguana_init_irq();
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Iguana Family
|
|
+ */
|
|
+extern uintptr_t temp_cap_slot;
|
|
+extern uintptr_t temp_cap_used;
|
|
+extern uintptr_t temp_cap_size;
|
|
+extern uintptr_t temp_cap_addr;
|
|
+
|
|
+extern void
|
|
+__cap_init(uintptr_t cap_slot, uintptr_t cap_used, uintptr_t cap_size, uintptr_t cap_addr);
|
|
+
|
|
+memsection_ref_t vmalloc_memsect;
|
|
+uintptr_t vmalloc_start, vmalloc_end;
|
|
+
|
|
+/* FIXME: Should be extended for SMP? */
|
|
+struct ig_irq_rec{
|
|
+ unsigned short pending;
|
|
+ L4_ThreadId_t tid;
|
|
+} irq_recs[NR_IRQS];
|
|
+
|
|
+static int __init
|
|
+iguana_arch_init(void)
|
|
+{
|
|
+#if 0
|
|
+ /*
|
|
+ * Enable the system error interrupts. These interrupts are
|
|
+ * all reported to the kernel as machine checks, so the handler
|
|
+ * is a nop so it can be called to count the individual events.
|
|
+ */
|
|
+
|
|
+ /*
|
|
+ FIXME: We need to setup capabilties library properly now!
|
|
+ Ideally we would do this really early, but this is about as early
|
|
+ as we get!
|
|
+ */
|
|
+ __cap_init(temp_cap_slot, temp_cap_used, temp_cap_size, temp_cap_addr);
|
|
+#endif
|
|
+
|
|
+ /* Just take physical memory end + 1MB hole as starting point */
|
|
+ unsigned long offset = 10*1024*1024;
|
|
+ vmalloc_start = (uintptr_t) genode_malloc(10);
|
|
+ vmalloc_start += (2*offset-1) & ~(offset-1);
|
|
+
|
|
+ /* Let the vmalloc area size be 100MB and hope it doesn't collude */
|
|
+ vmalloc_end = vmalloc_start + 100*1024*1024;
|
|
+ genode_printf("vmalloc area: %lx - %lx\n", vmalloc_start, vmalloc_end);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+arch_initcall(iguana_arch_init);
|
|
+
|
|
+extern void * __callback_buffer;
|
|
+
|
|
+#define BIT(x) (1<<(x))
|
|
+#define TIMER_IRQ 0
|
|
+
|
|
+/*
|
|
+ * XXX: namespace clash. :-(
|
|
+ */
|
|
+#define device_create okl4_device_create
|
|
+
|
|
+//#include <driver/types.h>
|
|
+//#include <interfaces/vtimer_client.h>
|
|
+
|
|
+//server_t timer_server;
|
|
+//device_t timer_dev;
|
|
+
|
|
+/*
|
|
+ * XXX this needs 32/64bit cleanup + merge into irq.c
|
|
+ */
|
|
+/* int mask_to_irq(L4_Word_t *mask) */
|
|
+/* { */
|
|
+/* int i; */
|
|
+
|
|
+/* for (i = 0 ; i < NR_IGUANA_IRQS; i++) */
|
|
+/* { */
|
|
+/* if (*mask & (1 << i)) */
|
|
+/* { */
|
|
+/* *mask &= ~(1 << i); */
|
|
+
|
|
+/* /\* Bit 31 is ia32 BSP's way of saying hardware interrupt *\/ */
|
|
+/* if (i == 31) */
|
|
+/* { */
|
|
+/* /\* read hw irq number from utcb->platform_reserved[0] *\/ */
|
|
+/* //printk("mask_to_irq: got hw irq %ld!\n", utcb_base_get()->platform_reserved[0]); */
|
|
+/* return utcb_base_get()->platform_reserved[0]; */
|
|
+/* } */
|
|
+/* else */
|
|
+/* { */
|
|
+/* return IGUANA_IRQ(i); */
|
|
+/* } */
|
|
+/* } */
|
|
+/* } */
|
|
+/* return -1; */
|
|
+/* } */
|
|
+
|
|
+int iguana_alloc_irq(void)
|
|
+{
|
|
+ int i;
|
|
+ for (i = 0; i < NR_IGUANA_IRQS; i++){
|
|
+ if (!(irq_mask & (1UL<<i))){
|
|
+ irq_mask |= (1UL<<i);
|
|
+ return IGUANA_IRQ(i);
|
|
+ }
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+//extern void ig_serial_interrupt(void);
|
|
+//extern void ig_input_interrupt(void);
|
|
+
|
|
+static int pending_tick;
|
|
+
|
|
+/* static int */
|
|
+/* tid_to_int(L4_ThreadId_t tid) */
|
|
+/* { */
|
|
+/* return (int)L4_ThreadNo(tid); */
|
|
+/* } */
|
|
+
|
|
+/* L4_Word_t */
|
|
+/* corba_l4_error(CORBA_Environment *env) */
|
|
+/* { */
|
|
+/* L4_Word_t val = *(L4_Word_t *)(env); */
|
|
+
|
|
+/* if ((val & 0xff) == CORBA_SYSTEM_EXCEPTION) */
|
|
+/* return val >> 8; */
|
|
+/* else */
|
|
+/* return 0; */
|
|
+/* } */
|
|
+
|
|
+extern void* timer_main_kernel_lock;
|
|
+
|
|
+void
|
|
+interrupt_loop(void)
|
|
+{
|
|
+ struct thread_info * curinfo;
|
|
+
|
|
+ /* timer interrupt */
|
|
+ int irq = IGUANA_IRQ(0);
|
|
+
|
|
+ /* Wait for wake up message from timer init */
|
|
+ L4_Call(main_thread);
|
|
+
|
|
+ printk("START CLOCK LOOP\n");
|
|
+
|
|
+ while(1) {
|
|
+ genode_sleep(10);
|
|
+ genode_lock(timer_main_kernel_lock);
|
|
+#ifdef CONFIG_SCREEN_GENODE
|
|
+ genode_input_handle_events();
|
|
+#endif
|
|
+#ifdef CONFIG_NET_GENODE
|
|
+ genode_net_rx_receive();
|
|
+#endif
|
|
+#ifdef CONFIG_BLOCK_GENODE
|
|
+ genode_block_collect_responses();
|
|
+#endif
|
|
+ curinfo = current_thread_info();
|
|
+ curinfo->regs.mode ++;
|
|
+
|
|
+ if (irqs_disabled())
|
|
+ {
|
|
+ FD_SET(irq, &pending_irqs[smp_processor_id()]);
|
|
+
|
|
+ /* Keep time going for missed ticks */
|
|
+ if (pending_tick)
|
|
+ jiffies_64++;
|
|
+ IRQ_pending(smp_processor_id()) ++;
|
|
+ pending_tick = 1;
|
|
+ curinfo->regs.mode --;
|
|
+ genode_unlock(timer_main_kernel_lock);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ isr_irq_disable();
|
|
+ // Should loop over all bits potentially set
|
|
+ handle_irq(irq, NULL);
|
|
+ isr_irq_enable();
|
|
+ pending_tick = 0;
|
|
+ isr_irq_disable();
|
|
+ irq_enter();
|
|
+ do_timer(1);
|
|
+ update_process_times(user_mode(&curinfo->regs));
|
|
+ irq_exit();
|
|
+ isr_irq_enable();
|
|
+ curinfo->regs.mode --;
|
|
+
|
|
+ genode_unlock(timer_main_kernel_lock);
|
|
+ if (need_resched()) {
|
|
+ L4_MsgTag_t msgtag = L4_Niltag;
|
|
+ L4_Msg_t msg;
|
|
+ L4_Set_MsgMsgTag( &msg, msgtag );
|
|
+ L4_MsgLoad( &msg );
|
|
+ L4_Send_Nonblocking(main_thread);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+static int irq_mask_to_num(void){
|
|
+ int i;
|
|
+ int cpu = smp_processor_id();
|
|
+ unsigned int least_sig;
|
|
+
|
|
+ for (i = 0; i <= PENDING_MASK_SIZE; ++i){
|
|
+ least_sig = fls(pending_irqs[cpu].fds_bits[i]);
|
|
+ if (least_sig == 0)
|
|
+ continue;
|
|
+ else{
|
|
+ int bit = (i * sizeof(long)*8) + least_sig;
|
|
+ FD_CLR(bit-1, &pending_irqs[smp_processor_id()]);
|
|
+ return (bit - 1);
|
|
+ }
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+/*
|
|
+ * This is called to handle pending interrupts from the main linux thread.
|
|
+ * We thus need to send a deceiving IPC to the L4 interrupt thread to
|
|
+ * ACK the interrupt. This is called with interrupts disabled
|
|
+ */
|
|
+void
|
|
+l4_handle_pending(void)
|
|
+{
|
|
+ int irq_num;
|
|
+ struct thread_info * curinfo = current_thread_info();
|
|
+
|
|
+ curinfo->regs.mode ++;
|
|
+
|
|
+ if (pending_tick)
|
|
+ {
|
|
+ irq_enter();
|
|
+ do_timer(1);
|
|
+ update_process_times(user_mode(&curinfo->regs));
|
|
+
|
|
+ pending_tick = 0;
|
|
+ irq_exit();
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * XXX
|
|
+ *
|
|
+ * Concurrency problem: the FD_SET() and FD_CLR() are not
|
|
+ * atomic but can be accessed either in the timer thread
|
|
+ * context or the syscall loop thread context
|
|
+ *
|
|
+ * -gl
|
|
+ */
|
|
+ while((irq_num = irq_mask_to_num()) != -1)
|
|
+ {
|
|
+ handle_irq(irq_num, NULL);
|
|
+ }
|
|
+
|
|
+ IRQ_pending(smp_processor_id())--;
|
|
+
|
|
+ curinfo->regs.mode --;
|
|
+}
|
|
+
|
|
+void local_irq_enable(void)
|
|
+{
|
|
+ if (unlikely(!in_interrupt() && IRQ_pending(smp_processor_id())))
|
|
+ {
|
|
+ IRQ_state(smp_processor_id()) = 1;
|
|
+ l4_handle_pending();
|
|
+ }
|
|
+ IRQ_state(smp_processor_id()) = 0;
|
|
+}
|
|
+
|
|
+EXPORT_SYMBOL(local_irq_enable);
|
|
+
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/syscall_loop.c contrib/arch/l4/kernel/syscall_loop.c
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/syscall_loop.c
|
|
+++ contrib/arch/l4/kernel/syscall_loop.c
|
|
@@ -23,10 +23,8 @@
|
|
#include <asm/setup.h>
|
|
|
|
#include <iguana/thread.h>
|
|
-#include <iguana/cap.h>
|
|
#include <iguana/memsection.h>
|
|
-#include <iguana/tls.h>
|
|
-#include <iguana/object.h>
|
|
+#include <genode/lock.h>
|
|
|
|
#include <linux/mman.h>
|
|
|
|
@@ -36,6 +34,7 @@
|
|
extern L4_ThreadId_t timer_thread;
|
|
extern L4_ThreadId_t timer_handle;
|
|
extern L4_ThreadId_t main_thread;
|
|
+extern void* timer_main_kernel_lock;
|
|
|
|
extern unsigned long get_instr(unsigned long addr);
|
|
extern unsigned long set_instr(unsigned long addr, unsigned long value);
|
|
@@ -556,9 +555,12 @@ return_to_user:
|
|
if (likely(reply_user_ipc(curinfo))) {
|
|
curinfo->regs.mode = 0;
|
|
L4_MsgLoad(&curinfo->regs.msg);
|
|
+ genode_unlock(timer_main_kernel_lock);
|
|
/* Reply to caller and wait for next IPC */
|
|
tag = L4_ReplyWait(curinfo->user_tid,
|
|
&from);
|
|
+ genode_lock(timer_main_kernel_lock);
|
|
+
|
|
} else {
|
|
retry:
|
|
if (user_need_restart(curinfo)) {
|
|
@@ -570,10 +572,12 @@ retry:
|
|
}
|
|
curinfo->regs.mode = 0;
|
|
/* Open Wait */
|
|
+ genode_unlock(timer_main_kernel_lock);
|
|
tag = L4_Wait (&from);
|
|
+ genode_lock(timer_main_kernel_lock);
|
|
}
|
|
|
|
- if (likely(from.raw == curinfo->user_handle.raw))
|
|
+ if (likely(from.raw == curinfo->user_tid.raw))
|
|
{
|
|
curinfo->regs.mode = 1;
|
|
curinfo->tag = tag;
|
|
@@ -587,6 +591,7 @@ retry:
|
|
}
|
|
else
|
|
{
|
|
+#if 0
|
|
/* XXX
|
|
* Here we have to lookup the linux thread from
|
|
* the L4 thread_id, which may be expensive.
|
|
@@ -595,9 +600,12 @@ retry:
|
|
* thread could use this to kill root processes.
|
|
*/
|
|
printk("illegal ipc from %lx, expected %lx\n", from.raw,
|
|
- curinfo->user_handle.raw);
|
|
+ curinfo->user_tid.raw);
|
|
L4_KDB_Enter("ill");
|
|
goto retry;
|
|
+#endif
|
|
+ curinfo->regs.mode = 1;
|
|
+ curinfo->tag = tag;
|
|
}
|
|
}
|
|
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/vmlinux.lds.S contrib/arch/l4/kernel/vmlinux.lds.S
|
|
--- kernel-2.6.23-v2/arch/l4/kernel/vmlinux.lds.S
|
|
+++ contrib/arch/l4/kernel/vmlinux.lds.S
|
|
@@ -22,6 +22,10 @@ SECTIONS
|
|
#endif
|
|
/* read-only */
|
|
.text : {
|
|
+ /* begin of program image (link address) */
|
|
+ _prog_img_beg = .;
|
|
+
|
|
+ _stext = .;
|
|
_text = .; /* Text and read-only data */
|
|
*(.text)
|
|
SCHED_TEXT
|
|
@@ -29,6 +33,18 @@ SECTIONS
|
|
*(.fixup)
|
|
*(.gnu.warning)
|
|
*(.note*)
|
|
+
|
|
+ . = ALIGN(0x04);
|
|
+
|
|
+ _ctors_start = .;
|
|
+ KEEP (*(.ctors))
|
|
+ KEEP (*(SORT(.ctors.*)))
|
|
+ _ctors_end = .;
|
|
+ _dtors_start = .;
|
|
+ KEEP (*(SORT(.dtors.*)))
|
|
+ KEEP (*(.dtors))
|
|
+ _dtors_end = .;
|
|
+
|
|
. = ALIGN(PAGE_SIZE);
|
|
__user_exregs_page = .;
|
|
*(.exregspage)
|
|
@@ -42,11 +58,25 @@ SECTIONS
|
|
__ex_table : { *(__ex_table) }
|
|
__stop___ex_table = .;
|
|
|
|
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
|
|
+
|
|
RODATA
|
|
|
|
- . = ALIGN(PAGE_SIZE);
|
|
-
|
|
+ . = ALIGN(PAGE_SIZE);
|
|
+
|
|
+ _prog_img_data = .;
|
|
+
|
|
.data : { /* Data */
|
|
+ /* Leave space for parent capability parameters at start of data
|
|
+ * section. The protection domain creator is reponsible for storing
|
|
+ * sane values here.
|
|
+ */
|
|
+ _parent_cap = .;
|
|
+ LONG(0xffffffff);
|
|
+ LONG(0xffffffff);
|
|
+ LONG(0xffffffff);
|
|
+ LONG(0xffffffff);
|
|
+
|
|
/* Align the initial ramdisk image (INITRD) on page boundaries. */
|
|
/*
|
|
__rd_start = .;
|
|
@@ -59,7 +89,16 @@ SECTIONS
|
|
|
|
CONSTRUCTORS
|
|
. = ALIGN(PAGE_SIZE);
|
|
- }
|
|
+ } : rw
|
|
+
|
|
+ /* exception frames for C++ */
|
|
+ .eh_frame : {
|
|
+ __eh_frame_start__ = .;
|
|
+ KEEP (*(.eh_frame))
|
|
+ LONG(0)
|
|
+ } : rw
|
|
+ .gcc_except_table : { KEEP(*(.gcc_except_table)) }
|
|
+ .dynamic : { *(.dynamic) }
|
|
|
|
. = ALIGN(32);
|
|
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
|
|
@@ -122,9 +161,15 @@ SECTIONS
|
|
*(COMMON)
|
|
_end = .;
|
|
}
|
|
+
|
|
+ /* end of program image -- must be after last section */
|
|
+ _prog_img_end = .;
|
|
+
|
|
}
|
|
|
|
PHDRS
|
|
{
|
|
main_seg PT_LOAD;
|
|
+ ro PT_LOAD;
|
|
+ rw PT_LOAD;
|
|
}
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/lib/checksum.c contrib/arch/l4/lib/checksum.c
|
|
--- kernel-2.6.23-v2/arch/l4/lib/checksum.c
|
|
+++ contrib/arch/l4/lib/checksum.c
|
|
@@ -85,7 +85,7 @@ out:
|
|
/*
|
|
* computes a partial checksum, e.g. for TCP/UDP fragments
|
|
*/
|
|
-__wsum csum_partial(const void *buff, int len, __wsum sum)
|
|
+asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum)
|
|
{
|
|
unsigned int result = do_csum(buff, len);
|
|
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/mm/mmu.c contrib/arch/l4/mm/mmu.c
|
|
--- kernel-2.6.23-v2/arch/l4/mm/mmu.c
|
|
+++ contrib/arch/l4/mm/mmu.c
|
|
@@ -39,7 +39,6 @@ void activate_mm(struct mm_struct *old,
|
|
|
|
if (old_thrd.raw != L4_nilthread.raw)
|
|
{
|
|
- int r;
|
|
thread_delete(old_thrd);
|
|
current_thread_info()->user_tid =
|
|
eas_create_thread(new->context.eas,
|
|
@@ -48,8 +47,6 @@ void activate_mm(struct mm_struct *old,
|
|
¤t_thread_info()->user_handle);
|
|
|
|
assert(current_thread_info()->user_tid.raw != 0);
|
|
- r = L4_Set_Priority(current_thread_info()->user_tid, 98);
|
|
- assert(r != 0);
|
|
|
|
{
|
|
char name[16];
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/sys-i386/Makefile contrib/arch/l4/sys-i386/Makefile
|
|
--- kernel-2.6.23-v2/arch/l4/sys-i386/Makefile
|
|
+++ contrib/arch/l4/sys-i386/Makefile
|
|
@@ -4,7 +4,7 @@ CFLAGS += -O2
|
|
ELF_ARCH = i386
|
|
ELF_FORMAT = elf32-i386
|
|
|
|
-obj-y = crt0.o delay.o signal.o syscalls.o semaphore.o io.o sys_i386.o bitops.o user.o ptrace.o process.o ldt.o traps.o processor.o string.o dma.o memcpy.o strstr.o ioport.o
|
|
+obj-y = delay.o signal.o syscalls.o semaphore.o io.o sys_i386.o bitops.o user.o ptrace.o process.o ldt.o traps.o processor.o string.o dma.o memcpy.o strstr.o ioport.o
|
|
|
|
ifdef CONFIG_IA32_VDSO_ENABLE
|
|
obj-y += sysenter.o vsyscall.o
|
|
@@ -42,7 +42,7 @@ targets += vsyscall-note.o vsyscall.lds
|
|
|
|
# The DSO images are built using a special linker script.
|
|
quiet_cmd_syscall = SYSCALL $@
|
|
- cmd_syscall = $(CC) -m elf_i386 -nostdlib $(SYSCFLAGS_$(@F)) \
|
|
+ cmd_syscall = $(CC) -m32 -nostdlib $(SYSCFLAGS_$(@F)) \
|
|
-Wl,-T,$(filter-out FORCE,$^) -o $@
|
|
|
|
export CPPFLAGS_vsyscall.lds += -P -C -U$(ARCH)
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/sys-i386/crt0.S contrib/arch/l4/sys-i386/crt0.S
|
|
--- kernel-2.6.23-v2/arch/l4/sys-i386/crt0.S
|
|
+++ contrib/arch/l4/sys-i386/crt0.S
|
|
@@ -31,13 +31,13 @@
|
|
********************************************************************/
|
|
|
|
.text
|
|
- .global _start
|
|
+ .global _wombat_start
|
|
_stext:
|
|
.global _stext
|
|
|
|
-_start:
|
|
+_wombat_start:
|
|
push $0xfee1dead /* dummy frame thingy */
|
|
jmp __sys_entry /* off we go! */
|
|
/*NOTREACHED*/
|
|
|
|
- .end _start
|
|
+ .end _wombat_start
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/sys-i386/dma.c contrib/arch/l4/sys-i386/dma.c
|
|
--- kernel-2.6.23-v2/arch/l4/sys-i386/dma.c
|
|
+++ contrib/arch/l4/sys-i386/dma.c
|
|
@@ -11,7 +11,7 @@
|
|
#include <iguana/thread.h>
|
|
#include <iguana/memsection.h>
|
|
#include <iguana/hardware.h>
|
|
-#include <iguana/physmem.h>
|
|
+//#include <iguana/physmem.h>
|
|
|
|
/* Allocate consistent (uncached, or the appearance of it) memory */
|
|
/* We ignore the flags at the moment */
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/sys-i386/ioport.c contrib/arch/l4/sys-i386/ioport.c
|
|
--- kernel-2.6.23-v2/arch/l4/sys-i386/ioport.c
|
|
+++ contrib/arch/l4/sys-i386/ioport.c
|
|
@@ -13,8 +13,8 @@
|
|
*/
|
|
asmlinkage long sys_iopl(unsigned long unused)
|
|
{
|
|
- unsigned long old = 0; /* XXX */
|
|
- unsigned long level; /* in %ebx */
|
|
+ //unsigned long old = 0; /* XXX */
|
|
+ //unsigned long level; /* in %ebx */
|
|
|
|
printk("%s: not implemented.\n", __func__);
|
|
#if 0
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/sys-i386/signal.c contrib/arch/l4/sys-i386/signal.c
|
|
--- kernel-2.6.23-v2/arch/l4/sys-i386/signal.c
|
|
+++ contrib/arch/l4/sys-i386/signal.c
|
|
@@ -189,8 +189,8 @@ restore_sigcontext(struct pt_regs *ptreg
|
|
|
|
return err;
|
|
|
|
-badframe:
|
|
- return 1;
|
|
+//badframe:
|
|
+// return 1;
|
|
}
|
|
|
|
asmlinkage int sys_sigreturn(struct pt_regs *regs)
|
|
diff -urNpB kernel-2.6.23-v2/arch/l4/sys-i386/syscalls.c contrib/arch/l4/sys-i386/syscalls.c
|
|
--- kernel-2.6.23-v2/arch/l4/sys-i386/syscalls.c
|
|
+++ contrib/arch/l4/sys-i386/syscalls.c
|
|
@@ -10,8 +10,8 @@
|
|
|
|
#define __NR_Linux 0
|
|
|
|
-extern long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
|
|
- unsigned long flags, unsigned long fd, unsigned long pgoff);
|
|
+extern asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
|
|
+ unsigned long flags, unsigned long fd, unsigned long pgoff);
|
|
|
|
|
|
unsigned int l4_i386_abi_syscall_start = 0;
|
|
diff -urNpB kernel-2.6.23-v2/block/cfq-iosched.c contrib/block/cfq-iosched.c
|
|
--- kernel-2.6.23-v2/block/cfq-iosched.c
|
|
+++ contrib/block/cfq-iosched.c
|
|
@@ -1427,6 +1427,7 @@ cfq_async_queue_prio(struct cfq_data *cf
|
|
default:
|
|
BUG();
|
|
}
|
|
+ return 0;
|
|
}
|
|
|
|
static struct cfq_queue *
|
|
diff -urNpB kernel-2.6.23-v2/include/asm-l4/bug.h contrib/include/asm-l4/bug.h
|
|
--- kernel-2.6.23-v2/include/asm-l4/bug.h
|
|
+++ contrib/include/asm-l4/bug.h
|
|
@@ -4,12 +4,13 @@
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#include <iguana/pd.h>
|
|
+#include <genode/printf.h>
|
|
+#include <genode/exit.h>
|
|
|
|
#define HAVE_ARCH_BUG
|
|
#define BUG() do { \
|
|
- /*panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__);*/ \
|
|
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
|
|
- pd_delete(pd_myself()); \
|
|
+ genode_printf("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
|
|
+ genode_exit(1); \
|
|
} while (0)
|
|
|
|
#define HAVE_ARCH_BUG_ON
|
|
@@ -23,6 +24,18 @@
|
|
BUG(); \
|
|
} while (0)
|
|
|
|
+
|
|
+#define HAVE_ARCH_WARN_ON
|
|
+#define WARN_ON(condition) ({ \
|
|
+ int __ret_warn_on = !!(condition); \
|
|
+ if (unlikely(__ret_warn_on)) { \
|
|
+ genode_printf("WARNING: at %s:%d %s()\n", __FILE__, \
|
|
+ __LINE__, __FUNCTION__); \
|
|
+ } \
|
|
+ unlikely(__ret_warn_on); \
|
|
+})
|
|
+
|
|
+
|
|
extern int foo;
|
|
|
|
#include <asm-generic/bug.h>
|
|
diff -urNpB kernel-2.6.23-v2/include/asm-l4/i386/dma-mapping.h contrib/include/asm-l4/i386/dma-mapping.h
|
|
--- kernel-2.6.23-v2/include/asm-l4/i386/dma-mapping.h
|
|
+++ contrib/include/asm-l4/i386/dma-mapping.h
|
|
@@ -26,7 +26,7 @@
|
|
#include <iguana/thread.h>
|
|
#include <iguana/memsection.h>
|
|
#include <iguana/hardware.h>
|
|
-#include <iguana/physmem.h>
|
|
+//#include <iguana/physmem.h>
|
|
|
|
|
|
static inline int
|
|
diff -urNpB kernel-2.6.23-v2/include/asm-l4/i386/ptrace.h contrib/include/asm-l4/i386/ptrace.h
|
|
--- kernel-2.6.23-v2/include/asm-l4/i386/ptrace.h
|
|
+++ contrib/include/asm-l4/i386/ptrace.h
|
|
@@ -61,7 +61,7 @@
|
|
#define PTRACE_GET_THREAD_AREA 25
|
|
#define PTRACE_SET_THREAD_AREA 26
|
|
|
|
-extern inline void
|
|
+static inline void
|
|
l4_arch_setup_restart(struct pt_regs *regs)
|
|
{
|
|
i386_put_eax(regs, i386_save(regs));
|
|
@@ -70,7 +70,7 @@ l4_arch_setup_restart(struct pt_regs *re
|
|
|
|
#define __NR_restart_syscall 0
|
|
|
|
-extern inline void
|
|
+static inline void
|
|
l4_arch_setup_sys_restart(struct pt_regs *regs)
|
|
{
|
|
i386_put_eax(regs, __NR_restart_syscall);
|
|
diff -urNpB kernel-2.6.23-v2/include/asm-l4/i386/syscalls.h contrib/include/asm-l4/i386/syscalls.h
|
|
--- kernel-2.6.23-v2/include/asm-l4/i386/syscalls.h
|
|
+++ contrib/include/asm-l4/i386/syscalls.h
|
|
@@ -47,7 +47,7 @@ extern l4_i386_abi_syscalls_t l4_i386_ab
|
|
|
|
#ifdef CONFIG_IA32_VDSO_ENABLE
|
|
|
|
-extern inline void
|
|
+static inline void
|
|
l4_i386_get_fast_syscall_args(struct pt_regs *regs)
|
|
{
|
|
/* TODO: ensure sp is valid */
|
|
@@ -69,7 +69,7 @@ l4_i386_get_fast_syscall_args(struct pt_
|
|
|
|
#endif /* ifdef CONFIG_IA32_VDSO_ENABLE */
|
|
|
|
-extern inline long
|
|
+static inline long
|
|
l4_arch_lookup_syscall (struct pt_regs *regs, L4_Word_t *abi)
|
|
{
|
|
L4_Word_t call;
|
|
@@ -98,7 +98,7 @@ typedef L4_Word_t func_four_arg_t(L4_Wor
|
|
typedef L4_Word_t func_five_arg_t(L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t);
|
|
typedef L4_Word_t func_six_arg_t(L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t);
|
|
|
|
-extern inline L4_Word_t
|
|
+static inline L4_Word_t
|
|
l4_arch_abi_call(struct pt_regs *regs, L4_Word_t sys_num, L4_Word_t abi)
|
|
{
|
|
L4_Word_t result = -1ul;
|
|
@@ -159,13 +159,13 @@ l4_arch_abi_call(struct pt_regs *regs, L
|
|
return result;
|
|
}
|
|
|
|
-extern inline long
|
|
+static inline long
|
|
l4_arch_get_error(struct pt_regs *regs)
|
|
{
|
|
return -(long)i386_eax(regs);
|
|
}
|
|
|
|
-extern inline int
|
|
+static inline int
|
|
l4_arch_restart_syscall(struct pt_regs *regs)
|
|
{
|
|
L4_Word_t temp;
|
|
diff -urNpB kernel-2.6.23-v2/include/asm-l4/signal_l4.h contrib/include/asm-l4/signal_l4.h
|
|
--- kernel-2.6.23-v2/include/asm-l4/signal_l4.h
|
|
+++ contrib/include/asm-l4/signal_l4.h
|
|
@@ -22,7 +22,7 @@ static inline int need_to_resched(struct
|
|
|
|
extern void do_syscall_trace(int, void *);
|
|
|
|
-extern inline void
|
|
+static inline void
|
|
syscall_entry(struct thread_info * my_info)
|
|
{
|
|
if (unlikely(need_syscall_trace(my_info)))
|
|
@@ -34,7 +34,7 @@ syscall_entry(struct thread_info * my_in
|
|
}
|
|
}
|
|
|
|
-extern inline void
|
|
+static inline void
|
|
syscall_exit(struct thread_info * my_info, int syscall)
|
|
{
|
|
if (unlikely( syscall && need_syscall_trace(my_info) ))
|
|
@@ -46,7 +46,7 @@ syscall_exit(struct thread_info * my_inf
|
|
}
|
|
}
|
|
|
|
-extern inline int
|
|
+static inline int
|
|
l4_work_pending(struct thread_info * my_info, int syscall, struct pt_regs *regs)
|
|
{
|
|
if (unlikely( need_to_resched(my_info) )) {
|
|
@@ -59,7 +59,7 @@ l4_work_pending(struct thread_info * my_
|
|
return 0;
|
|
}
|
|
|
|
-extern inline int
|
|
+static inline int
|
|
l4_work_pending_preempt(struct pt_regs *regs)
|
|
{
|
|
int restart = 0;
|
|
diff -urNpB kernel-2.6.23-v2/include/asm-l4/system.h contrib/include/asm-l4/system.h
|
|
--- kernel-2.6.23-v2/include/asm-l4/system.h
|
|
+++ contrib/include/asm-l4/system.h
|
|
@@ -8,7 +8,7 @@
|
|
#include <linux/irqflags.h>
|
|
|
|
struct task_struct;
|
|
-extern asmlinkage void *__switch_to(struct task_struct *prev, struct task_struct *next);
|
|
+extern void *__switch_to(struct task_struct *prev, struct task_struct *next);
|
|
|
|
#include <l4/kdebug.h>
|
|
#include <l4/thread.h>
|
|
diff -urNpB kernel-2.6.23-v2/include/asm-l4/uaccess.h contrib/include/asm-l4/uaccess.h
|
|
--- kernel-2.6.23-v2/include/asm-l4/uaccess.h
|
|
+++ contrib/include/asm-l4/uaccess.h
|
|
@@ -101,7 +101,7 @@ static inline int verify_area(int type,
|
|
return 0;
|
|
}
|
|
|
|
-#define access_ok(type,addr,size) 1
|
|
+#define access_ok(type,addr,size) (((unsigned long)addr != size) || 1)
|
|
|
|
#endif
|
|
|
|
diff -urNpB kernel-2.6.23-v2/include/asm-l4/unistd.h contrib/include/asm-l4/unistd.h
|
|
--- kernel-2.6.23-v2/include/asm-l4/unistd.h
|
|
+++ contrib/include/asm-l4/unistd.h
|
|
@@ -30,19 +30,19 @@
|
|
|
|
asmlinkage long sys_wait4(pid_t pid, int __user *stat_addr,
|
|
int options, struct rusage __user *ru);
|
|
-extern long sys_open(const char *filename, int flags, int mode);
|
|
-extern long sys_dup(unsigned int fildes);
|
|
-extern long sys_close(unsigned int fd);
|
|
+extern asmlinkage long sys_open(const char *filename, int flags, int mode);
|
|
+extern asmlinkage long sys_dup(unsigned int fildes);
|
|
+extern asmlinkage long sys_close(unsigned int fd);
|
|
extern int __execve(char *file, char **argv, char **env);
|
|
extern int sys_execve(char *file, char **argv, char **env);
|
|
-extern long sys_setsid(void);
|
|
-extern long sys_mount(char *dev_name, char *dir_name, char *type,
|
|
+extern asmlinkage long sys_setsid(void);
|
|
+extern asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
|
|
unsigned long flags, void *data);
|
|
-extern long sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
|
|
+extern asmlinkage long sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
|
|
struct timeval *tvp);
|
|
-extern off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin);
|
|
-extern ssize_t sys_read(unsigned int fd, char __user *buf, size_t count);
|
|
-extern ssize_t sys_write(unsigned int fd, const char __user *buf, size_t count);
|
|
+extern asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin);
|
|
+extern asmlinkage ssize_t sys_read(unsigned int fd, char __user *buf, size_t count);
|
|
+extern asmlinkage ssize_t sys_write(unsigned int fd, const char __user *buf, size_t count);
|
|
|
|
#define KERNEL_CALL(ret_t, sys, args...) \
|
|
mm_segment_t fs = get_fs(); \
|
|
diff -urNpB kernel-2.6.23-v2/kernel/mutex.c contrib/kernel/mutex.c
|
|
--- kernel-2.6.23-v2/kernel/mutex.c
|
|
+++ contrib/kernel/mutex.c
|
|
@@ -57,7 +57,7 @@ EXPORT_SYMBOL(__mutex_init);
|
|
* We also put the fastpath first in the kernel image, to make sure the
|
|
* branch is predicted by the CPU as default-untaken.
|
|
*/
|
|
-static void fastcall noinline __sched
|
|
+void fastcall noinline __sched
|
|
__mutex_lock_slowpath(atomic_t *lock_count);
|
|
|
|
/***
|
|
@@ -93,7 +93,7 @@ void inline fastcall __sched mutex_lock(
|
|
|
|
EXPORT_SYMBOL(mutex_lock);
|
|
|
|
-static void fastcall noinline __sched
|
|
+void fastcall noinline __sched
|
|
__mutex_unlock_slowpath(atomic_t *lock_count);
|
|
|
|
/***
|
|
@@ -197,7 +197,7 @@ done:
|
|
return 0;
|
|
}
|
|
|
|
-static void fastcall noinline __sched
|
|
+void fastcall noinline __sched
|
|
__mutex_lock_slowpath(atomic_t *lock_count)
|
|
{
|
|
struct mutex *lock = container_of(lock_count, struct mutex, count);
|
|
@@ -265,7 +265,7 @@ __mutex_unlock_common_slowpath(atomic_t
|
|
/*
|
|
* Release the lock, slowpath:
|
|
*/
|
|
-static fastcall noinline void
|
|
+fastcall noinline void
|
|
__mutex_unlock_slowpath(atomic_t *lock_count)
|
|
{
|
|
__mutex_unlock_common_slowpath(lock_count, 1);
|
|
diff -urNpB kernel-2.6.23-v2/mm/slab.c contrib/mm/slab.c
|
|
--- kernel-2.6.23-v2/mm/slab.c
|
|
+++ contrib/mm/slab.c
|
|
@@ -3758,6 +3758,7 @@ void kfree(const void *objp)
|
|
{
|
|
struct kmem_cache *c;
|
|
unsigned long flags;
|
|
+ void *ptr = (void*)objp;
|
|
|
|
if (unlikely(ZERO_OR_NULL_PTR(objp)))
|
|
return;
|
|
@@ -3765,7 +3766,7 @@ void kfree(const void *objp)
|
|
kfree_debugcheck(objp);
|
|
c = virt_to_cache(objp);
|
|
debug_check_no_locks_freed(objp, obj_size(c));
|
|
- __cache_free(c, (void *)objp);
|
|
+ __cache_free(c, /*(void *)objp*/ptr);
|
|
local_irq_restore(flags);
|
|
}
|
|
EXPORT_SYMBOL(kfree);
|
|
diff -urNpB kernel-2.6.23-v2/scripts/checksyscalls.sh contrib/scripts/checksyscalls.sh
|
|
--- kernel-2.6.23-v2/scripts/checksyscalls.sh
|
|
+++ contrib/scripts/checksyscalls.sh
|
|
@@ -119,5 +119,9 @@ sed -n -e '/^\#define/ { s/[^_]*__NR_\([
|
|
\#endif/p }' $1
|
|
}
|
|
|
|
+echo "SRCTREE"
|
|
+echo "${srctree}"
|
|
+echo "END"
|
|
+
|
|
(ignore_list && syscall_list ${srctree}/include/asm-i386/unistd.h) | \
|
|
$* -E -x c - > /dev/null
|