129f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill/* 229f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill * This file is subject to the terms and conditions of the GNU General Public 329f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill * License. See the file "COPYING" in the main directory of this archive 429f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill * for more details. 529f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill * 629f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill * Copyright (C) 2013 Imagination Technologies Ltd. 729f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill */ 829f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 929f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill#include <linux/kernel.h> 1029f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill#include <linux/debugfs.h> 1129f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill#include <linux/seq_file.h> 1229f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill#include <asm/cpu.h> 1329f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill#include <asm/mipsregs.h> 1429f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 1529f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hillstatic void build_segment_config(char *str, unsigned int cfg) 1629f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill{ 1729f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill unsigned int am; 1829f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill static const char * const am_str[] = { 1929f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill "UK", "MK", "MSK", "MUSK", "MUSUK", "USK", 2029f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill "RSRVD", "UUSK"}; 2129f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 2229f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill /* Segment access mode. */ 2329f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill am = (cfg & MIPS_SEGCFG_AM) >> MIPS_SEGCFG_AM_SHIFT; 2429f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill str += sprintf(str, "%-5s", am_str[am]); 2529f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 2629f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill /* 2729f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill * Access modes MK, MSK and MUSK are mapped segments. Therefore 2829f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill * there is no direct physical address mapping. 2929f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill */ 3029f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill if ((am == 0) || (am > 3)) { 3129f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill str += sprintf(str, " %03lx", 3229f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill ((cfg & MIPS_SEGCFG_PA) >> MIPS_SEGCFG_PA_SHIFT)); 3329f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill str += sprintf(str, " %01ld", 3429f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill ((cfg & MIPS_SEGCFG_C) >> MIPS_SEGCFG_C_SHIFT)); 3529f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill } else { 3629f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill str += sprintf(str, " UND"); 3729f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill str += sprintf(str, " U"); 3829f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill } 3929f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 4029f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill /* Exception configuration. */ 4129f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill str += sprintf(str, " %01ld\n", 4229f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill ((cfg & MIPS_SEGCFG_EU) >> MIPS_SEGCFG_EU_SHIFT)); 4329f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill} 4429f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 4529f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hillstatic int show_segments(struct seq_file *m, void *v) 4629f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill{ 4729f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill unsigned int segcfg; 4829f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill char str[42]; 4929f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 5029f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill seq_puts(m, "Segment Virtual Size Access Mode Physical Caching EU\n"); 5129f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill seq_puts(m, "------- ------- ---- ----------- -------- ------- --\n"); 5229f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 5329f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill segcfg = read_c0_segctl0(); 5429f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill build_segment_config(str, segcfg); 5529f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill seq_printf(m, " 0 e0000000 512M %s", str); 5629f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 5729f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill segcfg >>= 16; 5829f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill build_segment_config(str, segcfg); 5929f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill seq_printf(m, " 1 c0000000 512M %s", str); 6029f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 6129f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill segcfg = read_c0_segctl1(); 6229f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill build_segment_config(str, segcfg); 6329f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill seq_printf(m, " 2 a0000000 512M %s", str); 6429f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 6529f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill segcfg >>= 16; 6629f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill build_segment_config(str, segcfg); 6729f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill seq_printf(m, " 3 80000000 512M %s", str); 6829f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 6929f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill segcfg = read_c0_segctl2(); 7029f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill build_segment_config(str, segcfg); 7129f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill seq_printf(m, " 4 40000000 1G %s", str); 7229f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 7329f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill segcfg >>= 16; 7429f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill build_segment_config(str, segcfg); 7529f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill seq_printf(m, " 5 00000000 1G %s\n", str); 7629f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 7729f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill return 0; 7829f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill} 7929f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 8029f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hillstatic int segments_open(struct inode *inode, struct file *file) 8129f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill{ 8229f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill return single_open(file, show_segments, NULL); 8329f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill} 8429f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 8529f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hillstatic const struct file_operations segments_fops = { 8629f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill .open = segments_open, 8729f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill .read = seq_read, 8829f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill .llseek = seq_lseek, 8929f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill .release = single_release, 9029f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill}; 9129f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 9229f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hillstatic int __init segments_info(void) 9329f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill{ 9429f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill extern struct dentry *mips_debugfs_dir; 9529f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill struct dentry *segments; 9629f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 9729f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill if (cpu_has_segments) { 9829f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill if (!mips_debugfs_dir) 9929f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill return -ENODEV; 10029f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 10129f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill segments = debugfs_create_file("segments", S_IRUGO, 10229f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill mips_debugfs_dir, NULL, 10329f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill &segments_fops); 10429f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill if (!segments) 10529f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill return -ENOMEM; 10629f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill } 10729f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill return 0; 10829f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill} 10929f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hill 11029f9087c52d19067a1eccfd5c0a4a0045cf3ea04Steven J. Hilldevice_initcall(segments_info); 111