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 */