| .. | .. |
|---|
| 13 | 13 | #include <linux/debugfs.h> |
|---|
| 14 | 14 | #include <asm/diag.h> |
|---|
| 15 | 15 | #include <asm/trace/diag.h> |
|---|
| 16 | +#include <asm/sections.h> |
|---|
| 16 | 17 | |
|---|
| 17 | 18 | struct diag_stat { |
|---|
| 18 | 19 | unsigned int counter[NR_DIAG_STAT]; |
|---|
| .. | .. |
|---|
| 45 | 46 | [DIAG_STAT_X2FC] = { .code = 0x2fc, .name = "Guest Performance Data" }, |
|---|
| 46 | 47 | [DIAG_STAT_X304] = { .code = 0x304, .name = "Partition-Resource Service" }, |
|---|
| 47 | 48 | [DIAG_STAT_X308] = { .code = 0x308, .name = "List-Directed IPL" }, |
|---|
| 49 | + [DIAG_STAT_X318] = { .code = 0x318, .name = "CP Name and Version Codes" }, |
|---|
| 48 | 50 | [DIAG_STAT_X500] = { .code = 0x500, .name = "Virtio Service" }, |
|---|
| 49 | 51 | }; |
|---|
| 52 | + |
|---|
| 53 | +struct diag_ops __bootdata_preserved(diag_dma_ops); |
|---|
| 54 | +struct diag210 *__bootdata_preserved(__diag210_tmp_dma); |
|---|
| 50 | 55 | |
|---|
| 51 | 56 | static int show_diag_stat(struct seq_file *m, void *v) |
|---|
| 52 | 57 | { |
|---|
| .. | .. |
|---|
| 99 | 104 | .show = show_diag_stat, |
|---|
| 100 | 105 | }; |
|---|
| 101 | 106 | |
|---|
| 102 | | -static int show_diag_stat_open(struct inode *inode, struct file *file) |
|---|
| 103 | | -{ |
|---|
| 104 | | - return seq_open(file, &show_diag_stat_sops); |
|---|
| 105 | | -} |
|---|
| 106 | | - |
|---|
| 107 | | -static const struct file_operations show_diag_stat_fops = { |
|---|
| 108 | | - .open = show_diag_stat_open, |
|---|
| 109 | | - .read = seq_read, |
|---|
| 110 | | - .llseek = seq_lseek, |
|---|
| 111 | | - .release = seq_release, |
|---|
| 112 | | -}; |
|---|
| 113 | | - |
|---|
| 107 | +DEFINE_SEQ_ATTRIBUTE(show_diag_stat); |
|---|
| 114 | 108 | |
|---|
| 115 | 109 | static int __init show_diag_stat_init(void) |
|---|
| 116 | 110 | { |
|---|
| .. | .. |
|---|
| 138 | 132 | /* |
|---|
| 139 | 133 | * Diagnose 14: Input spool file manipulation |
|---|
| 140 | 134 | */ |
|---|
| 141 | | -static inline int __diag14(unsigned long rx, unsigned long ry1, |
|---|
| 142 | | - unsigned long subcode) |
|---|
| 143 | | -{ |
|---|
| 144 | | - register unsigned long _ry1 asm("2") = ry1; |
|---|
| 145 | | - register unsigned long _ry2 asm("3") = subcode; |
|---|
| 146 | | - int rc = 0; |
|---|
| 147 | | - |
|---|
| 148 | | - asm volatile( |
|---|
| 149 | | - " sam31\n" |
|---|
| 150 | | - " diag %2,2,0x14\n" |
|---|
| 151 | | - " sam64\n" |
|---|
| 152 | | - " ipm %0\n" |
|---|
| 153 | | - " srl %0,28\n" |
|---|
| 154 | | - : "=d" (rc), "+d" (_ry2) |
|---|
| 155 | | - : "d" (rx), "d" (_ry1) |
|---|
| 156 | | - : "cc"); |
|---|
| 157 | | - |
|---|
| 158 | | - return rc; |
|---|
| 159 | | -} |
|---|
| 160 | | - |
|---|
| 161 | 135 | int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode) |
|---|
| 162 | 136 | { |
|---|
| 163 | 137 | diag_stat_inc(DIAG_STAT_X014); |
|---|
| 164 | | - return __diag14(rx, ry1, subcode); |
|---|
| 138 | + return diag_dma_ops.diag14(rx, ry1, subcode); |
|---|
| 165 | 139 | } |
|---|
| 166 | 140 | EXPORT_SYMBOL(diag14); |
|---|
| 167 | 141 | |
|---|
| .. | .. |
|---|
| 194 | 168 | */ |
|---|
| 195 | 169 | int diag210(struct diag210 *addr) |
|---|
| 196 | 170 | { |
|---|
| 197 | | - /* |
|---|
| 198 | | - * diag 210 needs its data below the 2GB border, so we |
|---|
| 199 | | - * use a static data area to be sure |
|---|
| 200 | | - */ |
|---|
| 201 | | - static struct diag210 diag210_tmp; |
|---|
| 202 | 171 | static DEFINE_SPINLOCK(diag210_lock); |
|---|
| 203 | 172 | unsigned long flags; |
|---|
| 204 | 173 | int ccode; |
|---|
| 205 | 174 | |
|---|
| 206 | 175 | spin_lock_irqsave(&diag210_lock, flags); |
|---|
| 207 | | - diag210_tmp = *addr; |
|---|
| 176 | + *__diag210_tmp_dma = *addr; |
|---|
| 208 | 177 | |
|---|
| 209 | 178 | diag_stat_inc(DIAG_STAT_X210); |
|---|
| 210 | | - asm volatile( |
|---|
| 211 | | - " lhi %0,-1\n" |
|---|
| 212 | | - " sam31\n" |
|---|
| 213 | | - " diag %1,0,0x210\n" |
|---|
| 214 | | - "0: ipm %0\n" |
|---|
| 215 | | - " srl %0,28\n" |
|---|
| 216 | | - "1: sam64\n" |
|---|
| 217 | | - EX_TABLE(0b, 1b) |
|---|
| 218 | | - : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); |
|---|
| 179 | + ccode = diag_dma_ops.diag210(__diag210_tmp_dma); |
|---|
| 219 | 180 | |
|---|
| 220 | | - *addr = diag210_tmp; |
|---|
| 181 | + *addr = *__diag210_tmp_dma; |
|---|
| 221 | 182 | spin_unlock_irqrestore(&diag210_lock, flags); |
|---|
| 222 | 183 | |
|---|
| 223 | 184 | return ccode; |
|---|
| .. | .. |
|---|
| 242 | 203 | /* |
|---|
| 243 | 204 | * Diagnose 26C: Access Certain System Information |
|---|
| 244 | 205 | */ |
|---|
| 245 | | -static inline int __diag26c(void *req, void *resp, enum diag26c_sc subcode) |
|---|
| 246 | | -{ |
|---|
| 247 | | - register unsigned long _req asm("2") = (addr_t) req; |
|---|
| 248 | | - register unsigned long _resp asm("3") = (addr_t) resp; |
|---|
| 249 | | - register unsigned long _subcode asm("4") = subcode; |
|---|
| 250 | | - register unsigned long _rc asm("5") = -EOPNOTSUPP; |
|---|
| 251 | | - |
|---|
| 252 | | - asm volatile( |
|---|
| 253 | | - " sam31\n" |
|---|
| 254 | | - " diag %[rx],%[ry],0x26c\n" |
|---|
| 255 | | - "0: sam64\n" |
|---|
| 256 | | - EX_TABLE(0b,0b) |
|---|
| 257 | | - : "+d" (_rc) |
|---|
| 258 | | - : [rx] "d" (_req), "d" (_resp), [ry] "d" (_subcode) |
|---|
| 259 | | - : "cc", "memory"); |
|---|
| 260 | | - return _rc; |
|---|
| 261 | | -} |
|---|
| 262 | | - |
|---|
| 263 | 206 | int diag26c(void *req, void *resp, enum diag26c_sc subcode) |
|---|
| 264 | 207 | { |
|---|
| 265 | 208 | diag_stat_inc(DIAG_STAT_X26C); |
|---|
| 266 | | - return __diag26c(req, resp, subcode); |
|---|
| 209 | + return diag_dma_ops.diag26c(req, resp, subcode); |
|---|
| 267 | 210 | } |
|---|
| 268 | 211 | EXPORT_SYMBOL(diag26c); |
|---|