18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2018, Christophe Leroy CS S.I. 48c2ecf20Sopenharmony_ci * <christophe.leroy@c-s.fr> 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * This dumps the content of Segment Registers 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <asm/debugfs.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistatic void seg_show(struct seq_file *m, int i) 128c2ecf20Sopenharmony_ci{ 138c2ecf20Sopenharmony_ci u32 val = mfsrin(i << 28); 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci seq_printf(m, "0x%01x0000000-0x%01xfffffff ", i, i); 168c2ecf20Sopenharmony_ci seq_printf(m, "Kern key %d ", (val >> 30) & 1); 178c2ecf20Sopenharmony_ci seq_printf(m, "User key %d ", (val >> 29) & 1); 188c2ecf20Sopenharmony_ci if (val & 0x80000000) { 198c2ecf20Sopenharmony_ci seq_printf(m, "Device 0x%03x", (val >> 20) & 0x1ff); 208c2ecf20Sopenharmony_ci seq_printf(m, "-0x%05x", val & 0xfffff); 218c2ecf20Sopenharmony_ci } else { 228c2ecf20Sopenharmony_ci if (val & 0x10000000) 238c2ecf20Sopenharmony_ci seq_puts(m, "No Exec "); 248c2ecf20Sopenharmony_ci seq_printf(m, "VSID 0x%06x", val & 0xffffff); 258c2ecf20Sopenharmony_ci } 268c2ecf20Sopenharmony_ci seq_puts(m, "\n"); 278c2ecf20Sopenharmony_ci} 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistatic int sr_show(struct seq_file *m, void *v) 308c2ecf20Sopenharmony_ci{ 318c2ecf20Sopenharmony_ci int i; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci seq_puts(m, "---[ User Segments ]---\n"); 348c2ecf20Sopenharmony_ci for (i = 0; i < TASK_SIZE >> 28; i++) 358c2ecf20Sopenharmony_ci seg_show(m, i); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci seq_puts(m, "\n---[ Kernel Segments ]---\n"); 388c2ecf20Sopenharmony_ci for (; i < 16; i++) 398c2ecf20Sopenharmony_ci seg_show(m, i); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci return 0; 428c2ecf20Sopenharmony_ci} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistatic int sr_open(struct inode *inode, struct file *file) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci return single_open(file, sr_show, NULL); 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic const struct file_operations sr_fops = { 508c2ecf20Sopenharmony_ci .open = sr_open, 518c2ecf20Sopenharmony_ci .read = seq_read, 528c2ecf20Sopenharmony_ci .llseek = seq_lseek, 538c2ecf20Sopenharmony_ci .release = single_release, 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic int __init sr_init(void) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci debugfs_create_file("segment_registers", 0400, powerpc_debugfs_root, 598c2ecf20Sopenharmony_ci NULL, &sr_fops); 608c2ecf20Sopenharmony_ci return 0; 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_cidevice_initcall(sr_init); 63