Root/arch/s390/kernel/diag.c

1/*
2 * Implementation of s390 diagnose codes
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Michael Holzheu <holzheu@de.ibm.com>
6 */
7
8#include <linux/module.h>
9#include <asm/diag.h>
10
11/*
12 * Diagnose 10: Release pages
13 */
14void diag10(unsigned long addr)
15{
16    if (addr >= 0x7ff00000)
17        return;
18    asm volatile(
19#ifdef CONFIG_64BIT
20        " sam31\n"
21        " diag %0,%0,0x10\n"
22        "0: sam64\n"
23#else
24        " diag %0,%0,0x10\n"
25        "0:\n"
26#endif
27        EX_TABLE(0b, 0b)
28        : : "a" (addr));
29}
30EXPORT_SYMBOL(diag10);
31
32/*
33 * Diagnose 14: Input spool file manipulation
34 */
35int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
36{
37    register unsigned long _ry1 asm("2") = ry1;
38    register unsigned long _ry2 asm("3") = subcode;
39    int rc = 0;
40
41    asm volatile(
42#ifdef CONFIG_64BIT
43        " sam31\n"
44        " diag %2,2,0x14\n"
45        " sam64\n"
46#else
47        " diag %2,2,0x14\n"
48#endif
49        " ipm %0\n"
50        " srl %0,28\n"
51        : "=d" (rc), "+d" (_ry2)
52        : "d" (rx), "d" (_ry1)
53        : "cc");
54
55    return rc;
56}
57EXPORT_SYMBOL(diag14);
58
59/*
60 * Diagnose 210: Get information about a virtual device
61 */
62int diag210(struct diag210 *addr)
63{
64    /*
65     * diag 210 needs its data below the 2GB border, so we
66     * use a static data area to be sure
67     */
68    static struct diag210 diag210_tmp;
69    static DEFINE_SPINLOCK(diag210_lock);
70    unsigned long flags;
71    int ccode;
72
73    spin_lock_irqsave(&diag210_lock, flags);
74    diag210_tmp = *addr;
75
76#ifdef CONFIG_64BIT
77    asm volatile(
78        " lhi %0,-1\n"
79        " sam31\n"
80        " diag %1,0,0x210\n"
81        "0: ipm %0\n"
82        " srl %0,28\n"
83        "1: sam64\n"
84        EX_TABLE(0b, 1b)
85        : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
86#else
87    asm volatile(
88        " lhi %0,-1\n"
89        " diag %1,0,0x210\n"
90        "0: ipm %0\n"
91        " srl %0,28\n"
92        "1:\n"
93        EX_TABLE(0b, 1b)
94        : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
95#endif
96
97    *addr = diag210_tmp;
98    spin_unlock_irqrestore(&diag210_lock, flags);
99
100    return ccode;
101}
102EXPORT_SYMBOL(diag210);
103

Archive Download this file



interactive