genode/ports-okl4/patches/oklx_genode.patch

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 config \
+ 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,
&current_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