0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/debugfs.h>
0009 #include <linux/kernel.h>
0010 #include <linux/mm.h>
0011 #include <linux/proc_fs.h>
0012 #include <linux/seq_file.h>
0013 #include <linux/init.h>
0014 #include <linux/delay.h>
0015 #include <linux/export.h>
0016 #include <linux/slab.h>
0017 #include <asm/asm-extable.h>
0018 #include <asm/ebcdic.h>
0019 #include <asm/debug.h>
0020 #include <asm/sysinfo.h>
0021 #include <asm/cpcmd.h>
0022 #include <asm/topology.h>
0023 #include <asm/fpu/api.h>
0024
0025 int topology_max_mnest;
0026
0027 static inline int __stsi(void *sysinfo, int fc, int sel1, int sel2, int *lvl)
0028 {
0029 int r0 = (fc << 28) | sel1;
0030 int rc = 0;
0031
0032 asm volatile(
0033 " lr 0,%[r0]\n"
0034 " lr 1,%[r1]\n"
0035 " stsi 0(%[sysinfo])\n"
0036 "0: jz 2f\n"
0037 "1: lhi %[rc],%[retval]\n"
0038 "2: lr %[r0],0\n"
0039 EX_TABLE(0b, 1b)
0040 : [r0] "+d" (r0), [rc] "+d" (rc)
0041 : [r1] "d" (sel2),
0042 [sysinfo] "a" (sysinfo),
0043 [retval] "K" (-EOPNOTSUPP)
0044 : "cc", "0", "1", "memory");
0045 *lvl = ((unsigned int) r0) >> 28;
0046 return rc;
0047 }
0048
0049
0050
0051
0052
0053
0054
0055 int stsi(void *sysinfo, int fc, int sel1, int sel2)
0056 {
0057 int lvl, rc;
0058
0059 rc = __stsi(sysinfo, fc, sel1, sel2, &lvl);
0060 if (rc)
0061 return rc;
0062 return fc ? 0 : lvl;
0063 }
0064 EXPORT_SYMBOL(stsi);
0065
0066 #ifdef CONFIG_PROC_FS
0067
0068 static bool convert_ext_name(unsigned char encoding, char *name, size_t len)
0069 {
0070 switch (encoding) {
0071 case 1:
0072 EBCASC(name, len);
0073 break;
0074 case 2:
0075 break;
0076 default:
0077 return false;
0078 }
0079 return true;
0080 }
0081
0082 static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info)
0083 {
0084 int i;
0085
0086 if (stsi(info, 1, 1, 1))
0087 return;
0088 EBCASC(info->manufacturer, sizeof(info->manufacturer));
0089 EBCASC(info->type, sizeof(info->type));
0090 EBCASC(info->model, sizeof(info->model));
0091 EBCASC(info->sequence, sizeof(info->sequence));
0092 EBCASC(info->plant, sizeof(info->plant));
0093 EBCASC(info->model_capacity, sizeof(info->model_capacity));
0094 EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap));
0095 EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap));
0096 seq_printf(m, "Manufacturer: %-16.16s\n", info->manufacturer);
0097 seq_printf(m, "Type: %-4.4s\n", info->type);
0098 if (info->lic)
0099 seq_printf(m, "LIC Identifier: %016lx\n", info->lic);
0100
0101
0102
0103
0104
0105
0106
0107 seq_printf(m, "Model: %-16.16s", info->model_capacity);
0108 if (info->model[0] != '\0')
0109 seq_printf(m, " %-16.16s", info->model);
0110 seq_putc(m, '\n');
0111 seq_printf(m, "Sequence Code: %-16.16s\n", info->sequence);
0112 seq_printf(m, "Plant: %-4.4s\n", info->plant);
0113 seq_printf(m, "Model Capacity: %-16.16s %08u\n",
0114 info->model_capacity, info->model_cap_rating);
0115 if (info->model_perm_cap_rating)
0116 seq_printf(m, "Model Perm. Capacity: %-16.16s %08u\n",
0117 info->model_perm_cap,
0118 info->model_perm_cap_rating);
0119 if (info->model_temp_cap_rating)
0120 seq_printf(m, "Model Temp. Capacity: %-16.16s %08u\n",
0121 info->model_temp_cap,
0122 info->model_temp_cap_rating);
0123 if (info->ncr)
0124 seq_printf(m, "Nominal Cap. Rating: %08u\n", info->ncr);
0125 if (info->npr)
0126 seq_printf(m, "Nominal Perm. Rating: %08u\n", info->npr);
0127 if (info->ntr)
0128 seq_printf(m, "Nominal Temp. Rating: %08u\n", info->ntr);
0129 if (info->cai) {
0130 seq_printf(m, "Capacity Adj. Ind.: %d\n", info->cai);
0131 seq_printf(m, "Capacity Ch. Reason: %d\n", info->ccr);
0132 seq_printf(m, "Capacity Transient: %d\n", info->t);
0133 }
0134 if (info->p) {
0135 for (i = 1; i <= ARRAY_SIZE(info->typepct); i++) {
0136 seq_printf(m, "Type %d Percentage: %d\n",
0137 i, info->typepct[i - 1]);
0138 }
0139 }
0140 }
0141
0142 static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info)
0143 {
0144 int i;
0145
0146 seq_putc(m, '\n');
0147 if (!MACHINE_HAS_TOPOLOGY)
0148 return;
0149 if (stsi(info, 15, 1, topology_max_mnest))
0150 return;
0151 seq_printf(m, "CPU Topology HW: ");
0152 for (i = 0; i < TOPOLOGY_NR_MAG; i++)
0153 seq_printf(m, " %d", info->mag[i]);
0154 seq_putc(m, '\n');
0155 #ifdef CONFIG_SCHED_TOPOLOGY
0156 store_topology(info);
0157 seq_printf(m, "CPU Topology SW: ");
0158 for (i = 0; i < TOPOLOGY_NR_MAG; i++)
0159 seq_printf(m, " %d", info->mag[i]);
0160 seq_putc(m, '\n');
0161 #endif
0162 }
0163
0164 static void stsi_1_2_2(struct seq_file *m, struct sysinfo_1_2_2 *info)
0165 {
0166 struct sysinfo_1_2_2_extension *ext;
0167 int i;
0168
0169 if (stsi(info, 1, 2, 2))
0170 return;
0171 ext = (struct sysinfo_1_2_2_extension *)
0172 ((unsigned long) info + info->acc_offset);
0173 seq_printf(m, "CPUs Total: %d\n", info->cpus_total);
0174 seq_printf(m, "CPUs Configured: %d\n", info->cpus_configured);
0175 seq_printf(m, "CPUs Standby: %d\n", info->cpus_standby);
0176 seq_printf(m, "CPUs Reserved: %d\n", info->cpus_reserved);
0177 if (info->mt_installed) {
0178 seq_printf(m, "CPUs G-MTID: %d\n", info->mt_gtid);
0179 seq_printf(m, "CPUs S-MTID: %d\n", info->mt_stid);
0180 }
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 seq_printf(m, "Capability: %u", info->capability);
0191 if (info->format == 1)
0192 seq_printf(m, " %u", ext->alt_capability);
0193 seq_putc(m, '\n');
0194 if (info->nominal_cap)
0195 seq_printf(m, "Nominal Capability: %d\n", info->nominal_cap);
0196 if (info->secondary_cap)
0197 seq_printf(m, "Secondary Capability: %d\n", info->secondary_cap);
0198 for (i = 2; i <= info->cpus_total; i++) {
0199 seq_printf(m, "Adjustment %02d-way: %u",
0200 i, info->adjustment[i-2]);
0201 if (info->format == 1)
0202 seq_printf(m, " %u", ext->alt_adjustment[i-2]);
0203 seq_putc(m, '\n');
0204 }
0205 }
0206
0207 static void stsi_2_2_2(struct seq_file *m, struct sysinfo_2_2_2 *info)
0208 {
0209 if (stsi(info, 2, 2, 2))
0210 return;
0211 EBCASC(info->name, sizeof(info->name));
0212 seq_putc(m, '\n');
0213 seq_printf(m, "LPAR Number: %d\n", info->lpar_number);
0214 seq_printf(m, "LPAR Characteristics: ");
0215 if (info->characteristics & LPAR_CHAR_DEDICATED)
0216 seq_printf(m, "Dedicated ");
0217 if (info->characteristics & LPAR_CHAR_SHARED)
0218 seq_printf(m, "Shared ");
0219 if (info->characteristics & LPAR_CHAR_LIMITED)
0220 seq_printf(m, "Limited ");
0221 seq_putc(m, '\n');
0222 seq_printf(m, "LPAR Name: %-8.8s\n", info->name);
0223 seq_printf(m, "LPAR Adjustment: %d\n", info->caf);
0224 seq_printf(m, "LPAR CPUs Total: %d\n", info->cpus_total);
0225 seq_printf(m, "LPAR CPUs Configured: %d\n", info->cpus_configured);
0226 seq_printf(m, "LPAR CPUs Standby: %d\n", info->cpus_standby);
0227 seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved);
0228 seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated);
0229 seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared);
0230 if (info->mt_installed) {
0231 seq_printf(m, "LPAR CPUs G-MTID: %d\n", info->mt_gtid);
0232 seq_printf(m, "LPAR CPUs S-MTID: %d\n", info->mt_stid);
0233 seq_printf(m, "LPAR CPUs PS-MTID: %d\n", info->mt_psmtid);
0234 }
0235 if (convert_ext_name(info->vsne, info->ext_name, sizeof(info->ext_name))) {
0236 seq_printf(m, "LPAR Extended Name: %-.256s\n", info->ext_name);
0237 seq_printf(m, "LPAR UUID: %pUb\n", &info->uuid);
0238 }
0239 }
0240
0241 static void print_ext_name(struct seq_file *m, int lvl,
0242 struct sysinfo_3_2_2 *info)
0243 {
0244 size_t len = sizeof(info->ext_names[lvl]);
0245
0246 if (!convert_ext_name(info->vm[lvl].evmne, info->ext_names[lvl], len))
0247 return;
0248 seq_printf(m, "VM%02d Extended Name: %-.256s\n", lvl,
0249 info->ext_names[lvl]);
0250 }
0251
0252 static void print_uuid(struct seq_file *m, int i, struct sysinfo_3_2_2 *info)
0253 {
0254 if (uuid_is_null(&info->vm[i].uuid))
0255 return;
0256 seq_printf(m, "VM%02d UUID: %pUb\n", i, &info->vm[i].uuid);
0257 }
0258
0259 static void stsi_3_2_2(struct seq_file *m, struct sysinfo_3_2_2 *info)
0260 {
0261 int i;
0262
0263 if (stsi(info, 3, 2, 2))
0264 return;
0265 for (i = 0; i < info->count; i++) {
0266 EBCASC(info->vm[i].name, sizeof(info->vm[i].name));
0267 EBCASC(info->vm[i].cpi, sizeof(info->vm[i].cpi));
0268 seq_putc(m, '\n');
0269 seq_printf(m, "VM%02d Name: %-8.8s\n", i, info->vm[i].name);
0270 seq_printf(m, "VM%02d Control Program: %-16.16s\n", i, info->vm[i].cpi);
0271 seq_printf(m, "VM%02d Adjustment: %d\n", i, info->vm[i].caf);
0272 seq_printf(m, "VM%02d CPUs Total: %d\n", i, info->vm[i].cpus_total);
0273 seq_printf(m, "VM%02d CPUs Configured: %d\n", i, info->vm[i].cpus_configured);
0274 seq_printf(m, "VM%02d CPUs Standby: %d\n", i, info->vm[i].cpus_standby);
0275 seq_printf(m, "VM%02d CPUs Reserved: %d\n", i, info->vm[i].cpus_reserved);
0276 print_ext_name(m, i, info);
0277 print_uuid(m, i, info);
0278 }
0279 }
0280
0281 static int sysinfo_show(struct seq_file *m, void *v)
0282 {
0283 void *info = (void *)get_zeroed_page(GFP_KERNEL);
0284 int level;
0285
0286 if (!info)
0287 return 0;
0288 level = stsi(NULL, 0, 0, 0);
0289 if (level >= 1)
0290 stsi_1_1_1(m, info);
0291 if (level >= 1)
0292 stsi_15_1_x(m, info);
0293 if (level >= 1)
0294 stsi_1_2_2(m, info);
0295 if (level >= 2)
0296 stsi_2_2_2(m, info);
0297 if (level >= 3)
0298 stsi_3_2_2(m, info);
0299 free_page((unsigned long)info);
0300 return 0;
0301 }
0302
0303 static int __init sysinfo_create_proc(void)
0304 {
0305 proc_create_single("sysinfo", 0444, NULL, sysinfo_show);
0306 return 0;
0307 }
0308 device_initcall(sysinfo_create_proc);
0309
0310 #endif
0311
0312
0313
0314
0315
0316 static DECLARE_RWSEM(service_level_sem);
0317 static LIST_HEAD(service_level_list);
0318
0319 int register_service_level(struct service_level *slr)
0320 {
0321 struct service_level *ptr;
0322
0323 down_write(&service_level_sem);
0324 list_for_each_entry(ptr, &service_level_list, list)
0325 if (ptr == slr) {
0326 up_write(&service_level_sem);
0327 return -EEXIST;
0328 }
0329 list_add_tail(&slr->list, &service_level_list);
0330 up_write(&service_level_sem);
0331 return 0;
0332 }
0333 EXPORT_SYMBOL(register_service_level);
0334
0335 int unregister_service_level(struct service_level *slr)
0336 {
0337 struct service_level *ptr, *next;
0338 int rc = -ENOENT;
0339
0340 down_write(&service_level_sem);
0341 list_for_each_entry_safe(ptr, next, &service_level_list, list) {
0342 if (ptr != slr)
0343 continue;
0344 list_del(&ptr->list);
0345 rc = 0;
0346 break;
0347 }
0348 up_write(&service_level_sem);
0349 return rc;
0350 }
0351 EXPORT_SYMBOL(unregister_service_level);
0352
0353 static void *service_level_start(struct seq_file *m, loff_t *pos)
0354 {
0355 down_read(&service_level_sem);
0356 return seq_list_start(&service_level_list, *pos);
0357 }
0358
0359 static void *service_level_next(struct seq_file *m, void *p, loff_t *pos)
0360 {
0361 return seq_list_next(p, &service_level_list, pos);
0362 }
0363
0364 static void service_level_stop(struct seq_file *m, void *p)
0365 {
0366 up_read(&service_level_sem);
0367 }
0368
0369 static int service_level_show(struct seq_file *m, void *p)
0370 {
0371 struct service_level *slr;
0372
0373 slr = list_entry(p, struct service_level, list);
0374 slr->seq_print(m, slr);
0375 return 0;
0376 }
0377
0378 static const struct seq_operations service_level_seq_ops = {
0379 .start = service_level_start,
0380 .next = service_level_next,
0381 .stop = service_level_stop,
0382 .show = service_level_show
0383 };
0384
0385 static void service_level_vm_print(struct seq_file *m,
0386 struct service_level *slr)
0387 {
0388 char *query_buffer, *str;
0389
0390 query_buffer = kmalloc(1024, GFP_KERNEL | GFP_DMA);
0391 if (!query_buffer)
0392 return;
0393 cpcmd("QUERY CPLEVEL", query_buffer, 1024, NULL);
0394 str = strchr(query_buffer, '\n');
0395 if (str)
0396 *str = 0;
0397 seq_printf(m, "VM: %s\n", query_buffer);
0398 kfree(query_buffer);
0399 }
0400
0401 static struct service_level service_level_vm = {
0402 .seq_print = service_level_vm_print
0403 };
0404
0405 static __init int create_proc_service_level(void)
0406 {
0407 proc_create_seq("service_levels", 0, NULL, &service_level_seq_ops);
0408 if (MACHINE_IS_VM)
0409 register_service_level(&service_level_vm);
0410 return 0;
0411 }
0412 subsys_initcall(create_proc_service_level);
0413
0414
0415
0416
0417 void s390_adjust_jiffies(void)
0418 {
0419 struct sysinfo_1_2_2 *info;
0420 unsigned long capability;
0421 struct kernel_fpu fpu;
0422
0423 info = (void *) get_zeroed_page(GFP_KERNEL);
0424 if (!info)
0425 return;
0426
0427 if (stsi(info, 1, 2, 2) == 0) {
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439 kernel_fpu_begin(&fpu, KERNEL_FPR);
0440 asm volatile(
0441 " sfpc %3\n"
0442 " l %0,%1\n"
0443 " tmlh %0,0xff80\n"
0444 " jnz 0f\n"
0445 " cefbr %%f2,%0\n"
0446 " j 1f\n"
0447 "0: le %%f2,%1\n"
0448 "1: cefbr %%f0,%2\n"
0449 " debr %%f0,%%f2\n"
0450 " cgebr %0,5,%%f0\n"
0451 : "=&d" (capability)
0452 : "Q" (info->capability), "d" (10000000), "d" (0)
0453 : "cc"
0454 );
0455 kernel_fpu_end(&fpu, KERNEL_FPR);
0456 } else
0457
0458
0459
0460
0461 capability = 42;
0462 loops_per_jiffy = capability * (500000/HZ);
0463 free_page((unsigned long) info);
0464 }
0465
0466
0467
0468
0469 void calibrate_delay(void)
0470 {
0471 s390_adjust_jiffies();
0472
0473 printk(KERN_DEBUG "Calibrating delay loop (skipped)... "
0474 "%lu.%02lu BogoMIPS preset\n", loops_per_jiffy/(500000/HZ),
0475 (loops_per_jiffy/(5000/HZ)) % 100);
0476 }
0477
0478 #ifdef CONFIG_DEBUG_FS
0479
0480 #define STSI_FILE(fc, s1, s2) \
0481 static int stsi_open_##fc##_##s1##_##s2(struct inode *inode, struct file *file)\
0482 { \
0483 file->private_data = (void *) get_zeroed_page(GFP_KERNEL); \
0484 if (!file->private_data) \
0485 return -ENOMEM; \
0486 if (stsi(file->private_data, fc, s1, s2)) { \
0487 free_page((unsigned long)file->private_data); \
0488 file->private_data = NULL; \
0489 return -EACCES; \
0490 } \
0491 return nonseekable_open(inode, file); \
0492 } \
0493 \
0494 static const struct file_operations stsi_##fc##_##s1##_##s2##_fs_ops = { \
0495 .open = stsi_open_##fc##_##s1##_##s2, \
0496 .release = stsi_release, \
0497 .read = stsi_read, \
0498 .llseek = no_llseek, \
0499 };
0500
0501 static int stsi_release(struct inode *inode, struct file *file)
0502 {
0503 free_page((unsigned long)file->private_data);
0504 return 0;
0505 }
0506
0507 static ssize_t stsi_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
0508 {
0509 return simple_read_from_buffer(buf, size, ppos, file->private_data, PAGE_SIZE);
0510 }
0511
0512 STSI_FILE( 1, 1, 1);
0513 STSI_FILE( 1, 2, 1);
0514 STSI_FILE( 1, 2, 2);
0515 STSI_FILE( 2, 2, 1);
0516 STSI_FILE( 2, 2, 2);
0517 STSI_FILE( 3, 2, 2);
0518 STSI_FILE(15, 1, 2);
0519 STSI_FILE(15, 1, 3);
0520 STSI_FILE(15, 1, 4);
0521 STSI_FILE(15, 1, 5);
0522 STSI_FILE(15, 1, 6);
0523
0524 struct stsi_file {
0525 const struct file_operations *fops;
0526 char *name;
0527 };
0528
0529 static struct stsi_file stsi_file[] __initdata = {
0530 {.fops = &stsi_1_1_1_fs_ops, .name = "1_1_1"},
0531 {.fops = &stsi_1_2_1_fs_ops, .name = "1_2_1"},
0532 {.fops = &stsi_1_2_2_fs_ops, .name = "1_2_2"},
0533 {.fops = &stsi_2_2_1_fs_ops, .name = "2_2_1"},
0534 {.fops = &stsi_2_2_2_fs_ops, .name = "2_2_2"},
0535 {.fops = &stsi_3_2_2_fs_ops, .name = "3_2_2"},
0536 {.fops = &stsi_15_1_2_fs_ops, .name = "15_1_2"},
0537 {.fops = &stsi_15_1_3_fs_ops, .name = "15_1_3"},
0538 {.fops = &stsi_15_1_4_fs_ops, .name = "15_1_4"},
0539 {.fops = &stsi_15_1_5_fs_ops, .name = "15_1_5"},
0540 {.fops = &stsi_15_1_6_fs_ops, .name = "15_1_6"},
0541 };
0542
0543 static u8 stsi_0_0_0;
0544
0545 static __init int stsi_init_debugfs(void)
0546 {
0547 struct dentry *stsi_root;
0548 struct stsi_file *sf;
0549 int lvl, i;
0550
0551 stsi_root = debugfs_create_dir("stsi", arch_debugfs_dir);
0552 lvl = stsi(NULL, 0, 0, 0);
0553 if (lvl > 0)
0554 stsi_0_0_0 = lvl;
0555 debugfs_create_u8("0_0_0", 0400, stsi_root, &stsi_0_0_0);
0556 for (i = 0; i < ARRAY_SIZE(stsi_file); i++) {
0557 sf = &stsi_file[i];
0558 debugfs_create_file(sf->name, 0400, stsi_root, NULL, sf->fops);
0559 }
0560 if (IS_ENABLED(CONFIG_SCHED_TOPOLOGY) && MACHINE_HAS_TOPOLOGY) {
0561 char link_to[10];
0562
0563 sprintf(link_to, "15_1_%d", topology_mnest_limit());
0564 debugfs_create_symlink("topology", stsi_root, link_to);
0565 }
0566 return 0;
0567 }
0568 device_initcall(stsi_init_debugfs);
0569
0570 #endif