File linux-2.6-cell-mambo-drivers.patch of Package kernel

--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -332,6 +332,27 @@ config PPC_OF
 	depends on PPC_MULTIPLATFORM	# for now
 	default y
 
+# Systemsim configuration
+config MAMBO
+        bool "  IBM Full System Simulator (systemsim) support"
+        default n
+        ---help---
+           Support booting resulting image under IBMs Full System Simulator.
+config MAMBO_DISK
+        depends on MAMBO
+        tristate "    IBM Full System Simulator Bogus Disk Support"
+        default y
+        ---help---
+           Provides quick access to disk images in the simulator without
+           simulating a full IDE or SCSI device.
+config MAMBO_NET
+        depends on MAMBO
+        tristate "    IBM Full System Simulator Bogus Network Support"
+        default y
+        ---help---
+           Provides quick access to a raw ethernet device in the simulator
+           without simulating any specific network device hardware.
+
 config XICS
 	depends on PPC_PSERIES
 	bool
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_BLK_DEV_UMEM)	+= umem.o
 obj-$(CONFIG_BLK_DEV_NBD)	+= nbd.o
 obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o
 
+obj-$(CONFIG_MAMBO_DISK)	+= mambo_bd.o
 obj-$(CONFIG_VIODASD)		+= viodasd.o
 obj-$(CONFIG_BLK_DEV_SX8)	+= sx8.o
 obj-$(CONFIG_BLK_DEV_UB)	+= ub.o
--- /dev/null
+++ b/drivers/block/mambo_bd.c
@@ -0,0 +1,285 @@
+/*
+ *  Bogus Block Driver for PowerPC Full System Simulator
+ *
+ *  (C) Copyright IBM Corporation 2003-2005
+ *
+ *  Bogus Disk Driver
+ *
+ *  Author: Eric Van Hensbegren <ericvh@gmail.com>
+ *
+ *    inspired by drivers/block/nbd.c
+ *    written by Pavel Machek and Steven Whitehouse
+ *
+ *  Some code is from the IBM Full System Simulator Group in ARL
+ *  Author: PAtrick Bohrer <IBM Austin Research Lab>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02111-1301  USA
+ *
+ */
+
+#include <linux/major.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/file.h>
+#include <linux/ioctl.h>
+#include <linux/blkdev.h>
+#include <net/sock.h>
+
+#include <asm/systemsim.h>
+
+#include <asm/uaccess.h>
+#include <asm/types.h>
+
+#define MAJOR_NR 112
+#define MAX_MBD 128
+
+#define MBD_SET_BLKSIZE _IO( 0xab, 1 )
+#define MBD_SET_SIZE    _IO( 0xab, 2 )
+#define MBD_SET_SIZE_BLOCKS     _IO( 0xab, 7 )
+#define MBD_DISCONNECT  _IO( 0xab, 8 )
+
+struct mbd_device {
+	int initialized;
+	int refcnt;
+	int flags;
+	struct gendisk *disk;
+};
+
+static struct mbd_device mbd_dev[MAX_MBD];
+
+#define BD_INFO_SYNC   0
+#define BD_INFO_STATUS 1
+#define BD_INFO_BLKSZ  2
+#define BD_INFO_DEVSZ  3
+#define BD_INFO_CHANGE 4
+
+#define BOGUS_DISK_READ  116
+#define BOGUS_DISK_WRITE 117
+#define BOGUS_DISK_INFO  118
+
+static inline int
+MamboBogusDiskRead(int devno, void *buf, ulong sect, ulong nrsect)
+{
+	return callthru3(BOGUS_DISK_READ, (unsigned long)buf,
+			 (unsigned long)sect,
+			 (unsigned long)((nrsect << 16) | devno));
+}
+
+static inline int
+MamboBogusDiskWrite(int devno, void *buf, ulong sect, ulong nrsect)
+{
+	return callthru3(BOGUS_DISK_WRITE, (unsigned long)buf,
+			 (unsigned long)sect,
+			 (unsigned long)((nrsect << 16) | devno));
+}
+
+static inline int MamboBogusDiskInfo(int op, int devno)
+{
+	return callthru2(BOGUS_DISK_INFO, (unsigned long)op,
+			 (unsigned long)devno);
+}
+
+static int mbd_init_disk(int devno)
+{
+	struct gendisk *disk = mbd_dev[devno].disk;
+	unsigned int sz;
+
+	if (!__onsim())
+		return -1;
+
+	/* check disk configured */
+	if (!MamboBogusDiskInfo(BD_INFO_STATUS, devno)) {
+		printk(KERN_ERR
+		       "Attempting to open bogus disk before initializaiton\n");
+		return 0;
+	}
+
+	mbd_dev[devno].initialized++;
+
+	sz = MamboBogusDiskInfo(BD_INFO_DEVSZ, devno);
+
+	if (sz == -1)
+		return 0;
+
+	printk("Initializing disk %d with devsz %u\n", devno, sz);
+
+	set_capacity(disk, sz << 1);
+
+	return 1;
+}
+
+static void do_mbd_request(request_queue_t * q)
+{
+	int result = 0;
+	struct request *req;
+
+	while ((req = elv_next_request(q)) != NULL) {
+		int minor = req->rq_disk->first_minor;
+
+		switch (rq_data_dir(req)) {
+		case READ:
+			result = MamboBogusDiskRead(minor,
+						    req->buffer, req->sector,
+						    req->current_nr_sectors);
+			break;
+		case WRITE:
+			result = MamboBogusDiskWrite(minor,
+						     req->buffer, req->sector,
+						     req->current_nr_sectors);
+		};
+
+		if (result)
+			end_request(req, 0);	/* failure */
+		else
+			end_request(req, 1);	/* success */
+	}
+}
+
+static int mbd_release(struct inode *inode, struct file *file)
+{
+	struct mbd_device *lo;
+	int dev;
+
+	if (!inode)
+		return -ENODEV;
+	dev = inode->i_bdev->bd_disk->first_minor;
+	if (dev >= MAX_MBD)
+		return -ENODEV;
+	if (MamboBogusDiskInfo(BD_INFO_SYNC, dev) < 0) {
+		printk(KERN_ALERT "mbd_release: unable to sync\n");
+	}
+	lo = &mbd_dev[dev];
+	if (lo->refcnt <= 0)
+		printk(KERN_ALERT "mbd_release: refcount(%d) <= 0\n",
+		       lo->refcnt);
+	lo->refcnt--;
+	return 0;
+}
+
+static int mbd_revalidate(struct gendisk *disk)
+{
+	int devno = disk->first_minor;
+
+	mbd_init_disk(devno);
+
+	return 0;
+}
+
+static int mbd_open(struct inode *inode, struct file *file)
+{
+	int dev;
+
+	if (!inode)
+		return -EINVAL;
+	dev = inode->i_bdev->bd_disk->first_minor;
+	if (dev >= MAX_MBD)
+		return -ENODEV;
+
+	check_disk_change(inode->i_bdev);
+
+	if (!mbd_dev[dev].initialized)
+		if (!mbd_init_disk(dev))
+			return -ENODEV;
+
+	mbd_dev[dev].refcnt++;
+	return 0;
+}
+
+static struct block_device_operations mbd_fops = {
+      owner:THIS_MODULE,
+      open:mbd_open,
+      release:mbd_release,
+	/* media_changed:      mbd_check_change, */
+      revalidate_disk:mbd_revalidate,
+};
+
+static spinlock_t mbd_lock = SPIN_LOCK_UNLOCKED;
+
+static int __init mbd_init(void)
+{
+	int err = -ENOMEM;
+	int i;
+
+	for (i = 0; i < MAX_MBD; i++) {
+		struct gendisk *disk = alloc_disk(1);
+		if (!disk)
+			goto out;
+		mbd_dev[i].disk = disk;
+		/*
+		 * The new linux 2.5 block layer implementation requires
+		 * every gendisk to have its very own request_queue struct.
+		 * These structs are big so we dynamically allocate them.
+		 */
+		disk->queue = blk_init_queue(do_mbd_request, &mbd_lock);
+		if (!disk->queue) {
+			put_disk(disk);
+			goto out;
+		}
+	}
+
+	if (register_blkdev(MAJOR_NR, "mbd")) {
+		err = -EIO;
+		goto out;
+	}
+#ifdef MODULE
+	printk("mambo bogus disk: registered device at major %d\n", MAJOR_NR);
+#else
+	printk("mambo bogus disk: compiled in with kernel\n");
+#endif
+
+	for (i = 0; i < MAX_MBD; i++) {	/* load defaults */
+		struct gendisk *disk = mbd_dev[i].disk;
+		mbd_dev[i].initialized = 0;
+		mbd_dev[i].refcnt = 0;
+		mbd_dev[i].flags = 0;
+		disk->major = MAJOR_NR;
+		disk->first_minor = i;
+		disk->fops = &mbd_fops;
+		disk->private_data = &mbd_dev[i];
+		sprintf(disk->disk_name, "mambobd%d", i);
+		set_capacity(disk, 0x7ffffc00ULL << 1);	/* 2 TB */
+		add_disk(disk);
+	}
+
+	return 0;
+      out:
+	while (i--) {
+		if (mbd_dev[i].disk->queue)
+			blk_cleanup_queue(mbd_dev[i].disk->queue);
+		put_disk(mbd_dev[i].disk);
+	}
+	return -EIO;
+}
+
+static void __exit mbd_cleanup(void)
+{
+	if (unregister_blkdev(MAJOR_NR, "mbd") != 0)
+		printk("mbd: cleanup_module failed\n");
+	else
+		printk("mbd: module cleaned up.\n");
+}
+
+module_init(mbd_init);
+module_exit(mbd_cleanup);
+
+MODULE_DESCRIPTION("Mambo Block Device");
+MODULE_LICENSE("GPL");
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -140,6 +140,7 @@ obj-$(CONFIG_EL3) += 3c509.o
 obj-$(CONFIG_3C515) += 3c515.o
 obj-$(CONFIG_EEXPRESS) += eexpress.o
 obj-$(CONFIG_EEXPRESS_PRO) += eepro.o
+obj-$(CONFIG_MAMBO_NET) += mambonet.o
 obj-$(CONFIG_8139CP) += 8139cp.o
 obj-$(CONFIG_8139TOO) += 8139too.o
 obj-$(CONFIG_ZNET) += znet.o
--- /dev/null
+++ b/drivers/net/mambonet.c
@@ -0,0 +1,391 @@
+/*
+ *  Bogus Network Driver for PowerPC Full System Simulator
+ *
+ *  (C) Copyright IBM Corporation 2003-2005
+ *
+ *  Bogus Network Driver
+ * 
+ *  Author: JimiX <jimix@watson.ibm.com>
+ *  Maintained By: Eric Van Hensbergen <ericvh@gmail.com>
+ *
+ * 	inspired by drivers/net/ibmveth.c
+ *	written by Dave Larson 
+ *
+ *  Some code is from the IBM Full System Simulator Group in ARL
+ *  Author: Patrick Bohrer <IBM Austin Research Lab>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ * 
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to:
+ *  Free Software Foundation
+ *  51 Franklin Street, Fifth Floor
+ *  Boston, MA  02111-1301  USA
+ *  
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/socket.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/in.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <linux/if_ether.h>	/* For the statistics structure. */
+#include <linux/if_arp.h>	/* For ARPHRD_ETHER */
+#include <linux/workqueue.h>
+#include <asm/prom.h>
+#include <asm/systemsim.h>
+
+#define MAMBO_BOGUS_NET_PROBE   119
+#define MAMBO_BOGUS_NET_SEND    120
+#define MAMBO_BOGUS_NET_RECV    121
+
+static inline int MamboBogusNetProbe(int devno, void *buf)
+{
+	return callthru2(MAMBO_BOGUS_NET_PROBE,
+			 (unsigned long)devno, (unsigned long)buf);
+}
+
+static inline int MamboBogusNetSend(int devno, void *buf, ulong size)
+{
+	return callthru3(MAMBO_BOGUS_NET_SEND,
+			 (unsigned long)devno,
+			 (unsigned long)buf, (unsigned long)size);
+}
+
+static inline int MamboBogusNetRecv(int devno, void *buf, ulong size)
+{
+	return callthru3(MAMBO_BOGUS_NET_RECV,
+			 (unsigned long)devno,
+			 (unsigned long)buf, (unsigned long)size);
+}
+
+static irqreturn_t
+mambonet_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+
+#define INIT_BOTTOM_HALF(x,y,z) INIT_WORK(x, y, (void*)z)
+#define SCHEDULE_BOTTOM_HALF(x) schedule_delayed_work(x, 1)
+#define KILL_BOTTOM_HALF(x) cancel_delayed_work(x); flush_scheduled_work()
+
+#define MAMBO_MTU 1500
+
+struct netdev_private {
+	int devno;
+	int closing;
+	struct work_struct poll_task;
+	struct net_device_stats stats;
+};
+
+static int mambonet_probedev(int devno, void *buf)
+{
+	struct device_node *mambo;
+	struct device_node *net;
+	unsigned int *reg;
+
+	mambo = find_path_device("/mambo");
+
+	if (mambo == NULL) {
+		return -1;
+	}
+	net = find_path_device("/mambo/bogus-net@0");
+	if (net == NULL) {
+		return -1;
+	}
+	reg = (unsigned int *)get_property(net, "reg", 0);
+
+	if (*reg != devno) {
+		return -1;
+	}
+
+	return MamboBogusNetProbe(devno, buf);
+}
+
+static int mambonet_send(int devno, void *buf, ulong size)
+{
+	return MamboBogusNetSend(devno, buf, size);
+}
+
+static int mambonet_recv(int devno, void *buf, ulong size)
+{
+	return MamboBogusNetRecv(devno, buf, size);
+}
+
+static int mambonet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct netdev_private *priv = (struct netdev_private *)dev->priv;
+	int devno = priv->devno;
+
+	skb->dev = dev;
+
+	/* we might need to checksum or something */
+	mambonet_send(devno, skb->data, skb->len);
+
+	dev->last_rx = jiffies;
+	priv->stats.rx_bytes += skb->len;
+	priv->stats.tx_bytes += skb->len;
+	priv->stats.rx_packets++;
+	priv->stats.tx_packets++;
+
+	dev_kfree_skb(skb);
+
+	return (0);
+}
+
+static int mambonet_poll(struct net_device *dev, int *budget)
+{
+	struct netdev_private *np = dev->priv;
+	int devno = np->devno;
+	char buffer[1600];
+	int ns;
+	struct sk_buff *skb;
+	int frames = 0;
+	int max_frames = min(*budget, dev->quota);
+	int ret = 0;
+
+	while ((ns = mambonet_recv(devno, buffer, 1600)) > 0) {
+		if ((skb = dev_alloc_skb(ns + 2)) != NULL) {
+			skb->dev = dev;
+			skb_reserve(skb, 2);	/* 16 byte align the IP
+						 * header */
+#ifdef HAS_IP_COPYSUM
+			eth_copy_and_sum(skb, buffer, ns, 0);
+			skb_put(skb, ns);
+#else
+			memcpy(skb_put(skb, ns), buffer, ns);
+#endif
+			skb->protocol = eth_type_trans(skb, dev);
+
+			if (dev->irq)
+				netif_receive_skb(skb);
+			else
+				netif_rx(skb);
+
+			dev->last_rx = jiffies;
+			np->stats.rx_packets++;
+			np->stats.rx_bytes += ns;
+		} else {
+			printk("Failed to allocated skbuff, "
+			       "dropping packet\n");
+			np->stats.rx_dropped++;
+			/* wait for another cycle */
+			return 1;
+		}
+		++frames;
+		if (frames > max_frames) {
+			ret = 1;
+			break;
+		}
+	}
+	*budget -= frames;
+	dev->quota -= frames;
+
+	if ((!ret) && (dev->irq))
+		netif_rx_complete(dev);
+
+	return ret;
+}
+
+static void mambonet_timer(struct net_device *dev)
+{
+	int budget = 16;
+	struct netdev_private *priv = (struct netdev_private *)dev->priv;
+
+	mambonet_poll(dev, &budget);
+
+	if (!priv->closing) {
+		SCHEDULE_BOTTOM_HALF(&priv->poll_task);
+	}
+}
+
+static struct net_device_stats *get_stats(struct net_device *dev)
+{
+	struct netdev_private *priv = (struct netdev_private *)dev->priv;
+	return (struct net_device_stats *)&(priv->stats);
+}
+
+static irqreturn_t
+mambonet_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct net_device *dev = dev_instance;
+	if (netif_rx_schedule_prep(dev)) {
+		__netif_rx_schedule(dev);
+	}
+	return IRQ_HANDLED;
+}
+
+static int mambonet_open(struct net_device *dev)
+{
+	struct netdev_private *priv;
+	int ret = 0;
+
+	priv = dev->priv;
+
+	/*
+	 * we can't start polling in mambonet_init, because I don't think
+	 * workqueues are usable that early. so start polling now.
+	 */
+
+	if (dev->irq) {
+		ret = request_irq(dev->irq, &mambonet_interrupt, 0,
+				  dev->name, dev);
+
+		if (ret == 0) {
+			netif_start_queue(dev);
+		} else {
+			printk(KERN_ERR "mambonet: request irq failed\n");
+		}
+
+		MamboBogusNetProbe(priv->devno, NULL);	/* probe with NULL to activate interrupts */
+	} else {
+		mambonet_timer(dev);
+	}
+
+	return ret;
+}
+
+static int mambonet_close(struct net_device *dev)
+{
+	struct netdev_private *priv;
+
+	netif_stop_queue(dev);
+
+	if (dev->irq)
+		free_irq(dev->irq, dev);
+
+	priv = dev->priv;
+	priv->closing = 1;
+	if (dev->irq == 0) {
+		KILL_BOTTOM_HALF(&priv->poll_task);
+	}
+
+	kfree(priv);
+
+	return 0;
+}
+
+static struct net_device_stats mambonet_stats;
+
+static struct net_device_stats *mambonet_get_stats(struct net_device *dev)
+{
+	return &mambonet_stats;
+}
+
+static int mambonet_set_mac_address(struct net_device *dev, void *p)
+{
+	return -EOPNOTSUPP;
+}
+static int mambonet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	return -EOPNOTSUPP;
+}
+static int nextdevno = 0;	/* running count of device numbers */
+
+/* Initialize the rest of the device. */
+int __init do_mambonet_probe(struct net_device *dev)
+{
+	struct netdev_private *priv;
+	int devno = nextdevno++;
+	int irq;
+
+	printk("eth%d: bogus network driver initialization\n", devno);
+
+	irq = mambonet_probedev(devno, dev->dev_addr);
+
+	if (irq < 0) {
+		printk("No IRQ retreived\n");
+		return (-ENODEV);
+	}
+
+	printk("%s: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", dev->name,
+	       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+	       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+
+	SET_MODULE_OWNER(dev);
+
+	dev->irq = irq;
+	dev->mtu = MAMBO_MTU;
+	dev->open = mambonet_open;
+	dev->poll = mambonet_poll;
+	dev->weight = 16;
+	dev->stop = mambonet_close;
+	dev->hard_start_xmit = mambonet_start_xmit;
+	dev->get_stats = mambonet_get_stats;
+	dev->set_mac_address = mambonet_set_mac_address;
+	dev->do_ioctl = mambonet_ioctl;
+
+	dev->priv = kmalloc(sizeof(struct netdev_private), GFP_KERNEL);
+	if (dev->priv == NULL)
+		return -ENOMEM;
+	memset(dev->priv, 0, sizeof(struct netdev_private));
+
+	priv = dev->priv;
+	priv->devno = devno;
+	priv->closing = 0;
+	dev->get_stats = get_stats;
+
+	if (dev->irq == 0) {
+		INIT_BOTTOM_HALF(&priv->poll_task, (void *)mambonet_timer,
+				 (void *)dev);
+	}
+
+	return (0);
+};
+
+struct net_device *__init mambonet_probe(int unit)
+{
+	struct net_device *dev = alloc_etherdev(0);
+	int err;
+
+	if (!dev)
+		return ERR_PTR(-ENODEV);
+
+	sprintf(dev->name, "eth%d", unit);
+	netdev_boot_setup_check(dev);
+
+	err = do_mambonet_probe(dev);
+
+	if (err)
+		goto out;
+
+	err = register_netdev(dev);
+	if (err)
+		goto out;
+
+	return dev;
+
+      out:
+	free_netdev(dev);
+	return ERR_PTR(err);
+}
+
+int __init init_mambonet(void)
+{
+	mambonet_probe(0);
+	return 0;
+}
+
+module_init(init_mambonet);
+MODULE_LICENSE("GPL");
--- /dev/null
+++ b/include/asm-powerpc/systemsim.h
@@ -0,0 +1,130 @@
+/*********************************************************
+ *
+ * Copyright (C) 2001, 2005 IBM
+ * 
+ * Filename	: systemsim.h
+ *
+ * Originator	: Patrick Bohrer and Charles Lefurgy
+ * Modified By	: Eric Van Hensbegren <ericvh@gmail.com>
+ *
+ * Purpose	: 
+ *
+ *   This file is compiled with programs that are run under the 
+ *   PowerPC Full System simulator.  For example, stand-alone programs 
+ *   or operating systems.  The programs call the callthru wrapper 
+ *   functions which use an illegal PowerPC instruction to signal the 
+ *   simulator to emulate special support.
+ *
+ *********************************************************/
+
+#ifndef _SYSTEMSIM_CONFIG_H_
+#define _SYSTEMSIM_CONFIG_H_
+
+/* The functions callthru0 to callthru5 setup up the arguments for the
+ * simulator callthru and then use the callthru instruction.  Note that
+ * 0-5 specify the number of arguments after the command */
+
+/* Note: Arguments are cast as void* to prevent casting by the
+   compiler.  This way, you can pass pointers, integers, etc. in
+   machine register and have the simulator interpret what the
+   register is supposed to be.  To help with typing errors when using
+   callthrus, we provide wrapper functions for each callthru.  The
+   wrappers cast all arguments to void*.  Unfortunately, this results
+   in a lot of compiler warnings that I do not know how to remove.  If
+   you modify this code, be aware that we are trying to pick a type
+   that is the size of the registers (32-bit or 64-bit) and that is
+   why are choosing to cast to a void* (it should be the size of a
+   machine register) */
+
+static inline int callthru0(int command)
+{
+	register int c asm("r3") = command;
+	asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c));
+	return (c);
+}
+static inline int callthru1(int command, unsigned long arg1)
+{
+	register int c asm("r3") = command;
+	register unsigned long a1 asm("r4") = arg1;
+	asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1));
+	return (c);
+}
+static inline int callthru2(int command, unsigned long arg1, unsigned long arg2)
+{
+	register int c asm("r3") = command;
+	register unsigned long a1 asm("r4") = arg1;
+	register unsigned long a2 asm("r5") = arg2;
+	asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2));
+	return (c);
+}
+static inline int callthru3(int command, unsigned long arg1, unsigned long arg2,
+			    unsigned long arg3)
+{
+	register int c asm("r3") = command;
+	register unsigned long a1 asm("r4") = arg1;
+	register unsigned long a2 asm("r5") = arg2;
+	register unsigned long a3 asm("r6") = arg3;
+	asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2),
+		      "r"(a3));
+	return (c);
+}
+static inline int callthru4(int command, unsigned long arg1, unsigned long arg2,
+			    unsigned long arg3, unsigned long arg4)
+{
+	register int c asm("r3") = command;
+	register unsigned long a1 asm("r4") = arg1;
+	register unsigned long a2 asm("r5") = arg2;
+	register unsigned long a3 asm("r6") = arg3;
+	register unsigned long a4 asm("r7") = arg4;
+	asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2),
+		      "r"(a3), "r"(a4));
+	return (c);
+}
+static inline int callthru5(int command, unsigned long arg1, unsigned long arg2,
+			    unsigned long arg3, unsigned long arg4,
+			    unsigned long arg5)
+{
+	register int c asm("r3") = command;
+	register unsigned long a1 asm("r4") = arg1;
+	register unsigned long a2 asm("r5") = arg2;
+	register unsigned long a3 asm("r6") = arg3;
+	register unsigned long a4 asm("r7") = arg4;
+	register unsigned long a5 asm("r8") = arg5;
+	asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2),
+		      "r"(a3), "r"(a4), "r"(a5));
+	return (c);
+}
+static inline int callthru6(int command, unsigned long arg1, unsigned long arg2,
+			    unsigned long arg3, unsigned long arg4,
+			    unsigned long arg5, unsigned long arg6)
+{
+	register int c asm("r3") = command;
+	register unsigned long a1 asm("r4") = arg1;
+	register unsigned long a2 asm("r5") = arg2;
+	register unsigned long a3 asm("r6") = arg3;
+	register unsigned long a4 asm("r7") = arg4;
+	register unsigned long a5 asm("r8") = arg5;
+	register unsigned long a6 asm("r9") = arg6;
+	asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2),
+		      "r"(a3), "r"(a4), "r"(a5), "r"(a6));
+	return (c);
+}
+static inline int callthru7(int command, unsigned long arg1, unsigned long arg2,
+			    unsigned long arg3, unsigned long arg4,
+			    unsigned long arg5, unsigned long arg6,
+			    unsigned long arg7)
+{
+	register int c asm("r3") = command;
+	register unsigned long a1 asm("r4") = arg1;
+	register unsigned long a2 asm("r5") = arg2;
+	register unsigned long a3 asm("r6") = arg3;
+	register unsigned long a4 asm("r7") = arg4;
+	register unsigned long a5 asm("r8") = arg5;
+	register unsigned long a6 asm("r9") = arg6;
+	register unsigned long a7 asm("r10") = arg7;
+	asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2),
+		      "r"(a3), "r"(a4), "r"(a5), "r"(a6), "r"(a7));
+	return (c);
+}
+
+#endif/* _SYSTEMSIM_CONFIG_H_ */
--- a/include/linux/root_dev.h
+++ b/include/linux/root_dev.h
@@ -14,6 +14,9 @@ enum {
 	Root_SDA2 = MKDEV(SCSI_DISK0_MAJOR, 2),
 	Root_HDC1 = MKDEV(IDE1_MAJOR, 1),
 	Root_SR0 = MKDEV(SCSI_CDROM_MAJOR, 0),
+#ifdef CONFIG_MAMBO_DISK
+	Root_Mambo = MKDEV(112, 0),
+#endif
 };
 
 extern dev_t ROOT_DEV;
--- linux-2.6.15-rc.orig/include/asm-powerpc/processor.h
+++ linux-2.6.15-rc/include/asm-powerpc/processor.h
@@ -284,6 +284,23 @@ static inline void pause_zero(void)
 }
 #endif
 
+#ifdef CONFIG_PPC_CELL /* MAMBO SIMULATION code */
+#define MSR_SIM_LG      29
+#define MSR_SIM         __MASK(MSR_SIM_LG)
+
+static __inline__ int __onsim(void)
+{
+        unsigned long msr;
+        __asm__ __volatile__ ("mfmsr    %0" : "=&r" (msr));
+        return ((msr & MSR_SIM) ? 1 : 0);
+}
+#endif /* CONFIG_PPC_CELL */
+
 #endif /* __KERNEL__ */
+#else
+/* must be given a register to perform the compare, set cr0 = 1
+ * Usage: __onsim(r0); bne _if_onsim
+ */
+#define __onsim(r) mfmsr        r; rldicl. r,r,35,63
 #endif /* __ASSEMBLY__ */
 #endif /* _ASM_POWERPC_PROCESSOR_H */
openSUSE Build Service is sponsored by