⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extmem.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File...........: arch/s390/mm/dcss.c * Author(s)......: Steven Shultz <shultzss@us.ibm.com> *                  Carsten Otte <cotte@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com> * thanks to Rob M van der Heij * - he wrote the diag64 function * (C) IBM Corporation 2002 */#include <linux/kernel.h>#include <linux/string.h>#include <linux/spinlock.h>#include <linux/list.h>#include <linux/slab.h>#include <linux/module.h>#include <linux/bootmem.h>#include <asm/page.h>#include <asm/ebcdic.h>#include <asm/errno.h>#include <asm/extmem.h>#include <asm/cpcmd.h>#include <linux/ctype.h>#define DCSS_DEBUG	/* Debug messages on/off */#define DCSS_NAME "extmem"#ifdef DCSS_DEBUG#define PRINT_DEBUG(x...)	printk(KERN_DEBUG DCSS_NAME " debug:" x)#else#define PRINT_DEBUG(x...)   do {} while (0)#endif#define PRINT_INFO(x...)	printk(KERN_INFO DCSS_NAME " info:" x)#define PRINT_WARN(x...)	printk(KERN_WARNING DCSS_NAME " warning:" x)#define PRINT_ERR(x...)		printk(KERN_ERR DCSS_NAME " error:" x)#define DCSS_LOADSHR    0x00#define DCSS_LOADNSR    0x04#define DCSS_PURGESEG   0x08#define DCSS_FINDSEG    0x0c#define DCSS_LOADNOLY   0x10#define DCSS_SEGEXT     0x18#define DCSS_QACTV      0x0cstruct dcss_segment {        struct list_head list;        char dcss_name[8];        unsigned long start_addr;        unsigned long end;        atomic_t ref_count;        int dcss_attr;	int shared_attr;};static spinlock_t dcss_lock = SPIN_LOCK_UNLOCKED;static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list);extern struct {	unsigned long addr, size, type;} memory_chunk[MEMORY_CHUNKS];/* * Create the 8 bytes, ebcdic VM segment name from * an ascii name. */static void inline dcss_mkname(char *name, char *dcss_name){        int i;        for (i = 0; i <= 8; i++) {                if (name[i] == '\0')                        break;                dcss_name[i] = toupper(name[i]);        };        for (; i <= 8; i++)                dcss_name[i] = ' ';        ASCEBC(dcss_name, 8);}/* * Perform a function on a dcss segment. */static inline intdcss_diag (__u8 func, void *parameter,           unsigned long *ret1, unsigned long *ret2){        unsigned long rx, ry;        int rc;        rx = (unsigned long) parameter;        ry = (unsigned long) func;        __asm__ __volatile__(#ifdef CONFIG_ARCH_S390X                             "   sam31\n" // switch to 31 bit                             "   diag    %0,%1,0x64\n"                             "   sam64\n" // switch back to 64 bit#else                             "   diag    %0,%1,0x64\n"#endif                             "   ipm     %2\n"                             "   srl     %2,28\n"                             : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc" );        *ret1 = rx;        *ret2 = ry;        return rc;}/* use to issue "extended" dcss query */static inline intdcss_diag_query(char *name, int *rwattr, int *shattr, unsigned long *segstart, unsigned long *segend){        int i,j,rc;        unsigned long  rx, ry;        typedef struct segentry {                char thisseg[8];        } segentry;        struct qout64 {                int segstart;                int segend;                int segcnt;                int segrcnt;                segentry segout[6];        };        struct qin64 {                char qopcode;                char rsrv1[3];                char qrcode;                char rsrv2[3];                char qname[8];                unsigned int qoutptr;                short int qoutlen;        };        struct qin64  *qinarea;        struct qout64 *qoutarea;        qinarea = (struct qin64*) get_zeroed_page (GFP_DMA);        if (!qinarea) {                rc =-ENOMEM;                goto out;        }        qoutarea = (struct qout64*) get_zeroed_page (GFP_DMA);        if (!qoutarea) {                rc = -ENOMEM;                free_page ((unsigned long) qinarea);                goto out;        }        memset (qinarea,0,PAGE_SIZE);        memset (qoutarea,0,PAGE_SIZE);        qinarea->qopcode = DCSS_QACTV; /* do a query for active                                          segments */        qinarea->qoutptr = (unsigned long) qoutarea;        qinarea->qoutlen = sizeof(struct qout64);        /* Move segment name into double word aligned           field and pad with blanks to 8 long.         */        for (i = j = 0 ; i < 8; i++) {                qinarea->qname[i] = (name[j] == '\0') ? ' ' : name[j++];        }        /* name already in EBCDIC */        /* ASCEBC ((void *)&qinarea.qname, 8); */        /* set the assembler variables */        rx = (unsigned long) qinarea;        ry = DCSS_SEGEXT; /* this is extended function */        /* issue diagnose x'64' */        __asm__ __volatile__(#ifdef CONFIG_ARCH_S390X                             "   sam31\n" // switch to 31 bit                             "   diag    %0,%1,0x64\n"                             "   sam64\n" // switch back to 64 bit#else                             "   diag    %0,%1,0x64\n"#endif                             "   ipm     %2\n"                             "   srl     %2,28\n"                             : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc" );        /* parse the query output area */	*segstart=qoutarea->segstart;	*segend=qoutarea->segend;        if (rc > 1)                {                        *rwattr = 2;                        *shattr = 2;                        rc = 0;                        goto free;                }        if (qoutarea->segcnt > 6)                {                        *rwattr = 3;                        *shattr = 3;                        rc = 0;                        goto free;                }        *rwattr = 1;        *shattr = 1;        for (i=0; i < qoutarea->segrcnt; i++) {                if (qoutarea->segout[i].thisseg[3] == 2 ||                    qoutarea->segout[i].thisseg[3] == 3 ||                    qoutarea->segout[i].thisseg[3] == 6 )                        *rwattr = 0;                if (qoutarea->segout[i].thisseg[3] == 1 ||                    qoutarea->segout[i].thisseg[3] == 3 ||                    qoutarea->segout[i].thisseg[3] == 5 )                        *shattr = 0;        } /* end of for statement */        rc = 0; free:        free_page ((unsigned long) qoutarea);        free_page ((unsigned long) qinarea); out:        return rc;}/* * Load a DCSS segment via the diag 0x64. */int segment_load(char *name, int segtype, unsigned long *addr,                 unsigned long *end){        char dcss_name[8];        struct list_head *l;        struct dcss_segment *seg, *tmp;	unsigned long dummy;	unsigned long segstart, segend;        int rc = 0,i;        int rwattr, shattr;        if (!MACHINE_IS_VM)                return -ENOSYS;        dcss_mkname(name, dcss_name);	/* search for the dcss in list of currently loaded segments */        spin_lock(&dcss_lock);        seg = NULL;        list_for_each(l, &dcss_list) {                tmp = list_entry(l, struct dcss_segment, list);                if (memcmp(tmp->dcss_name, dcss_name, 8) == 0) {                        seg = tmp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -