Basic support for running on the IBM full system simulator Once we have the simulator out there with support for our CPU, we need a few tweaks to the kernel. In the current form, this is obviously not acceptable for inclusion, but it makes it possible to run our code for many more people. Index: linux-cg/arch/ppc64/kernel/bpa_iommu.c =================================================================== --- linux-cg.orig/arch/ppc64/kernel/bpa_iommu.c +++ linux-cg/arch/ppc64/kernel/bpa_iommu.c @@ -374,7 +374,11 @@ static int bpa_dma_supported(struct devi void bpa_init_iommu(void) { - bpa_map_iommu(); + if (__onsim()) { + printk(KERN_INFO "Not using iommu on mambo\n"); + } else { + bpa_map_iommu(); + } /* Direct I/O, IOMMU off */ ppc_md.iommu_dev_setup = iommu_dev_setup_null; Index: linux-cg/arch/ppc64/kernel/entry.S =================================================================== --- linux-cg.orig/arch/ppc64/kernel/entry.S +++ linux-cg/arch/ppc64/kernel/entry.S @@ -35,6 +35,10 @@ #define DO_SOFT_DISABLE #endif +_GLOBAL(callthru) + .long 0x7c0007cc + blr + /* * System calls. */ Index: linux-cg/include/asm-ppc64/processor.h =================================================================== --- linux-cg.orig/include/asm-ppc64/processor.h +++ linux-cg/include/asm-ppc64/processor.h @@ -347,6 +347,11 @@ name: \ .type GLUE(.,name),@function; \ GLUE(.,name): +/* 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 + #else /* __ASSEMBLY__ */ /* @@ -554,6 +559,18 @@ static inline void pause_zero(void) } #endif +#ifdef CONFIG_PPC_BPA /* 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_BPA */ + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ Index: linux-cg/include/stidc/callthru_config.h =================================================================== --- /dev/null +++ linux-cg/include/stidc/callthru_config.h @@ -0,0 +1,241 @@ +/********************************************************* + * + * (C) Copyright IBM Corporation 2001, 2003 + * + * Filename : callthru_config.h + * + * Originator : Patrick Bohrer + * + * Purpose : + * + * This file is compiled with programs that are run under the Mambo + * simulator. For example, stand-alone programs or operating + * systems. (This file is not compiled info Mambo!) The programs + * call the callthru wrapper functions which use an illegal PowerPC + * instruction to signal the Mambo simulator to emulate special + * support. + * + *********************************************************/ + +#ifndef _CALLTHRU_CONFIG_H_ +#define _CALLTHRU_CONFIG_H_ + +#include "sim_support_code.h" + +#define CAST(t,e) ((t)(e)) + +/* The AIX xlc compiler does not seem to like the gcc + "static inline" declaration. */ +#ifdef __GNUC__ +#define INLINE static inline +#else /* #ifdef __GNUC__ */ +#define INLINE static +#endif /* #ifdef __GNUC__ */ + + +/* The functions callthru0 to callthru5 setup up the arguments for the + * Mambo callthru and then use the callthru instruction. Note that + * 0-5 specify the number of arguments after the command */ + +/* Note: Arguments are cast as unsigned long to prevent casting by the + compiler. This way, you can pass pointers, integers, etc. in + machine register and have the Mambo 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 unsigned long. 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) */ + +INLINE int callthru0(int command) +{ + register int c asm ("r3") = command; + asm volatile (".long 0x000EAEB0" : "=r" (c): "r" (c)); + return((c)); +} +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)); +} +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)); +} +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)); +} +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)); +} +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)); +} +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)); +} +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)); +} + + + +/* Wrappers for simulator callthrus */ + +INLINE int MamboWriteConsole( char *string ) +{ + return(callthru3( SimWriteConsoleCode, CAST(unsigned long,string), CAST(unsigned long,strlen(string)), CAST(unsigned long,1) )); +} + +INLINE int MamboStopSimulation(void) +{ + return(callthru0( SimExitCode)); +} + +INLINE int MamboReadConsole(void) +{ + return(callthru0( SimReadConsoleCode)); +} + +INLINE int MamboThinIPRead( char *string, int length ) +{ + return(callthru2( SimThinIPReadCode, CAST(unsigned long,string), CAST(unsigned long,length))); +} + +INLINE int MamboThinIPWrite( char *string, int length ) +{ + return(callthru2( SimThinIPWriteCode, CAST(unsigned long,string), CAST(unsigned long,length))); +} + +INLINE int MamboGetConfig( CallthruConfig *config ) +{ + return(callthru1( SimGetConfigCode, CAST(unsigned long,config))); +} + +INLINE int MamboLogStats( char *comment, int id ) +{ + return(callthru2( SimLogStatsCode, CAST(unsigned long,comment), CAST(unsigned long,id))); +} + +INLINE int MamboPPCOnly( int newstate ) +{ + return(callthru1( SimPPCOnlyCode, CAST(unsigned long,newstate))); +} + +INLINE int MamboPIDCreate(int parent, int pid, int flags) +{ + return(callthru3(SimPIDCreateCode,CAST(unsigned long,parent),CAST(unsigned long,pid),CAST(unsigned long,flags))); +} + +INLINE int MamboPIDExecExit(int pid) +{ + return(callthru1(SimPIDExecExitCode, CAST(unsigned long,pid))); +} + +INLINE int MamboPIDExec(int pid, char *filename, int len) +{ + return(callthru3(SimPIDExecCode, CAST(unsigned long,pid), CAST(unsigned long,filename), CAST(unsigned long,len))); +} + +INLINE int MamboPIDResume(int processor, int pid) +{ + return(callthru3(SimPIDResumeCode, CAST(unsigned long,processor), CAST(unsigned long,pid), CAST(unsigned long,0))); +} + +INLINE int MamboPIDKill(int pid) +{ + return(callthru1(SimPIDKillCode,CAST(unsigned long,pid))); +} +INLINE int MamboKernelThreadCreate(int parent, int pid, int flags) +{ + return(callthru3(SimKernelThreadCreateCode,CAST(unsigned long,parent),CAST(unsigned long,pid),CAST(unsigned long,flags))); +} + +INLINE int MamboBogusDiskRead( int devno, void *buf, ulong sect, ulong nrsect) +{ + return callthru3( SimBogusDiskReadCode, CAST(unsigned long,buf), CAST(unsigned long,sect), + CAST(unsigned long,(nrsect<<16)|devno)); +} + +INLINE int MamboBogusDiskWrite( int devno, void *buf, ulong sect, ulong nrsect) +{ + return callthru3( SimBogusDiskWriteCode, CAST(unsigned long,buf), CAST(unsigned long,sect), + CAST(unsigned long,(nrsect<<16)|devno)); +} +INLINE int MamboBogusDiskInfo( int op, int devno) +{ + return(callthru2( SimBogusDiskInfoCode, CAST(unsigned long,op), CAST(unsigned long,devno))); +} + +INLINE int MamboBogusNetProbe( int devno, void *buf) +{ + return(callthru2( SimBogusNetProbeCode, CAST(unsigned long,devno), CAST(unsigned long,buf) )); +} + +INLINE int MamboBogusNetSend( int devno, void *buf, ulong size) +{ + return(callthru3( SimBogusNetSendCode, CAST(unsigned long,devno), CAST(unsigned long,buf), CAST(unsigned long,size))); +} + +INLINE int MamboBogusNetRecv( int devno, void *buf, ulong size) +{ + return(callthru3( SimBogusNetRecvCode, CAST(unsigned long,devno), CAST(unsigned long,buf), CAST(unsigned long,size))); +} + +INLINE void BogusHalt( void ) { callthru0( SimBogusHaltCode ); } + +INLINE int MamboKernelMmapFile(char *buffer, int pathlen, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flag, unsigned long offset) +{ + return(callthru7( SimKernelMmapFileCode, CAST(unsigned long,buffer), CAST(unsigned long,pathlen), CAST(unsigned long,addr), CAST(unsigned long,len), CAST(unsigned long,prot), CAST(unsigned long,flag), CAST(unsigned long,offset))); +} + +#endif /* #ifndef _CALLTHRU_CONFIG_H_ */ + Index: linux-cg/include/stidc/sim_support_code.h =================================================================== --- /dev/null +++ linux-cg/include/stidc/sim_support_code.h @@ -0,0 +1,171 @@ +/********************************************************* + * + * (C) Copyright IBM Corporation 2001, 2003 + * + * Filename : sim_support_code.h + * + * Originator : Charles Lefurgy + * + * Purpose : This file is shared between Mambo and OSes (Linux, K42). + * + *********************************************************/ + +#ifndef _SIM_SUPPORT_CODE_H_ +#define _SIM_SUPPORT_CODE_H_ + + +typedef struct CallthruCacheConfig +{ + int dcache_size; /* bytes */ + int dcache_assoc; + int dcache_line_size; /* bytes */ + int dcache_block_size; /* bytes */ + + int icache_size; /* bytes */ + int icache_assoc; + int icache_line_size; /* bytes */ + int icache_block_size; /* bytes */ + + int l2cache_size; /* bytes */ + int l2cache_assoc; + int l2cache_line_size; /* bytes */ +} CallthruCacheConfig; + +typedef struct CallthruConfig +{ + int num_cpus; + int cpu_clock_freq; /* Mhz */ + unsigned long long mem_size; /* bytes */ + CallthruCacheConfig cache; +} CallthruConfig; + + + +/* + * Support functions that can be invoked by the simulated program + * + * Simulated reg 3 contains code indicating which function to perform: */ +typedef enum +{ + SimWriteConsoleCode = 0, /* 0 */ + SimDiskReadCode, /* 1 */ + SimDiskWriteCode, /* 2 */ + SimDeviceIntRegisterCode, /* 3 */ + SimDeviceIntDeregisterCode, /* 4 */ + SimDeviceEnableIntCode, /* 5 */ + SimDeviceDisableIntCode, /* 6 */ + SimGetIntStreamForDeviceCode, /* 7 */ + SimResetIntForStreamCode, /* 8 */ + SimCharReadCode, /* 9 */ + SimCharWriteCode, /* 10 */ + SimGetInterruptingLevelCode, /* 11 */ + SimSetExternalLevelMaskCode, /* 12 */ + SimSetInterruptCode, /* 13 */ + SimMapLevelCode, /* 14 */ + SimResetInterruptCode, /* 15 */ + SimFileOpenCode, /* 16 */ + SimFileCloseCode, /* 17 */ + SimFileReadCode, /* 18 */ + SimFileWriteCode, /* 19 */ + SimTakeCheckpointCode, /* 20 */ + SimInterruptEOICode, /* 21 */ + SimShellCode, /* 22 */ + SimBlockIOCode, /* 23 */ + SimGetCookieCode, /* 24 */ + SimDumpStatsCode, /* 25 */ + SimReturnStatsCode = 30, /* 30 */ + SimExitCode, /* 31 */ + SimDumpPPCStatsCode = 32, /* 32 */ /* used in cyclesim + ??? */ + SimClearPPCStatsCode = 33, /* 33 */ /* used in cyclesim + ??? */ + SimCopyQuickCode = 34, /* 34 */ /* shortcut a long memory copy */ + /* 35 */ /* bmark under test for power validation in cyclesim */ + SimSetTestNameCode = 35, + + SimDumpSystemStatsCode = 36, /* 36 */ + SimClearSystemStatsCode = 37, /* 37 */ + SimSystemMemTraceEnableCode = 38, /* 38 */ + SimSystemMemTraceDisableCode = 39, /* 39 */ + + SimTCLReadCode = 40, /* 40 */ + SimTCLWriteCode, /* 41 */ + SimFileLoadedByAIXCode = 50, /* 50 */ + SimUnloadedFileCode, /* 51 */ + SimDumpStateCode, /* 52 */ /* get a machine attribute */ + + SimReadConsoleCode = 60, /* 60 */ /* k42 codes starting at 60 */ + SimThinIPReadCode, /* 61 */ /* thinIP read */ + SimThinIPWriteCode, /* 62 */ /* thinIP write */ + SimFastRevMemCopyCode, /* 63 */ /* fast rev mem cpy */ + SimStartCPUCode, /* 64 */ /* start a cpu */ + SimSendIPICode, /* 65 */ /* make an IPI */ + SimGetInstrCountCode, /* 66 */ /* get instr count */ + SimGetNumbPhysProcsCode, /* 67 */ /* get numb procs */ + SimGetMachAttrCode, /* 68 */ /* get a machine attribute */ + SimPhysMemCopyCode, /* 69 */ /* a fast phys to phys mem copy */ + SimGetTimeCode, /* 70 */ /* get a time */ + SimPhysMemSetCode, /* 71 */ /* a fast memory set routine */ + SimTraceFileCtlCode, /* 72 */ /* allows open, write, close */ + + /* 80 */ /* read up to 4096 bytes from a simulator disk */ + SimDiskReadK42Code = 80, + + /* 81 */ /* write up to 4096 bytes to a simulator disk */ + SimDiskWriteK42Code, + + /* 82 */ /* open simulator disk; return disk size */ + SimDiskOpenK42Code, + + /* 83 */ /* close simulator disk; NOT YET IMPLEMENTED */ + SimDiskCloseK42Code, + + + SimGetConfigCode, /* 84 */ /* read the system configuration */ + /* 85 */ /* print out the stats with a comment and id */ + SimLogStatsCode, + + + /* 86 */ /* execute the passed string as a tcl procedure */ + SimCallTCLCode, + + SimPROMCode = 99, /* 99 */ /* Handle open firmware calls */ + +#if 1 // def STI + SimPPCOnlyCode = 100, /* 100 */ /* Turn PPC-ONLY mode on or off */ +#endif /* #ifdef STI */ +/* mco hooks to linux kernel process creation destruction routines */ + SimPIDCreateCode = 101, /* 101 */ /* fork a proc */ + SimPIDExecExitCode, /* 102 */ /* exit() */ + SimPIDExecCode, /* 103 */ /* execve() */ + SimPIDResumeCode, /* 104 */ /* */ + SimPIDKillCode, /* 105 */ /* */ + SimKernelThreadCreateCode, /* 106 */ /* kernel_thread() */ + SimKernelStartedCode, /* 107 */ /* kernel finished booting */ + SimLinuxLoadShlibCode, /* 108 */ /* linux load_elf_library() */ + SimOpenConnectionCode = 110, /* 110 */ /* open connection code */ + SimCloseConnectionCode, /* 111 */ /* close connection code */ + SimReadConnectionCode, /* 112 */ /* read connection code */ + SimWriteConnectionCode, /* 113 */ /* write connection code */ + SimSelectConnectionCode, /* 114 */ /* select connection code */ + SimPthreadCreateCode, /* 115 traps into simulator to create/start a pthread */ + + SimBogusDiskReadCode, /* 116 mambo bogus disk block read */ + SimBogusDiskWriteCode, /* 117 mambo bogus disk block write */ + SimBogusDiskInfoCode, /* 118 mambo bogus disk info op */ + SimBogusNetProbeCode, /* 119 mambo bogus net probe op */ + SimBogusNetSendCode, /* 120 mambo bogus net send op */ + SimBogusNetRecvCode, /* 121 mambo bogus net recv op */ + + SimFileLoadedByOSCode, /* 122 */ + + SimKernelThreadCallCode, /* 123 */ /* kernel_thread() */ + + SimKernelMmapFileCode, /* 124 */ /* do_mmap from linux */ + + SimDumpMemoryCode, /* 125 */ /* print memory region to file */ + SimBogusHaltCode, /* 126 */ /* bogus halt for idle */ + + + SimLastCode /* This must be last in this list */ +} SimSupportCode; + +#endif /* #ifndef _SIM_SUPPORT_CODE_H_ */ Index: linux-cg/arch/ppc64/Kconfig =================================================================== --- linux-cg.orig/arch/ppc64/Kconfig +++ linux-cg/arch/ppc64/Kconfig @@ -389,6 +389,12 @@ config CMDLINE some command-line options at build time by entering them here. In most cases you will need to specify the root device here. +config MAMBO_BD + bool "Mambo Block driver stuff" + depends on PPC_PSERIES || PPC_BPA + ---help--- + mambo block device driver + endmenu config ISA_DMA_API Index: linux-cg/arch/ppc64/kernel/head.S =================================================================== --- linux-cg.orig/arch/ppc64/kernel/head.S +++ linux-cg/arch/ppc64/kernel/head.S @@ -1586,6 +1586,10 @@ _STATIC(__after_prom_start) * Note: this routine *only* clobbers r0, r6 and lr */ _GLOBAL(copy_and_flush) +#ifdef CONFIG_PPC_BPA + __onsim(r0) + bne _sim_copy_and_flush +#endif addi r5,r5,-8 addi r6,r6,-8 4: li r0,16 /* Use the least common */ @@ -1612,6 +1616,42 @@ _GLOBAL(copy_and_flush) addi r6,r6,8 blr +#ifdef CONFIG_PPC_BPA +_sim_copy_and_flush: +/* + * Use Simulators copy cut-thru + * which is SimOSSupport(SimPhysMemCopyK, dst, src, size); + */ + mr r0,r6 + mr r6,r5 + subf r6,r0,r6 + + mr r5,r4 + add r5,r5,r0 + + mr r4,r3 + add r4,r4,r0 + + li r3,69 # SimPhysMemCopyK + .long 0x000EAEB0 # SimOS trap + + ## restore + mr r3,r4 + subf r3,r0,r3 + + mr r4,r5 + subf r4,r0,r4 + + mr r5,r6 + add r5,r5,r0 + + ## r6 needs to be r5 rounded up to nearest 8 + mr r6,r5 + addi r6,r6,7 + rldicr r6,r6,0,60 + blr +#endif + .align 8 copy_to_here: Index: linux-cg/arch/ppc64/kernel/spider-pic.c =================================================================== --- linux-cg.orig/arch/ppc64/kernel/spider-pic.c +++ linux-cg/arch/ppc64/kernel/spider-pic.c @@ -159,6 +159,10 @@ void spider_init_IRQ(void) long pics[] = { 0x24000008000, 0x34000008000 }; int n; + if (__onsim()) { + return; + } + /* FIXME: detect multiple PICs as soon as the device tree has them */ for (node = 0; node < num_present_cpus()/2; node++) { #if 0 Index: linux-cg/drivers/block/Makefile =================================================================== --- linux-cg.orig/drivers/block/Makefile +++ linux-cg/drivers/block/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o obj-$(CONFIG_BLK_DEV_UMEM) += umem.o obj-$(CONFIG_BLK_DEV_NBD) += nbd.o +obj-$(CONFIG_MAMBO_BD) += mambo_bd.o obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o obj-$(CONFIG_VIODASD) += viodasd.o Index: linux-cg/drivers/block/mambo_bd.c =================================================================== --- /dev/null +++ linux-cg/drivers/block/mambo_bd.c @@ -0,0 +1,252 @@ +/* + * Mambo Block Driver - expose block devices through mambo callthru + * + * copyright 2003 IBM + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#define MAJOR_NR 42 +#include + +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 + +static int +mbd_init_disk (int devno) +{ + /* 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++; +#ifdef DEBUG + printk ("<1>Bogus Device %d Init\n", devno); +#endif + + 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; + +#ifdef DEBUG + dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%lx)\n", + req->rq_disk->disk_name, req, req->flags); +#endif + + 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; +} + +#if 0 +static int +mbd_check_change (struct gendisk *disk) +{ + int devno = disk->first_minor; + + if (MamboBogusDiskInfo (BD_INFO_CHANGE, devno)) + return 1; + + return 0; +} +#endif + +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; + int i; + + if (!__onsim()) + return 0; + + err = -ENOMEM; + 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 + + devfs_mk_dir ("mambobd"); + 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); + sprintf (disk->devfs_name, "mambobd%d", i); + set_capacity (disk, 0x3ffffe); + 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) +{ + devfs_remove("mambobd"); + + 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"); Index: linux-cg/drivers/char/tty_io.c =================================================================== --- linux-cg.orig/drivers/char/tty_io.c +++ linux-cg/drivers/char/tty_io.c @@ -1841,7 +1841,10 @@ retry_open: if (driver) { /* Don't let /dev/console block */ filp->f_flags |= O_NONBLOCK; - noctty = 1; +#ifdef CONFIG_PPC_BPA + if (!__onsim()) + noctty = 1; +#endif goto got_driver; } up(&tty_sem); Index: linux-cg/include/linux/mambobd.h =================================================================== --- /dev/null +++ linux-cg/include/linux/mambobd.h @@ -0,0 +1,38 @@ +/* + * 2001 Copyright (C) IBM + */ + +#ifndef LINUX_MAMBOBD_H +#define LINUX_MAMBOBD_H + +#ifdef MAJOR_NR + +#include + +#ifdef _STIDC_LINUX_25 +#include +#else +#include +#endif + +#ifdef PARANOIA +extern int requests_in; +extern int requests_out; +#endif + +#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; +}; +#endif + +#endif --