All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613
@ 2009-06-13 16:27 Jaswinder Singh Rajput
  2009-06-13 16:28 ` [RFC][PATCH 1/10 -tip] x86: cpu_debug update Kconfig entry Jaswinder Singh Rajput
  2009-06-13 22:27 ` [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613 Thomas Gleixner
  0 siblings, 2 replies; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 16:27 UTC (permalink / raw)
  To: Ingo Molnar, H. Peter Anvin, x86 maintainers, Andreas Herrmann,
	Andrew Morton, Andi Kleen, LKML, Yinghai Lu, Dave Jones,
	Linus Torvalds, Thomas Gleixner, Robert Richter

By adding these patches, cpu_debug will support :

1. Standard Registers
2. Control Registers
3. Debug Registers
4. Descriptor Tables
5. APIC Registers
6. Model specific Register (MSRs)
7. PCI configuration registers (for AMD)
8. Basic cpuinfo
9. CPUID Functions

Please let me know how we can improve it and add more features so it
becomes more useful.

For example on AMD 64 Laptop :

1. Standard Registers
---------------------

a. access complete state

# cat /sys/kernel/debug/x86/cpu/cpu0/tss/state
 RAX	: ffffffff81789fe8
 RBX	: 000000000007e000
 RCX	: ffffffff8179437f
 RDX	: 0000000000000000
 RSI	: 0000000000000000
 RDI	: 81798e0000104136
 RBP	: 000000000000001f
 ESP	: 0000000000000000
 R08	: 00000000000932d0
 R09	: 0000000000000000
 R10	: ffffffff8179429a
 R11	: ffffffff81789fa8
 R12	: 00000000afc723ac
 R13	: 00000000018e4f80
 R14	: ffffffff817cee80
 R15	: ffffffff81789f88
 CS	:             0010
 DS	:             0018
 SS	:             0000
 ES	:             0018
 FS	:             0000
 GS	:             0000
 EFLAGS	: 0000000000000000
 EIP	: 0000000000000000

2. Control Registers
--------------------

a. access complete state

# cat /sys/kernel/debug/x86/cpu/cpu0/cr/state
 cr0	: 000000008005003b
 cr2	: 0000000000429040
 cr3	: 0000000001001000
 cr4	: 00000000000006b0
 cr8	: 0000000000000000

3. Debug Registers
------------------

a. access complete state

# cat /sys/kernel/debug/x86/cpu/cpu0/debug/state
 dr0	: 0000000000000000
 dr1	: 0000000000000000
 dr2	: 0000000000000000
 dr3	: 0000000000000000
 dr6	: 00000000ffff0ff0
 dr7	: 0000000000000400

 MSR	:
 000001d9: 00000000_00000000

4. Descriptor Tables
--------------------

a. access complete state

# cat /sys/kernel/debug/x86/cpu/cpu0/dt/state
 IDT	: ffffffff81820fff
 GDT	: ffff88002802607f
 LDT	: ffffffff810b0000
 TR	: 0000000000000040

5. APIC Registers
-----------------

a. access complete state

# cat /sys/kernel/debug/x86/cpu/cpu0/apic/state
 LAPIC	:
 ID		: 00000000
 LVR		: 80050010
 TASKPRI	: 00000000
 ARBPRI		: 00000000
 PROCPRI	: 00000000
 LDR		: 01000000
 DFR		: ffffffff
 SPIV		: 000001ff
 ISR		: 00000000
 ESR		: 00000004
 ICR		: 000208fd
 ICR2		: 02000000
 LVTT		: 000300ef
 LVTTHMR	: 00010000
 LVTPC		: 00000400
 LVT0		: 00010700
 LVT1		: 00000400
 LVTERR		: 000000fe
 TMICT		: ffffffff
 TMCCT		: 8d52660d
 TDCR		: 00000003
 EFEAT		: 00040007
 ECTRL		: 00000000
 EILVT0		: 00010000
 EILVT1		: 00010000
 EILVT2		: 00010000
 EILVT3		: 00010000

 MSR	:
 0000001b: 00000000_fee00900

b. access individual APIC register :

# cat /sys/kernel/debug/x86/cpu/cpu0/apic/APIC_EFEAT/value 
0x40007

# cat /sys/kernel/debug/x86/cpu/cpu0/apic/MSR_1b/value
0xfee00900

6. Model specific Register (MSRs)
---------------------------------

a. access complete state, say performance monitor counter (pmc)

# cat /sys/kernel/debug/x86/cpu/cpu0/pmc/state
 MSR	:
 c0010000: 00000000_00430076
 c0010001: 00000000_3d179f6b
 c0010002: 00000000_7993feae
 c0010003: 00000000_f69637fe
 c0010004: 0000000f_4c47618a
 c0010005: 0000f0db_ffc3e9c3
 c0010006: 0000834f_15f5610e
 c0010007: 00006ade_595d2c95

b. access individual MSR :

# cat /sys/kernel/debug/x86/cpu/cpu0/pmc/MSR_c0010006/value 
0x834f15f5610e

c. write individual MSR :
# echo 2 >  /sys/kernel/debug/x86/cpu/cpu0/pmc/MSR_c0010006/value

# cat /sys/kernel/debug/x86/cpu/cpu0/pmc/MSR_c0010006/value 
0x2

7. PCI configuration registers (for AMD)
----------------------------------------

a. access complete state

 PCI configuration regsiters :
 function : 0
 000	: 13001022
 004	: 00100000
 008	: 06000040
 00c	: 00800000
 034	: 00000080
 040	: 00000000
 044	: 00000000
 048	: 00000000
 04c	: 00000000
 050	: 00000000
 054	: 00000000
 058	: 00000000
 05c	: 00000000
 060	: 00000000
 064	: 00000000
 068	: 012e4820
 06c	: 00000030
 080	: 21010008
 084	: 11112020
 088	: 1ff50a60
 08c	: 00000003
 090	: 001005b6
 094	: 00000000
 098	: 00000007
 0a0	: 00000000
 0a4	: 00000000
 0a8	: 00000000
 0ac	: 00000000
 0b0	: 00000000
 0b4	: 00000000
 0b8	: 00000000
 0c0	: 00000000
 0c4	: 00000000
 0c8	: 00000000
 0cc	: 00000000
 0d0	: 00000000
 0d4	: 00000000
 0d8	: 00000000
 0e0	: 00000000
 0e4	: 00000000
 0e8	: 00000000
 0ec	: 00000000
 0f0	: 00000000
 0f4	: 00000000
 0f8	: 00000000
 110	: 00000000
 114	: 00000000
 118	: 00000000
 11c	: 00000000
 120	: 00000000
 124	: 00000000
 128	: 00000000
 12c	: 00000000
 130	: 000000c1
 134	: 00000000
 138	: 00000000
 13c	: 00000000
 140	: 00000000
 144	: 00000000
 148	: 00000000
 14c	: 00000000
 150	: 00070000
 164	: 00000000
 168	: 00000000
 16c	: 0074e026
 170	: 07c00109
 174	: 00000000
 178	: 00000000
 17c	: 00000000
 180	: 00000000
 184	: 00000000
 188	: 00000000
 18c	: 00000000
 1a0	: 00000000
 1a4	: 00002824
 1d0	: 00000400
 1d4	: 00000051

 function : 1
 000	: 13011022
 004	: 00000000
 008	: 06000000
 00c	: 00800000
 034	: 00000000
 040	: 00000003
 044	: 013f0000
 048	: 00000000
 04c	: 00000000
 050	: 00000000
 054	: 00000000
 058	: 00000000
 05c	: 00000000
 060	: 00000000
 064	: 00000000
 068	: 00000000
 06c	: 00000000
 070	: 00000000
 074	: 00000000
 078	: 00000000
 07c	: 00000000
 080	: 00000000
 084	: 00000000
 088	: 00000a03
 08c	: 00000b00
 090	: 00c00003
 094	: 00cfff80
 098	: 00d00003
 09c	: 00d21f00
 0a0	: 00d22003
 0a4	: 00d22f80
 0a8	: 00d23003
 0ac	: 00dfff00
 0b0	: 00e00003
 0b4	: 00e3ff80
 0b8	: 00e40003
 0bc	: 00ffff00
 0c0	: 00000013
 0c4	: 00fff000
 0c8	: 00000000
 0cc	: 00000000
 0d0	: 00000000
 0d4	: 00000000
 0d8	: 00000000
 0dc	: 00000000
 0e0	: 00000000
 0e4	: 00000000
 0e8	: 00000000
 0ec	: 00000000
 0f0	: c0004001
 0f4	: 00000000
 110	: 00000000
 114	: 00000000
 120	: 00000000
 124	: 00000000
 140	: 00000000
 144	: 00000000
 148	: 00000000
 14c	: 00000000
 150	: 00000000
 154	: 00000000
 158	: 00000000
 15c	: 00000000
 160	: 00000000
 164	: 00000000
 168	: 00000000
 16c	: 00000000
 170	: 00000000
 174	: 00000000
 178	: 00000000
 17c	: 00000000
 180	: e0000011
 184	: 00000000

 function : 2
 000	: 13021022
 004	: 00000000
 008	: 06000000
 00c	: 00800000
 034	: 00000000
 040	: 00000001
 044	: 00000101
 048	: 00000000
 04c	: 00000000
 050	: 00000000
 054	: 00000000
 058	: 00000000
 05c	: 00000000
 060	: 00783ee0
 064	: 00000000
 068	: 00000000
 06c	: 00000000
 070	: 00000000
 074	: 00000000
 078	: 00000036
 07c	: 00000000
 080	: 00000005
 084	: 00000000
 088	: 7d7dfb35
 08c	: 0022173f
 090	: 00600020
 094	: 7e51806b
 098	: 80000013
 09c	: 0000003a
 0a0	: 000000a8
 0a4	: 00000000
 10c	: 00000000
 110	: 00000584
 114	: 00000000
 118	: 1441b4a4
 11c	: 00402064
 140	: 00000001
 144	: 00000101
 148	: 00000000
 14c	: 00000000
 150	: 00000000
 154	: 00000000
 158	: 00000000
 15c	: 00000000
 160	: 00783ee0
 164	: 00000000
 168	: 00000000
 16c	: 00000000
 178	: 00000036
 17c	: 00000000
 180	: 00000005
 184	: 00000000
 188	: 4d7dfb35
 18c	: 0022173f
 190	: 00600020
 194	: 7e51806b
 198	: 80000013
 19c	: 0000003c
 1a0	: 00000008
 1b0	: 00000000

 function : 3
 000	: 13031022
 004	: 00100000
 008	: 06000000
 00c	: 00800000
 034	: 000000f0
 040	: 00000100
 044	: 0a100040
 048	: 00000000
 04c	: 00000000
 050	: 00000000
 054	: 00000000
 058	: 00000000
 05c	: 00000000
 060	: 00000000
 064	: 1a600000
 068	: 100000c0
 06c	: 08000808
 070	: 00000000
 074	: 30000876
 078	: 00000000
 07c	: 85001101
 080	: ff00f300
 084	: 80e600ee
 088	: 00000000
 08c	: 00000000
 090	: 00000000
 094	: 00000000
 098	: 00000000
 09c	: 00000000
 0a0	: 800402bc
 0a4	: 3b201800
 0b0	: 00000000
 0d4	: 0005024d
 0d8	: 03000025
 0dc	: 00034240
 0e4	: 00000520
 0e8	: 00001f81
 0f0	: 0010000f
 0f4	: 00000000
 0f8	: 00000000
 0fc	: 00200f31
 140	: 00000000
 144	: 00000000
 148	: 00000000
 14c	: 00000000
 150	: 00000000
 154	: 00000000
 158	: 00000000
 15c	: 00000000
 160	: 00000000
 164	: 00000000
 168	: 00000000
 16c	: 00000000
 170	: 00000000
 174	: 00000000
 178	: 00000000
 17c	: 00000000
 180	: 00400002
 188	: 1b000438
 190	: 00000000
 1a0	: 00000000
 1cc	: 00000000
 1e4	: 80000000
 1e8	: 00000000
 1ec	: 00000000
 1f0	: 000f0500
 1fc	: 00000000

 function : 4
 000	: 13041022
 004	: 00000000
 008	: 06000000
 00c	: 00800000
 034	: 00000000
 080	: 00000000
 084	: 00000000
 088	: 00000000
 08c	: 00000000
 090	: 00000000
 094	: 00000000
 098	: 00000000
 09c	: 00000000
 0a0	: 00000000
 0a4	: 00000000
 0a8	: 00000000
 0ac	: 00000000
 0b0	: 00000000
 0b4	: 00000000
 0b8	: 00000000
 0bc	: 00000000
 0c0	: 00000000
 0c4	: 00000000
 0c8	: 00000000
 0cc	: 00000000
 0d0	: 00000000
 0d4	: 00000000
 0d8	: 00000000
 0dc	: 00000000
 0e0	: 00000000
 0e4	: 00000000
 0e8	: 00000000
 0ec	: 00000000
 0f0	: 00000000
 0f4	: 00000000
 0f8	: 00000000
 170	: 00000006
 174	: 0a3cdfe6
 180	: 800000c4
 184	: 00006400
 188	: 00000000
 18c	: 00000000
 190	: 00000000
 194	: 00000000
 198	: 00000000
 19c	: 00000000
 1c4	: 00000000
 1e0	: 00000000
 1e4	: 00000000
 1e8	: 00000000
 1ec	: 00000000
 1f0	: 00000000

b. access individual PCI configuration :

# cat /sys/kernel/debug/x86/cpu/cpu0/pci/PCI0_000/value 
0x13001022

# cat /sys/kernel/debug/x86/cpu/cpu0/therm/PCI3_0a4/value 
0x3c001800

8. Basic cpuinfo
----------------

a. access complete state

# cat /sys/kernel/debug/x86/cpu/cpu0/cpuinfo/state 
 CPUINFO	:
 processor		: 0
 family			: 17
 vendor			: 2
 model			: 3
 mask			: 1
 TLB size		: 1024 4K pages
 virtual bits		: 48
 physical bits		: 40
 extended cpuid level	: 8000001a (8000001a)
 cpuid level		: 1
 flags			: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow constant_tsc rep_good nonstop_tsc pni cx16 lahf_lm cmp_legacy svm extapic cr8_legacy 3dnowprefetch osvw skinit
 vendor id		: AuthenticAMD
 model id		: AMD Turion(tm) X2 Ultra Dual-Core Mobile ZM-80
 cache size		: 1024 KB
 cache alignment	: 64
 power management	: ts ttp tm stc 100mhzsteps hwpstate
 loops per jiffy	: 2098811
 bogomips		: 4197.62
 max cores		: 2
 apic id		: 0
 intial apic id		: 0
 clflush size		: 64
 cpu cores		: 2
 physical id		: 0
 core id		: 0
 cpu index		: 0
 hyper vendor		: 0

9. CPUID Functions
------------------

a. access complete state

# cat /sys/kernel/debug/x86/cpu/cpu0/cpuid/state
 CPUID	:
              eax       ebx       ecx       edx
 00000000  00000001  68747541  444d4163  69746e65
 00000001  00200f31  00020800  00002001  178bfbff
 80000000  8000001a  68747541  444d4163  69746e65
 80000001  00200f31  20000500  0000131f  ebd3fbff
 80000002  20444d41  69727554  74286e6f  5820296d
 80000003  6c552032  20617274  6c617544  726f432d
 80000004  6f4d2065  656c6962  2d4d5a20  00003038
 80000005  ff08ff08  ff20ff20  40020140  40020140
 80000006  00000000  42004200  04008140  00000000
 80000007  00000000  00000000  00000000  000001f9
 80000008  00003028  00000000  00001001  00000000
 80000009  00000000  00000000  00000000  00000000
 8000000a  00000001  00000040  00000000  0000000e
 8000000b  00000000  00000000  00000000  00000000
 8000000c  00000000  00000000  00000000  00000000
 8000000d  00000000  00000000  00000000  00000000
 8000000e  00000000  00000000  00000000  00000000
 8000000f  00000000  00000000  00000000  00000000
 80000010  00000000  00000000  00000000  00000000
 80000011  00000000  00000000  00000000  00000000
 80000012  00000000  00000000  00000000  00000000
 80000013  00000000  00000000  00000000  00000000
 80000014  00000000  00000000  00000000  00000000
 80000015  00000000  00000000  00000000  00000000
 80000016  00000000  00000000  00000000  00000000
 80000017  00000000  00000000  00000000  00000000
 80000018  00000000  00000000  00000000  00000000
 80000019  00000000  00000000  00000000  00000000
 8000001a  00000000  00000000  00000000  00000000

The following changes since commit 50149b2db7be15514079089d0c4efa4c7a2676bb:
  Ingo Molnar (1):
        Merge branch 'linus'

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jaswinder/linux-2.6-tip.git master

Jaswinder Singh Rajput (10):
      x86: cpu_debug update Kconfig entry
      x86: cpu_debug.c remove some not required header files
      x86: cpu_debug.c use a WARN_ONCE() instead of a pr_err()
      x86: cpu_debug make room to support more categories
      x86: cpu_debug update MSR list to support new architectures
      x86: cpu_debug make room for more cpu registers
      x86: cpu_debug support APIC_register_name with directory structure
      x86: cpu_debug display PCI configuration registers for AMD
      x86: cpu_debug display cpuid functions
      x86: cpu_debug display basic cpuinfo

 arch/x86/Kconfig                 |   12 +-
 arch/x86/include/asm/cpu_debug.h |  125 ++++----
 arch/x86/kernel/cpu/cpu_debug.c  |  681 +++++++++++++++++++++++++++++++++-----
 3 files changed, 666 insertions(+), 152 deletions(-)

Complete diff :

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 0c2321d..e5e26b3 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -994,9 +994,19 @@ config X86_CPUID
 
 config X86_CPU_DEBUG
 	tristate "/sys/kernel/debug/x86/cpu/* - CPU Debug support"
+	select DEBUG_FS
 	---help---
 	  If you select this option, this will provide various x86 CPUs
-	  information through debugfs.
+	  information through debugfs. Any user can read these file but writing
+	  needs root privilege.
+
+	  Note: 1. If you compile cpu_debug as a module, it will _not_ be loaded
+	  automatically (like usual drivers). You will need to load it manually
+	  (or add it to list of modules loaded during boot).
+
+	  2. You need debugfs, if you want to mount debugfs automatically
+	  append this line in /etc/fstab:
+	  debugfs	/sys/kernel/debug	debugfs	defaults	0 0
 
 choice
 	prompt "High Memory Support"
diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
index d96c1ee..b75758e 100644
--- a/arch/x86/include/asm/cpu_debug.h
+++ b/arch/x86/include/asm/cpu_debug.h
@@ -10,91 +10,80 @@
 /* Register flags */
 enum cpu_debug_bit {
 /* Model Specific Registers (MSRs)					*/
-	CPU_MC_BIT,				/* Machine Check	*/
-	CPU_MONITOR_BIT,			/* Monitor		*/
-	CPU_TIME_BIT,				/* Time			*/
-	CPU_PMC_BIT,				/* Performance Monitor	*/
-	CPU_PLATFORM_BIT,			/* Platform		*/
-	CPU_APIC_BIT,				/* APIC			*/
-	CPU_POWERON_BIT,			/* Power-on		*/
-	CPU_CONTROL_BIT,			/* Control		*/
-	CPU_FEATURES_BIT,			/* Features control	*/
-	CPU_LBRANCH_BIT,			/* Last Branch		*/
-	CPU_BIOS_BIT,				/* BIOS			*/
-	CPU_FREQ_BIT,				/* Frequency		*/
-	CPU_MTTR_BIT,				/* MTRR			*/
-	CPU_PERF_BIT,				/* Performance		*/
-	CPU_CACHE_BIT,				/* Cache		*/
-	CPU_SYSENTER_BIT,			/* Sysenter		*/
-	CPU_THERM_BIT,				/* Thermal		*/
-	CPU_MISC_BIT,				/* Miscellaneous	*/
-	CPU_DEBUG_BIT,				/* Debug		*/
-	CPU_PAT_BIT,				/* PAT			*/
-	CPU_VMX_BIT,				/* VMX			*/
-	CPU_CALL_BIT,				/* System Call		*/
-	CPU_BASE_BIT,				/* BASE Address		*/
-	CPU_VER_BIT,				/* Version ID		*/
-	CPU_CONF_BIT,				/* Configuration	*/
-	CPU_SMM_BIT,				/* System mgmt mode	*/
-	CPU_SVM_BIT,				/*Secure Virtual Machine*/
-	CPU_OSVM_BIT,				/* OS-Visible Workaround*/
+	CPU_MC,					/* Machine Check	*/
+	CPU_MONITOR,				/* Monitor		*/
+	CPU_TIME,				/* Time			*/
+	CPU_PMC,				/* Performance Monitor	*/
+	CPU_PLATFORM,				/* Platform		*/
+	CPU_APIC,				/* APIC			*/
+	CPU_POWERON,				/* Power-on		*/
+	CPU_CONTROL,				/* Control		*/
+	CPU_FEATURES,				/* Features control	*/
+	CPU_LBRANCH,				/* Last Branch		*/
+	CPU_BIOS,				/* BIOS			*/
+	CPU_FREQ,				/* Frequency		*/
+	CPU_MTRR,				/* MTRR			*/
+	CPU_PERF,				/* Performance		*/
+	CPU_CACHE,				/* Cache		*/
+	CPU_SYSENTER,				/* Sysenter		*/
+	CPU_THERM,				/* Thermal		*/
+	CPU_MISC,				/* Miscellaneous	*/
+	CPU_DEBUG,				/* Debug		*/
+	CPU_PAT,				/* PAT			*/
+	CPU_VMX,				/* VMX			*/
+	CPU_CALL,				/* System Call		*/
+	CPU_BASE,				/* BASE Address		*/
+	CPU_VER,				/* Version ID		*/
+	CPU_CONF,				/* Configuration	*/
+	CPU_SMM,				/* System mgmt mode	*/
+	CPU_POWER,				/* Power mgmt		*/
+	CPU_PNAME,				/* Processor name	*/
+	CPU_IBS,				/* IBS			*/
+	CPU_SVM,				/*Secure Virtual Machine*/
+	CPU_OSVM,				/* OS-Visible Workaround*/
+	CPU_NB,					/* North Bridge		*/
+	CPU_DRAM,				/* DRAM			*/
+	CPU_MMIO,				/* Memory based IO	*/
+	CPU_DISPLAY,				/* Display/VGA		*/
+	CPU_LINK,				/* HyperTransport	*/
 /* Standard Registers							*/
-	CPU_TSS_BIT,				/* Task Stack Segment	*/
-	CPU_CR_BIT,				/* Control Registers	*/
-	CPU_DT_BIT,				/* Descriptor Table	*/
+	CPU_TSS,				/* Task Stack Segment	*/
+	CPU_CR,					/* Control Registers	*/
+	CPU_DT,					/* Descriptor Table	*/
+	CPU_CPUID,				/* CPUID		*/
+	CPU_CPUINFO,				/* struct cpuinfo_x86	*/
+	CPU_PCI,				/* PCI configuration	*/
 /* End of Registers flags						*/
-	CPU_REG_ALL_BIT,			/* Select all Registers	*/
+	CPU_REG_MAX,				/* Max Registers flags	*/
 };
 
 #define	CPU_REG_ALL		(~0)		/* Select all Registers	*/
 
-#define	CPU_MC			(1 << CPU_MC_BIT)
-#define	CPU_MONITOR		(1 << CPU_MONITOR_BIT)
-#define	CPU_TIME		(1 << CPU_TIME_BIT)
-#define	CPU_PMC			(1 << CPU_PMC_BIT)
-#define	CPU_PLATFORM		(1 << CPU_PLATFORM_BIT)
-#define	CPU_APIC		(1 << CPU_APIC_BIT)
-#define	CPU_POWERON		(1 << CPU_POWERON_BIT)
-#define	CPU_CONTROL		(1 << CPU_CONTROL_BIT)
-#define	CPU_FEATURES		(1 << CPU_FEATURES_BIT)
-#define	CPU_LBRANCH		(1 << CPU_LBRANCH_BIT)
-#define	CPU_BIOS		(1 << CPU_BIOS_BIT)
-#define	CPU_FREQ		(1 << CPU_FREQ_BIT)
-#define	CPU_MTRR		(1 << CPU_MTTR_BIT)
-#define	CPU_PERF		(1 << CPU_PERF_BIT)
-#define	CPU_CACHE		(1 << CPU_CACHE_BIT)
-#define	CPU_SYSENTER		(1 << CPU_SYSENTER_BIT)
-#define	CPU_THERM		(1 << CPU_THERM_BIT)
-#define	CPU_MISC		(1 << CPU_MISC_BIT)
-#define	CPU_DEBUG		(1 << CPU_DEBUG_BIT)
-#define	CPU_PAT			(1 << CPU_PAT_BIT)
-#define	CPU_VMX			(1 << CPU_VMX_BIT)
-#define	CPU_CALL		(1 << CPU_CALL_BIT)
-#define	CPU_BASE		(1 << CPU_BASE_BIT)
-#define	CPU_VER			(1 << CPU_VER_BIT)
-#define	CPU_CONF		(1 << CPU_CONF_BIT)
-#define	CPU_SMM			(1 << CPU_SMM_BIT)
-#define	CPU_SVM			(1 << CPU_SVM_BIT)
-#define	CPU_OSVM		(1 << CPU_OSVM_BIT)
-#define	CPU_TSS			(1 << CPU_TSS_BIT)
-#define	CPU_CR			(1 << CPU_CR_BIT)
-#define	CPU_DT			(1 << CPU_DT_BIT)
-
 /* Register file flags */
 enum cpu_file_bit {
-	CPU_INDEX_BIT,				/* index		*/
-	CPU_VALUE_BIT,				/* value		*/
+	CPU_INDEX,				/* index		*/
+	CPU_VALUE,				/* value		*/
+};
+
+/* Register category flags */
+enum cpu_cat_bit {
+	CPU_REG_STD,				/* Standard registers	*/
+	CPU_REG_MSR,				/* MSRs			*/
+	CPU_REG_APIC,				/* APIC registers	*/
+	CPU_REG_PCI,				/* PCI conf registers	*/
 };
 
-#define	CPU_FILE_VALUE		(1 << CPU_VALUE_BIT)
+#define MAX_CPU_FILES		768		/* Max CPU debug files	*/
+#define MAX_CPU_PCI		5		/* AMD supports func 0-4*/
 
-#define MAX_CPU_FILES		512
+#define CPUID_MASK		0xffff0000
 
 struct cpu_private {
 	unsigned		cpu;
 	unsigned		type;
 	unsigned		reg;
 	unsigned		file;
+	unsigned		cat;
 };
 
 struct cpu_debug_base {
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index 6b2a52d..993a5bc 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -6,32 +6,34 @@
  * For licencing details see kernel-base/COPYING
  */
 
-#include <linux/interrupt.h>
-#include <linux/compiler.h>
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
-#include <linux/kprobes.h>
 #include <linux/uaccess.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/percpu.h>
-#include <linux/signal.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/pci.h>
 #include <linux/smp.h>
 
 #include <asm/cpu_debug.h>
 #include <asm/paravirt.h>
 #include <asm/system.h>
-#include <asm/traps.h>
 #include <asm/apic.h>
 #include <asm/desc.h>
 
-static DEFINE_PER_CPU(struct cpu_cpuX_base, cpu_arr[CPU_REG_ALL_BIT]);
+#ifdef MODULE
+#include "capflags.c"
+#include "powerflags.c"
+#endif
+
+static DEFINE_PER_CPU(struct cpu_cpuX_base, cpu_arr[CPU_REG_MAX]);
 static DEFINE_PER_CPU(struct cpu_private *, priv_arr[MAX_CPU_FILES]);
+static DEFINE_PER_CPU(struct pci_dev *, pci_arr[MAX_CPU_PCI]);
 static DEFINE_PER_CPU(int, cpu_priv_count);
 
 static DEFINE_MUTEX(cpu_debug_lock);
@@ -65,21 +67,63 @@ static struct cpu_debug_base cpu_base[] = {
 	{ "ver",	CPU_VER,	0	},
 	{ "conf",	CPU_CONF,	0	},
 	{ "smm",	CPU_SMM,	0	},
+	{ "power",	CPU_POWER,	0	},
+	{ "pname",	CPU_PNAME,	0	},
+	{ "ibs",	CPU_IBS,	0	},
 	{ "svm",	CPU_SVM,	0	},
 	{ "osvm",	CPU_OSVM,	0	},
+	{ "nbridge",	CPU_NB,		0	},
+	{ "dram",	CPU_DRAM,	0	},
+	{ "mmio",	CPU_MMIO,	0	},
+	{ "display",	CPU_DISPLAY,	0	},
+	{ "link",	CPU_LINK,	0	},
 	{ "tss",	CPU_TSS,	0	},
 	{ "cr",		CPU_CR,		0	},
 	{ "dt",		CPU_DT,		0	},
+	{ "cpuid",	CPU_CPUID,	0	},
+	{ "cpuinfo",	CPU_CPUINFO,	0	},
+	{ "pci",	CPU_PCI,	0	},
 	{ "registers",	CPU_REG_ALL,	0	},
 };
 
+#ifdef CONFIG_X86_LOCAL_APIC
+static struct cpu_debug_base cpu_apic[] = {
+	{ "ID",		APIC_ID,	0	},
+	{ "LVR",	APIC_LVR,	0	},
+	{ "TASKPRI",	APIC_TASKPRI,	0	},
+	{ "ARBPRI",	APIC_ARBPRI,	0	},
+	{ "PROCPRI",	APIC_PROCPRI,	0	},
+	{ "LDR",	APIC_LDR,	0	},
+	{ "DFR",	APIC_DFR,	0	},
+	{ "SPIV",	APIC_SPIV,	0	},
+	{ "ISR",	APIC_ISR,	0	},
+	{ "ESR",	APIC_ESR,	0	},
+	{ "ICR",	APIC_ICR,	0	},
+	{ "ICR2",	APIC_ICR2,	0	},
+	{ "LVTT",	APIC_LVTT,	0	},
+	{ "LVTTHMR",	APIC_LVTTHMR,	0	},
+	{ "LVTPC",	APIC_LVTPC,	0	},
+	{ "LVT0",	APIC_LVT0,	0	},
+	{ "LVT1",	APIC_LVT1,	0	},
+	{ "LVTERR",	APIC_LVTERR,	0	},
+	{ "TMICT",	APIC_TMICT,	0	},
+	{ "TMCCT",	APIC_TMCCT,	0	},
+	{ "TDCR",	APIC_TDCR,	0	},
+};
+
+static struct cpu_debug_base cpu_xapic[] = {
+	{ "EFEAT",	APIC_EFEAT,	0	},
+	{ "ECTRL",	APIC_ECTRL,	0	},
+};
+#endif
+
 static struct cpu_file_base cpu_file[] = {
-	{ "index",	CPU_REG_ALL,	0	},
+	{ "state",	CPU_REG_ALL,	0	},
 	{ "value",	CPU_REG_ALL,	1	},
 };
 
 /* CPU Registers Range */
-static struct cpu_debug_range cpu_reg_range[] = {
+static struct cpu_debug_range cpu_msr_range[] = {
 	{ 0x00000000, 0x00000001, CPU_MC,	},
 	{ 0x00000006, 0x00000007, CPU_MONITOR,	},
 	{ 0x00000010, 0x00000010, CPU_TIME,	},
@@ -95,6 +139,7 @@ static struct cpu_debug_range cpu_reg_range[] = {
 	{ 0x00000088, 0x0000008A, CPU_CACHE,	},
 	{ 0x0000008B, 0x0000008B, CPU_BIOS,	},
 	{ 0x0000009B, 0x0000009B, CPU_MONITOR,	},
+	{ 0x000000A0, 0x000000A1, CPU_SMM,	},
 	{ 0x000000C1, 0x000000C4, CPU_PMC,	},
 	{ 0x000000CD, 0x000000CD, CPU_FREQ,	},
 	{ 0x000000E7, 0x000000E8, CPU_PERF,	},
@@ -103,40 +148,49 @@ static struct cpu_debug_range cpu_reg_range[] = {
 	{ 0x00000116, 0x0000011E, CPU_CACHE,	},
 	{ 0x00000174, 0x00000176, CPU_SYSENTER,	},
 	{ 0x00000179, 0x0000017B, CPU_MC,	},
+	{ 0x00000180, 0x00000185, CPU_MC,	},
 	{ 0x00000186, 0x00000189, CPU_PMC,	},
 	{ 0x00000198, 0x00000199, CPU_PERF,	},
 	{ 0x0000019A, 0x0000019A, CPU_TIME,	},
 	{ 0x0000019B, 0x0000019D, CPU_THERM,	},
 	{ 0x000001A0, 0x000001A0, CPU_MISC,	},
-	{ 0x000001C9, 0x000001C9, CPU_LBRANCH,	},
+	{ 0x000001A1, 0x000001A1, CPU_PLATFORM,	},
+	{ 0x000001A2, 0x000001A2, CPU_THERM,	},
+	{ 0x000001A6, 0x000001A6, CPU_PMC,	},
+	{ 0x000001AD, 0x000001AD, CPU_FREQ,	},
+	{ 0x000001C8, 0x000001C9, CPU_LBRANCH,	},
 	{ 0x000001D7, 0x000001D8, CPU_LBRANCH,	},
 	{ 0x000001D9, 0x000001D9, CPU_DEBUG,	},
 	{ 0x000001DA, 0x000001E0, CPU_LBRANCH,	},
+	{ 0x000001F2, 0x000001F3, CPU_SMM,	},
 
 	{ 0x00000200, 0x0000020F, CPU_MTRR,	},
 	{ 0x00000250, 0x00000250, CPU_MTRR,	},
 	{ 0x00000258, 0x00000259, CPU_MTRR,	},
 	{ 0x00000268, 0x0000026F, CPU_MTRR,	},
 	{ 0x00000277, 0x00000277, CPU_PAT,	},
+	{ 0x00000280, 0x00000288, CPU_MC,	},
 	{ 0x000002FF, 0x000002FF, CPU_MTRR,	},
 
 	{ 0x00000300, 0x00000311, CPU_PMC,	},
 	{ 0x00000345, 0x00000345, CPU_PMC,	},
 	{ 0x00000360, 0x00000371, CPU_PMC,	},
-	{ 0x0000038D, 0x00000390, CPU_PMC,	},
+	{ 0x0000038D, 0x00000396, CPU_PMC,	},
 	{ 0x000003A0, 0x000003BE, CPU_PMC,	},
 	{ 0x000003C0, 0x000003CD, CPU_PMC,	},
 	{ 0x000003E0, 0x000003E1, CPU_PMC,	},
-	{ 0x000003F0, 0x000003F2, CPU_PMC,	},
+	{ 0x000003F0, 0x000003FD, CPU_PMC,	},
 
-	{ 0x00000400, 0x00000417, CPU_MC,	},
+	{ 0x00000400, 0x00000421, CPU_MC,	},
 	{ 0x00000480, 0x0000048B, CPU_VMX,	},
 
 	{ 0x00000600, 0x00000600, CPU_DEBUG,	},
 	{ 0x00000680, 0x0000068F, CPU_LBRANCH,	},
 	{ 0x000006C0, 0x000006CF, CPU_LBRANCH,	},
 
-	{ 0x000107CC, 0x000107D3, CPU_PMC,	},
+	{ 0x00000800, 0x0000083F, CPU_APIC,	},
+
+	{ 0x000107CC, 0x000107D8, CPU_PMC,	},
 
 	{ 0xC0000080, 0xC0000080, CPU_FEATURES,	},
 	{ 0xC0000081, 0xC0000084, CPU_CALL,	},
@@ -149,20 +203,120 @@ static struct cpu_debug_range cpu_reg_range[] = {
 	{ 0xC0010016, 0xC001001A, CPU_MTRR,	},
 	{ 0xC001001D, 0xC001001D, CPU_MTRR,	},
 	{ 0xC001001F, 0xC001001F, CPU_CONF,	},
-	{ 0xC0010030, 0xC0010035, CPU_BIOS,	},
-	{ 0xC0010044, 0xC0010048, CPU_MC,	},
+	{ 0xC0010022, 0xC0010022, CPU_MC,	},
+	{ 0xC0010030, 0xC0010035, CPU_PNAME,	},
+	{ 0xC0010044, 0xC0010049, CPU_MC,	},
 	{ 0xC0010050, 0xC0010056, CPU_SMM,	},
 	{ 0xC0010058, 0xC0010058, CPU_CONF,	},
 	{ 0xC0010060, 0xC0010060, CPU_CACHE,	},
-	{ 0xC0010061, 0xC0010068, CPU_SMM,	},
-	{ 0xC0010069, 0xC001006B, CPU_SMM,	},
+	{ 0xC0010061, 0xC001006B, CPU_POWER,	},
 	{ 0xC0010070, 0xC0010071, CPU_SMM,	},
+	{ 0xC0010074, 0xC0010074, CPU_TIME,	},
 	{ 0xC0010111, 0xC0010113, CPU_SMM,	},
 	{ 0xC0010114, 0xC0010118, CPU_SVM,	},
 	{ 0xC0010140, 0xC0010141, CPU_OSVM,	},
+
+	{ 0xC0011004, 0xC0011005, CPU_FEATURES,	},
 	{ 0xC0011022, 0xC0011023, CPU_CONF,	},
+	{ 0xC001102A, 0xC001102A, CPU_CONF,	},
+	{ 0xC0011030, 0xC001103A, CPU_IBS,	},
+};
+
+/* PCI-defined configurations registers		*/
+
+/* Function 0 Link Configuration Registers	*/
+static struct cpu_debug_range cpu_amd_pci0[] = {
+	{ 0x000,	0x00C,	CPU_PCI		},
+	{ 0x034,	0x034,	CPU_PCI		},
+	{ 0x040,	0x06C,	CPU_LINK	},
+	{ 0x080,	0x098,	CPU_LINK	},
+	{ 0x0A0,	0x0B8,	CPU_LINK	},
+	{ 0x0C0,	0x0D8,	CPU_LINK	},
+	{ 0x0E0,	0x0F8,	CPU_LINK	},
+	{ 0x110,	0x150,	CPU_LINK	},
+	{ 0x164,	0x18C,	CPU_LINK	},
+	{ 0x1A0,	0x1A0,	CPU_LINK	},
+	{ 0x1A4,	0x1A4,	CPU_DISPLAY	},
+	{ 0x1D0,	0x1D4,	CPU_DISPLAY	},
+};
+
+/* Function 1 Address Map Registers		*/
+static struct cpu_debug_range cpu_amd_pci1[] = {
+	{ 0x000,	0x00C,	CPU_PCI		},
+	{ 0x034,	0x034,	CPU_PCI		},
+	{ 0x040,	0x07C,	CPU_DRAM	},
+	{ 0x080,	0x0BC,	CPU_MMIO	},
+	{ 0x0C0,	0x0DC,	CPU_PCI		},
+	{ 0x0E0,	0x0EC,	CPU_CONF	},
+	{ 0x0F0,	0x0F0,	CPU_DRAM	},
+	{ 0x0F4,	0x0F4,	CPU_DISPLAY	},
+	{ 0x110,	0x114,	CPU_MMIO	},
+	{ 0x120,	0x124,	CPU_DRAM	},
+	{ 0x140,	0x17C,	CPU_DRAM	},
+	{ 0x180,	0x184,	CPU_NB		},
+};
+
+/* Function 2 DRAM Controller Registers		*/
+static struct cpu_debug_range cpu_amd_pci2[] = {
+	{ 0x000,	0x00C,	CPU_PCI		},
+	{ 0x034,	0x034,	CPU_PCI		},
+	{ 0x040,	0x0A4,	CPU_DRAM	},
+	{ 0x10C,	0x11C,	CPU_DRAM	},
+	{ 0x140,	0x16C,	CPU_DRAM	},
+	{ 0x178,	0x1A0,	CPU_DRAM	},
+	{ 0x1B0,	0x1B0,	CPU_DRAM	},
+};
+
+/* Function 3 Misc. Configuration Registers	*/
+static struct cpu_debug_range cpu_amd_pci3[] = {
+	{ 0x000,	0x00C,	CPU_PCI		},
+	{ 0x034,	0x034,	CPU_PCI		},
+	{ 0x040,	0x054,	CPU_NB		},
+	{ 0x058,	0x060,	CPU_DRAM	},
+	{ 0x064,	0x068,	CPU_THERM	},
+	{ 0x06C,	0x06C,	CPU_POWER	},
+	{ 0x070,	0x07C,	CPU_DISPLAY	},
+	{ 0x080,	0x084,	CPU_POWER	},
+	{ 0x088,	0x08C,	CPU_NB		},
+	{ 0x090,	0x09C,	CPU_DISPLAY	},
+	{ 0x0A0,	0x0A0,	CPU_POWER	},
+	{ 0x0A4,	0x0A4,	CPU_THERM	},
+	{ 0x0B0,	0x0B0,	CPU_DISPLAY	},
+	{ 0x0D4,	0x0DC,	CPU_POWER	},
+	{ 0x0E4,	0x0E4,	CPU_THERM	},
+	{ 0x0E8,	0x0E8,	CPU_NB		},
+	{ 0x0F0,	0x0F0,	CPU_PCI		},
+	{ 0x0F4,	0x0F8,	CPU_PCI		},
+	{ 0x0FC,	0x0FC,	CPU_CPUID	},
+	{ 0x140,	0x180,	CPU_NB		},
+	{ 0x188,	0x188,	CPU_NB		},
+	{ 0x190,	0x190,	CPU_CONTROL	},
+	{ 0x1A0,	0x1A0,	CPU_CACHE	},
+	{ 0x1CC,	0x1CC,	CPU_IBS		},
+	{ 0x1E4,	0x1EC,	CPU_THERM	},
+	{ 0x1F0,	0x1F0,	CPU_CPUID	},
+	{ 0x1FC,	0x1FC,	CPU_NB		},
 };
 
+/* Function 4 Link Configuration Registers	*/
+static struct cpu_debug_range cpu_amd_pci4[] = {
+	{ 0x000,	0x00C,	CPU_PCI		},
+	{ 0x034,	0x034,	CPU_PCI		},
+	{ 0x080,	0x0F8,	CPU_LINK	},
+	{ 0x170,	0x174,	CPU_POWER	},
+	{ 0x180,	0x19C,	CPU_LINK	},
+	{ 0x1C4,	0x1C4,	CPU_POWER	},
+	{ 0x1E0,	0x1F0,	CPU_POWER	},
+};
+
+/* Extended CPUID base address			*/
+static u32 cpu_ext_cpuid[] = {
+	0x80000000,		/* Intel, AMD	*/
+	0x80860000,		/* Transmeta	*/
+	0xC0000000,		/* Centaur	*/
+};
+
+/* Check validity of cpu debug flag */
 static int is_typeflag_valid(unsigned cpu, unsigned flag)
 {
 	int i;
@@ -171,8 +325,9 @@ static int is_typeflag_valid(unsigned cpu, unsigned flag)
 	if (flag >= CPU_TSS)
 		return 1;
 
-	for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
-		if (cpu_reg_range[i].flag == flag)
+	/* check MSR range */
+	for (i = 0; i < ARRAY_SIZE(cpu_msr_range); i++) {
+		if (cpu_msr_range[i].flag == flag)
 			return 1;
 	}
 
@@ -180,12 +335,13 @@ static int is_typeflag_valid(unsigned cpu, unsigned flag)
 	return 0;
 }
 
-static unsigned get_cpu_range(unsigned cpu, unsigned *min, unsigned *max,
+/* get MSR range */
+static unsigned get_msr_range(unsigned cpu, unsigned *min, unsigned *max,
 			      int index, unsigned flag)
 {
-	if (cpu_reg_range[index].flag == flag) {
-		*min = cpu_reg_range[index].min;
-		*max = cpu_reg_range[index].max;
+	if (cpu_msr_range[index].flag == flag) {
+		*min = cpu_msr_range[index].min;
+		*max = cpu_msr_range[index].max;
 	} else
 		*max = 0;
 
@@ -226,11 +382,12 @@ static void print_msr(struct seq_file *seq, unsigned cpu, unsigned flag)
 					       &low, &high))
 				print_cpu_data(seq, priv->reg, low, high);
 			return;
-		}
+		} else
+			seq_printf(seq, " MSR\t:\n");
 	}
 
-	for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
-		if (!get_cpu_range(cpu, &msr_min, &msr_max, i, flag))
+	for (i = 0; i < ARRAY_SIZE(cpu_msr_range); i++) {
+		if (!get_msr_range(cpu, &msr_min, &msr_max, i, flag))
 			continue;
 
 		for (msr = msr_min; msr <= msr_max; msr++) {
@@ -339,7 +496,7 @@ static void print_dr(void *arg)
 		seq_printf(seq, " dr%d\t: %016lx\n", i, dr);
 	}
 
-	seq_printf(seq, "\n MSR\t:\n");
+	seq_printf(seq, "\n");
 }
 
 static void print_apic(void *arg)
@@ -347,43 +504,251 @@ static void print_apic(void *arg)
 	struct seq_file *seq = arg;
 
 #ifdef CONFIG_X86_LOCAL_APIC
+	unsigned int i;
+
 	seq_printf(seq, " LAPIC\t:\n");
-	seq_printf(seq, " ID\t\t: %08x\n",  apic_read(APIC_ID) >> 24);
-	seq_printf(seq, " LVR\t\t: %08x\n",  apic_read(APIC_LVR));
-	seq_printf(seq, " TASKPRI\t: %08x\n",  apic_read(APIC_TASKPRI));
-	seq_printf(seq, " ARBPRI\t\t: %08x\n",  apic_read(APIC_ARBPRI));
-	seq_printf(seq, " PROCPRI\t: %08x\n",  apic_read(APIC_PROCPRI));
-	seq_printf(seq, " LDR\t\t: %08x\n",  apic_read(APIC_LDR));
-	seq_printf(seq, " DFR\t\t: %08x\n",  apic_read(APIC_DFR));
-	seq_printf(seq, " SPIV\t\t: %08x\n",  apic_read(APIC_SPIV));
-	seq_printf(seq, " ISR\t\t: %08x\n",  apic_read(APIC_ISR));
-	seq_printf(seq, " ESR\t\t: %08x\n",  apic_read(APIC_ESR));
-	seq_printf(seq, " ICR\t\t: %08x\n",  apic_read(APIC_ICR));
-	seq_printf(seq, " ICR2\t\t: %08x\n",  apic_read(APIC_ICR2));
-	seq_printf(seq, " LVTT\t\t: %08x\n",  apic_read(APIC_LVTT));
-	seq_printf(seq, " LVTTHMR\t: %08x\n",  apic_read(APIC_LVTTHMR));
-	seq_printf(seq, " LVTPC\t\t: %08x\n",  apic_read(APIC_LVTPC));
-	seq_printf(seq, " LVT0\t\t: %08x\n",  apic_read(APIC_LVT0));
-	seq_printf(seq, " LVT1\t\t: %08x\n",  apic_read(APIC_LVT1));
-	seq_printf(seq, " LVTERR\t\t: %08x\n",  apic_read(APIC_LVTERR));
-	seq_printf(seq, " TMICT\t\t: %08x\n",  apic_read(APIC_TMICT));
-	seq_printf(seq, " TMCCT\t\t: %08x\n",  apic_read(APIC_TMCCT));
-	seq_printf(seq, " TDCR\t\t: %08x\n",  apic_read(APIC_TDCR));
+	for (i = 0; i < ARRAY_SIZE(cpu_apic); i++) {
+		if (strlen(cpu_apic[i].name) < 7)
+			seq_printf(seq, " %s\t\t: %08x\n",  cpu_apic[i].name,
+				   apic_read(cpu_apic[i].flag));
+		else
+			seq_printf(seq, " %s\t: %08x\n",  cpu_apic[i].name,
+				   apic_read(cpu_apic[i].flag));
+	}
 	if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
-		unsigned int i, v, maxeilvt;
+		unsigned int maxeilvt;
 
-		v = apic_read(APIC_EFEAT);
-		maxeilvt = (v >> 16) & 0xff;
-		seq_printf(seq, " EFEAT\t\t: %08x\n", v);
-		seq_printf(seq, " ECTRL\t\t: %08x\n", apic_read(APIC_ECTRL));
+		for (i = 0; i < ARRAY_SIZE(cpu_xapic); i++)
+			seq_printf(seq, " %s\t\t: %08x\n",  cpu_xapic[i].name,
+				   apic_read(cpu_xapic[i].flag));
 
-		for (i = 0; i < maxeilvt; i++) {
-			v = apic_read(APIC_EILVTn(i));
-			seq_printf(seq, " EILVT%d\t\t: %08x\n", i, v);
+		maxeilvt = (apic_read(APIC_EFEAT) >> 16) & 0xff;
+		for (i = 0; i < maxeilvt; i++)
+			seq_printf(seq, " EILVT%d\t\t: %08x\n",
+				   i, apic_read(APIC_EILVTn(i)));
+	}
+	seq_printf(seq, "\n");
+#endif
+}
+
+/* Get extended CPUID level */
+static u32 get_extended_cpuid(void)
+{
+	u32 i, level;
+
+	for (i = 0; i < ARRAY_SIZE(cpu_ext_cpuid); i++) {
+		level = cpuid_eax(cpu_ext_cpuid[i]);
+		if ((level & CPUID_MASK) == cpu_ext_cpuid[i])
+			return level;
+	}
+
+	return 0;		/* Not found */
+}
+
+static void print_cpuidabcd(struct seq_file *seq, u32 min, u32 max)
+{
+	u32 i, eax, ebx, ecx, edx;
+
+	for (i = min; i <= max; i++) {
+		cpuid(i, &eax, &ebx, &ecx, &edx);
+		seq_printf(seq, " %08x  %08x  %08x  %08x  %08x\n",
+			   i, eax, ebx, ecx, edx);
+	}
+}
+
+static void print_cpuid(void *arg)
+{
+	struct seq_file *seq = arg;
+	u32 level;
+
+	seq_printf(seq, " CPUID\t:\n");
+	seq_printf(seq, "              eax       ebx       ecx       edx\n");
+
+	/* Standard CPUID functions */
+	level = cpuid_eax(0);
+	print_cpuidabcd(seq, 0, level);
+
+	/* Extended CPUID functions */
+	level = get_extended_cpuid();
+	if (level)
+		print_cpuidabcd(seq, (level & CPUID_MASK), level);
+}
+
+/* dump struct cpuinfo_x86 */
+static void print_cpuinfo(void *arg)
+{
+	struct seq_file *seq = arg;
+	struct cpu_private *priv = seq->private;
+	struct cpuinfo_x86 *cpui;
+	unsigned int i;
+
+	cpui = &cpu_data(priv->cpu);
+	seq_printf(seq, " CPUINFO\t:\n");
+	seq_printf(seq, " processor\t\t: %u\n", priv->cpu);
+
+	seq_printf(seq, " family\t\t\t: %u\n", cpui->x86);
+	seq_printf(seq, " vendor\t\t\t: %u\n", cpui->x86_vendor);
+	seq_printf(seq, " model\t\t\t: %u\n", cpui->x86_model);
+	seq_printf(seq, " mask\t\t\t: %u\n", cpui->x86_mask);
+#ifdef CONFIG_X86_32
+	seq_printf(seq, " wp_works_ok\t\t: %u\n", cpui->wp_works_ok);
+	seq_printf(seq, " halt_works_ok\t\t: %u\n", cpui->hlt_works_ok);
+	seq_printf(seq, " hard_math\t\t: %u\n", cpui->hard_math);
+	seq_printf(seq, " rfu\t\t\t: %u\n", cpui->rfu);
+	seq_printf(seq, " fdiv_bug\t\t: %u\n", cpui->fdiv_bug);
+	seq_printf(seq, " f00f_bug\t\t: %u\n", cpui->f00f_bug);
+	seq_printf(seq, " coma_bug\t\t: %u\n", cpui->coma_bug);
+#else
+	seq_printf(seq, " TLB size\t\t: %d 4K pages\n", cpui->x86_tlbsize);
+#endif
+	seq_printf(seq, " virtual bits\t\t: %u\n", cpui->x86_virt_bits);
+	seq_printf(seq, " physical bits\t\t: %u\n", cpui->x86_phys_bits);
+
+	seq_printf(seq, " extended cpuid level\t: %08x (%08x)\n",
+		   cpui->extended_cpuid_level, get_extended_cpuid());
+	seq_printf(seq, " cpuid level\t\t: %d\n", cpui->cpuid_level);
+
+	seq_printf(seq, " flags\t\t\t:");
+	for (i = 0; i < 32 * NCAPINTS; i++)
+		if (cpu_has(cpui, i) && x86_cap_flags[i] != NULL)
+			seq_printf(seq, " %s", x86_cap_flags[i]);
+
+	seq_printf(seq, "\n vendor id\t\t: %s\n",
+		   cpui->x86_vendor_id[0] ? cpui->x86_vendor_id : "unknown");
+	seq_printf(seq, " model id\t\t: %s\n",
+		   cpui->x86_model_id[0] ? cpui->x86_model_id : "unknown");
+
+	seq_printf(seq, " cache size\t\t: %d KB\n", cpui->x86_cache_size);
+	seq_printf(seq, " cache alignment\t: %d\n", cpui->x86_cache_alignment);
+
+	seq_printf(seq, " power management\t:");
+	for (i = 0; i < 32; i++) {
+		if (cpui->x86_power & (1 << i)) {
+			if (i < ARRAY_SIZE(x86_power_flags) &&
+			    x86_power_flags[i])
+				seq_printf(seq, "%s%s",
+					   x86_power_flags[i][0] ? " " : "",
+					   x86_power_flags[i]);
+			else
+				seq_printf(seq, " [%d]", i);
 		}
 	}
-#endif /* CONFIG_X86_LOCAL_APIC */
-	seq_printf(seq, "\n MSR\t:\n");
+
+	seq_printf(seq, "\n loops per jiffy\t: %lu\n", cpui->loops_per_jiffy);
+	seq_printf(seq, " bogomips\t\t: %lu.%02lu\n",
+		   cpui->loops_per_jiffy/(500000/HZ),
+		   (cpui->loops_per_jiffy/(5000/HZ)) % 100);
+
+	seq_printf(seq, " max cores\t\t: %d\n", cpui->x86_max_cores);
+	seq_printf(seq, " apic id\t\t: %d\n", cpui->apicid);
+	seq_printf(seq, " intial apic id\t\t: %d\n", cpui->initial_apicid);
+	seq_printf(seq, " clflush size\t\t: %u\n", cpui->x86_clflush_size);
+
+#ifdef CONFIG_SMP
+	seq_printf(seq, " cpu cores\t\t: %d\n", cpui->booted_cores);
+	seq_printf(seq, " physical id\t\t: %d\n", cpui->phys_proc_id);
+	seq_printf(seq, " core id\t\t: %d\n", cpui->cpu_core_id);
+	seq_printf(seq, " cpu index\t\t: %d\n", cpui->cpu_index);
+#endif
+
+	seq_printf(seq, " hyper vendor\t\t: %d\n", cpui->x86_hyper_vendor);
+}
+
+static void print_apicval(void *arg)
+{
+	struct seq_file *seq = arg;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+	struct cpu_private *priv = seq->private;
+
+	seq_printf(seq, "0x%x\n", apic_read(priv->reg));
+#endif
+}
+
+static void print_pcival(void *arg)
+{
+	struct seq_file *seq = arg;
+	struct cpu_private *priv = seq->private;
+	struct pci_dev *dev;
+	u32 data = (priv->reg & 0xf0000) >> 16;
+
+	if (data >= MAX_CPU_PCI)
+		return;
+
+	dev = per_cpu(pci_arr[data], priv->cpu);
+	if (!pci_read_config_dword(dev, priv->reg & 0x0fff, &data))
+		seq_printf(seq, "0x%x\n", data);
+}
+
+#define PRINT_AMD_PCI(func) \
+static void print_amd_pci##func(struct seq_file *seq, struct pci_dev *dev) \
+{									\
+	unsigned int reg, i;						\
+	u32 data;							\
+									\
+	for (i = 0; i < ARRAY_SIZE(cpu_amd_pci##func); i++) {		\
+		for (reg = cpu_amd_pci##func[i].min; 			\
+		     reg <= cpu_amd_pci##func[i].max; reg++) {		\
+			if (!pci_read_config_dword(dev, reg, &data)) {	\
+				seq_printf(seq, " %03x\t: %08x\n", 	\
+					   reg, data);			\
+			}						\
+		}							\
+	}								\
+	seq_printf(seq, "\n");						\
+}
+
+PRINT_AMD_PCI(0)
+PRINT_AMD_PCI(1)
+PRINT_AMD_PCI(2)
+PRINT_AMD_PCI(3)
+PRINT_AMD_PCI(4)
+
+static void print_amd_pci(struct seq_file *seq)
+{
+	struct cpu_private *priv = seq->private;
+	struct pci_dev *dev;
+	unsigned int func;
+
+	for (func = 0; func < MAX_CPU_PCI; func++) {
+		dev = per_cpu(pci_arr[func], priv->cpu);
+		if (dev == NULL)
+			continue;
+
+		seq_printf(seq, " function : %d\n", func);
+
+		switch (func) {
+		case 0:
+			print_amd_pci0(seq, dev);
+			break;
+		case 1:
+			print_amd_pci1(seq, dev);
+			break;
+		case 2:
+			print_amd_pci2(seq, dev);
+			break;
+		case 3:
+			print_amd_pci3(seq, dev);
+			break;
+		case 4:
+			print_amd_pci4(seq, dev);
+			break;
+		}
+	}
+}
+
+static void print_pci(void *arg)
+{
+	struct seq_file *seq = arg;
+
+	seq_printf(seq, " PCI configuration regsiters :\n");
+	switch (boot_cpu_data.x86_vendor) {
+	case X86_VENDOR_AMD:
+		print_amd_pci(seq);
+		break;
+	default:
+		return;
+	}
 }
 
 static int cpu_seq_show(struct seq_file *seq, void *v)
@@ -403,19 +768,46 @@ static int cpu_seq_show(struct seq_file *seq, void *v)
 	case CPU_DT:
 		smp_call_function_single(priv->cpu, print_dt, seq, 1);
 		break;
+	case CPU_CPUID:
+		if (priv->file == CPU_INDEX)
+			smp_call_function_single(priv->cpu, print_cpuid,
+						 seq, 1);
+		else
+			smp_call_function_single(priv->cpu, print_pcival,
+						 seq, 1);
+		break;
+	case CPU_CPUINFO:
+		smp_call_function_single(priv->cpu, print_cpuinfo, seq, 1);
+		break;
+	case CPU_PCI:
+		if (priv->file == CPU_INDEX)
+			smp_call_function_single(priv->cpu, print_pci, seq, 1);
+		else
+			smp_call_function_single(priv->cpu, print_pcival,
+						 seq, 1);
+		break;
 	case CPU_DEBUG:
-		if (priv->file == CPU_INDEX_BIT)
+		if (priv->file == CPU_INDEX)
 			smp_call_function_single(priv->cpu, print_dr, seq, 1);
-		print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
+		if (priv->cat == CPU_REG_MSR)
+			print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
 		break;
 	case CPU_APIC:
-		if (priv->file == CPU_INDEX_BIT)
+		if (priv->file == CPU_INDEX)
 			smp_call_function_single(priv->cpu, print_apic, seq, 1);
-		print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
+		if (priv->cat == CPU_REG_MSR)
+			print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
+		else if (priv->cat == CPU_REG_APIC)
+			smp_call_function_single(priv->cpu, print_apicval,
+						 seq, 1);
 		break;
 
 	default:
-		print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
+		if (priv->cat == CPU_REG_MSR)
+			print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
+		else if (priv->cat == CPU_REG_PCI)
+			smp_call_function_single(priv->cpu, print_pcival,
+						 seq, 1);
 		break;
 	}
 	seq_printf(seq, "\n");
@@ -487,7 +879,7 @@ static int write_cpu_register(struct cpu_private *priv, const char *buf)
 		return ret;
 
 	/* Supporting only MSRs */
-	if (priv->type < CPU_TSS_BIT)
+	if (priv->type < CPU_TSS)
 		return write_msr(priv, val);
 
 	return ret;
@@ -525,12 +917,12 @@ static const struct file_operations cpu_fops = {
 };
 
 static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
-			   unsigned file, struct dentry *dentry)
+			   unsigned file, unsigned cat, struct dentry *dentry)
 {
 	struct cpu_private *priv = NULL;
 
 	/* Already intialized */
-	if (file == CPU_INDEX_BIT)
+	if (file == CPU_INDEX)
 		if (per_cpu(cpu_arr[type].init, cpu))
 			return 0;
 
@@ -542,6 +934,7 @@ static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
 	priv->type = type;
 	priv->reg = reg;
 	priv->file = file;
+	priv->cat = cat;
 	mutex_lock(&cpu_debug_lock);
 	per_cpu(priv_arr[type], cpu) = priv;
 	per_cpu(cpu_priv_count, cpu)++;
@@ -551,7 +944,7 @@ static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
 		debugfs_create_file(cpu_file[file].name, S_IRUGO,
 				    dentry, (void *)priv, &cpu_fops);
 	else {
-		debugfs_create_file(cpu_base[type].name, S_IRUGO,
+		debugfs_create_file(cpu_file[file].name, S_IRUGO,
 				    per_cpu(cpu_arr[type].dentry, cpu),
 				    (void *)priv, &cpu_fops);
 		mutex_lock(&cpu_debug_lock);
@@ -563,13 +956,13 @@ static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
 }
 
 static int cpu_init_regfiles(unsigned cpu, unsigned int type, unsigned reg,
-			     struct dentry *dentry)
+			     unsigned cat, struct dentry *dentry)
 {
 	unsigned file;
 	int err = 0;
 
-	for (file = 0; file <  ARRAY_SIZE(cpu_file); file++) {
-		err = cpu_create_file(cpu, type, reg, file, dentry);
+	for (file = 0; file < ARRAY_SIZE(cpu_file); file++) {
+		err = cpu_create_file(cpu, type, reg, file, cat, dentry);
 		if (err)
 			return err;
 	}
@@ -585,8 +978,8 @@ static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry)
 	char reg_dir[12];
 	u32 low, high;
 
-	for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
-		if (!get_cpu_range(cpu, &reg_min, &reg_max, i,
+	for (i = 0; i < ARRAY_SIZE(cpu_msr_range); i++) {
+		if (!get_msr_range(cpu, &reg_min, &reg_max, i,
 				   cpu_base[type].flag))
 			continue;
 
@@ -594,9 +987,10 @@ static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry)
 			if (rdmsr_safe_on_cpu(cpu, reg, &low, &high))
 				continue;
 
-			sprintf(reg_dir, "0x%x", reg);
+			sprintf(reg_dir, "MSR_%x", reg);
 			cpu_dentry = debugfs_create_dir(reg_dir, dentry);
-			err = cpu_init_regfiles(cpu, type, reg, cpu_dentry);
+			err = cpu_init_regfiles(cpu, type, reg, CPU_REG_MSR,
+						cpu_dentry);
 			if (err)
 				return err;
 		}
@@ -605,23 +999,144 @@ static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry)
 	return err;
 }
 
+static void cpu_init_apic(unsigned cpu, struct dentry *dentry)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	struct dentry *cpu_dentry;
+	char reg_dir[16];
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(cpu_apic); i++) {
+		sprintf(reg_dir, "APIC_%s", cpu_apic[i].name);
+		cpu_dentry = debugfs_create_dir(reg_dir, dentry);
+		cpu_create_file(cpu, CPU_APIC, cpu_apic[i].flag, CPU_VALUE,
+				CPU_REG_APIC, cpu_dentry);
+	}
+
+	if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
+		unsigned int maxeilvt;
+
+		for (i = 0; i < ARRAY_SIZE(cpu_xapic); i++) {
+			sprintf(reg_dir, "APIC_%s", cpu_xapic[i].name);
+			cpu_dentry = debugfs_create_dir(reg_dir, dentry);
+			cpu_create_file(cpu, CPU_APIC, cpu_xapic[i].flag,
+					CPU_VALUE, CPU_REG_APIC, cpu_dentry);
+		}
+
+		maxeilvt = (apic_read(APIC_EFEAT) >> 16) & 0xff;
+		for (i = 0; i < maxeilvt; i++) {
+			sprintf(reg_dir, "APIC_EILVT%d", i);
+			cpu_dentry = debugfs_create_dir(reg_dir, dentry);
+			cpu_create_file(cpu, CPU_APIC, APIC_EILVTn(i),
+					CPU_VALUE, CPU_REG_APIC, cpu_dentry);
+		}
+	}
+#endif
+}
+
+#define INIT_AMD_PCI(func) \
+static void init_amd_pci##func(unsigned cpu, struct dentry *dentry, 	\
+				struct pci_dev *dev)			\
+{									\
+	struct dentry *cdentry;						\
+	unsigned int reg, i, id;					\
+	char reg_dir[10];						\
+	u32 data;							\
+									\
+	for (i = 0; i < ARRAY_SIZE(cpu_amd_pci##func); i++) {		\
+		for (reg = cpu_amd_pci##func[i].min;			\
+		     reg <= cpu_amd_pci##func[i].max; reg++) {		\
+			if (!pci_read_config_dword(dev, reg, &data)) {	\
+				sprintf(reg_dir, "PCI%d_%03x",		\
+					func, reg);			\
+				id = cpu_amd_pci##func[i].flag;		\
+				cdentry = debugfs_create_dir(reg_dir,	\
+					per_cpu(cpu_arr[id].dentry, cpu)); \
+				cpu_create_file(cpu, 			\
+						cpu_amd_pci##func[i].flag, \
+						(func << 16) | reg,	\
+						CPU_VALUE, CPU_REG_PCI, \
+						cdentry);		\
+			}						\
+		}							\
+	}								\
+}
+
+/* AMD supports five functions, 0 through 4 */
+INIT_AMD_PCI(0)
+INIT_AMD_PCI(1)
+INIT_AMD_PCI(2)
+INIT_AMD_PCI(3)
+INIT_AMD_PCI(4)
+
+static void init_amd_pci(unsigned cpu, struct dentry *dentry)
+{
+	struct pci_dev *dev = NULL;
+	unsigned int func;
+
+	while ((dev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_ANY_ID, dev))
+	       != NULL) {
+		if ((dev->device >= 0x1100) && (dev->device < 0x2000)) {
+			func = dev->device & 0xff;
+			if (func >= MAX_CPU_PCI)
+				continue;
+
+			per_cpu(pci_arr[func], cpu) = dev;
+			switch (func) {
+			case 0:
+				init_amd_pci0(cpu, dentry, dev);
+				break;
+			case 1:
+				init_amd_pci1(cpu, dentry, dev);
+				break;
+			case 2:
+				init_amd_pci2(cpu, dentry, dev);
+				break;
+			case 3:
+				init_amd_pci3(cpu, dentry, dev);
+				break;
+			case 4:
+				init_amd_pci4(cpu, dentry, dev);
+				break;
+			}
+		}
+	}
+}
+
+static void cpu_init_pci(unsigned cpu, struct dentry *dentry)
+{
+	switch (boot_cpu_data.x86_vendor) {
+	case X86_VENDOR_AMD:
+		init_amd_pci(cpu, dentry);
+		break;
+	default:
+		return;
+	}
+}
+
 static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
 {
 	struct dentry *cpu_dentry = NULL;
 	unsigned type;
 	int err = 0;
 
-	for (type = 0; type <  ARRAY_SIZE(cpu_base) - 1; type++) {
-		if (!is_typeflag_valid(cpu, cpu_base[type].flag))
-			continue;
+	for (type = 0; type < ARRAY_SIZE(cpu_base) - 1; type++) {
 		cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry);
 		per_cpu(cpu_arr[type].dentry, cpu) = cpu_dentry;
 
-		if (type < CPU_TSS_BIT)
+		/* check before preparing "state" file */
+		if (!is_typeflag_valid(cpu, cpu_base[type].flag))
+			continue;
+
+		if (type == CPU_APIC)
+			cpu_init_apic(cpu, cpu_dentry);
+		if (type == CPU_PCI)
+			cpu_init_pci(cpu, cpu_dentry);
+		if (type < CPU_TSS)
 			err = cpu_init_msr(cpu, type, cpu_dentry);
 		else
-			err = cpu_create_file(cpu, type, 0, CPU_INDEX_BIT,
-					      cpu_dentry);
+			err = cpu_create_file(cpu, type, 0, CPU_INDEX,
+					      CPU_REG_STD, cpu_dentry);
 		if (err)
 			return err;
 	}
@@ -649,8 +1164,8 @@ static int cpu_init_cpu(void)
 		pr_info("cpu%d(%d) debug files %d\n",
 			cpu, nr_cpu_ids, per_cpu(cpu_priv_count, cpu));
 		if (per_cpu(cpu_priv_count, cpu) > MAX_CPU_FILES) {
-			pr_err("Register files count %d exceeds limit %d\n",
-				per_cpu(cpu_priv_count, cpu), MAX_CPU_FILES);
+			WARN_ONCE(1, "debug files count %d exceeds limit %d\n",
+				  per_cpu(cpu_priv_count, cpu), MAX_CPU_FILES);
 			per_cpu(cpu_priv_count, cpu) = MAX_CPU_FILES;
 			err = -ENFILE;
 		}
@@ -683,6 +1198,6 @@ static void __exit cpu_debug_exit(void)
 module_init(cpu_debug_init);
 module_exit(cpu_debug_exit);
 
-MODULE_AUTHOR("Jaswinder Singh Rajput");
+MODULE_AUTHOR("Jaswinder Singh Rajput <jaswinder@kernel.org>");
 MODULE_DESCRIPTION("CPU Debug module");
 MODULE_LICENSE("GPL");



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH 1/10 -tip] x86: cpu_debug update Kconfig entry
  2009-06-13 16:27 [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613 Jaswinder Singh Rajput
@ 2009-06-13 16:28 ` Jaswinder Singh Rajput
  2009-06-13 16:29   ` [RFC][PATCH 2/10 -tip] x86: cpu_debug.c remove some not required header files Jaswinder Singh Rajput
  2009-06-13 22:27 ` [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613 Thomas Gleixner
  1 sibling, 1 reply; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 16:28 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: H. Peter Anvin, x86 maintainers, Andreas Herrmann, Andrew Morton,
	Andi Kleen, LKML, Yinghai Lu, Dave Jones, Linus Torvalds,
	Thomas Gleixner, Robert Richter


cpu_debug needs DEBUG_FS.

Explain basic info to use cpu_debug.

Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
---
 arch/x86/Kconfig |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 0c2321d..e5e26b3 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -994,9 +994,19 @@ config X86_CPUID
 
 config X86_CPU_DEBUG
 	tristate "/sys/kernel/debug/x86/cpu/* - CPU Debug support"
+	select DEBUG_FS
 	---help---
 	  If you select this option, this will provide various x86 CPUs
-	  information through debugfs.
+	  information through debugfs. Any user can read these file but writing
+	  needs root privilege.
+
+	  Note: 1. If you compile cpu_debug as a module, it will _not_ be loaded
+	  automatically (like usual drivers). You will need to load it manually
+	  (or add it to list of modules loaded during boot).
+
+	  2. You need debugfs, if you want to mount debugfs automatically
+	  append this line in /etc/fstab:
+	  debugfs	/sys/kernel/debug	debugfs	defaults	0 0
 
 choice
 	prompt "High Memory Support"
-- 
1.6.0.6




^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH 2/10 -tip] x86: cpu_debug.c remove some not required header files
  2009-06-13 16:28 ` [RFC][PATCH 1/10 -tip] x86: cpu_debug update Kconfig entry Jaswinder Singh Rajput
@ 2009-06-13 16:29   ` Jaswinder Singh Rajput
  2009-06-13 16:30     ` [RFC][PATCH 3/10 -tip] x86: cpu_debug.c use a WARN_ONCE() instead of a pr_err() Jaswinder Singh Rajput
  0 siblings, 1 reply; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 16:29 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: H. Peter Anvin, x86 maintainers, Andreas Herrmann, Andrew Morton,
	Andi Kleen, LKML, Yinghai Lu, Dave Jones, Linus Torvalds,
	Thomas Gleixner, Robert Richter

remove some not required header files

Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
---
 arch/x86/kernel/cpu/cpu_debug.c |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index 6b2a52d..f7b42d2 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -6,16 +6,12 @@
  * For licencing details see kernel-base/COPYING
  */
 
-#include <linux/interrupt.h>
-#include <linux/compiler.h>
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
-#include <linux/kprobes.h>
 #include <linux/uaccess.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/percpu.h>
-#include <linux/signal.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/types.h>
@@ -26,7 +22,6 @@
 #include <asm/cpu_debug.h>
 #include <asm/paravirt.h>
 #include <asm/system.h>
-#include <asm/traps.h>
 #include <asm/apic.h>
 #include <asm/desc.h>
 
-- 
1.6.0.6




^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH 3/10 -tip] x86: cpu_debug.c use a WARN_ONCE() instead of a pr_err()
  2009-06-13 16:29   ` [RFC][PATCH 2/10 -tip] x86: cpu_debug.c remove some not required header files Jaswinder Singh Rajput
@ 2009-06-13 16:30     ` Jaswinder Singh Rajput
  2009-06-13 16:30       ` [RFC][PATCH 4/10 -tip] x86: cpu_debug make room to support more categories Jaswinder Singh Rajput
  0 siblings, 1 reply; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 16:30 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: H. Peter Anvin, x86 maintainers, Andreas Herrmann, Andrew Morton,
	Andi Kleen, LKML, Yinghai Lu, Dave Jones, Linus Torvalds,
	Thomas Gleixner, Robert Richter


Use a WARN_ONCE() instead of a pr_err(). Hitting this is a
bug we want to fix.

Also added email address.

Reported-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
---
 arch/x86/kernel/cpu/cpu_debug.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index f7b42d2..3aa3596 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -644,8 +644,8 @@ static int cpu_init_cpu(void)
 		pr_info("cpu%d(%d) debug files %d\n",
 			cpu, nr_cpu_ids, per_cpu(cpu_priv_count, cpu));
 		if (per_cpu(cpu_priv_count, cpu) > MAX_CPU_FILES) {
-			pr_err("Register files count %d exceeds limit %d\n",
-				per_cpu(cpu_priv_count, cpu), MAX_CPU_FILES);
+			WARN_ONCE(1, "debug files count %d exceeds limit %d\n",
+				  per_cpu(cpu_priv_count, cpu), MAX_CPU_FILES);
 			per_cpu(cpu_priv_count, cpu) = MAX_CPU_FILES;
 			err = -ENFILE;
 		}
@@ -678,6 +678,6 @@ static void __exit cpu_debug_exit(void)
 module_init(cpu_debug_init);
 module_exit(cpu_debug_exit);
 
-MODULE_AUTHOR("Jaswinder Singh Rajput");
+MODULE_AUTHOR("Jaswinder Singh Rajput <jaswinder@kernel.org>");
 MODULE_DESCRIPTION("CPU Debug module");
 MODULE_LICENSE("GPL");
-- 
1.6.0.6




^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH 4/10 -tip] x86: cpu_debug make room to support more categories
  2009-06-13 16:30     ` [RFC][PATCH 3/10 -tip] x86: cpu_debug.c use a WARN_ONCE() instead of a pr_err() Jaswinder Singh Rajput
@ 2009-06-13 16:30       ` Jaswinder Singh Rajput
  2009-06-13 16:31         ` [RFC][PATCH 5/10 -tip] x86: cpu_debug update MSR list to support new architectures Jaswinder Singh Rajput
  0 siblings, 1 reply; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 16:30 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: H. Peter Anvin, x86 maintainers, Andreas Herrmann, Andrew Morton,
	Andi Kleen, LKML, Yinghai Lu, Dave Jones, Linus Torvalds,
	Thomas Gleixner, Robert Richter


Earlier cpu_debug categories was stored in bitwise fashion and
we reached the limit of 0-31.

So now storing the categories based on count so that we can add more.

Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
---
 arch/x86/include/asm/cpu_debug.h |  102 +++++++++++++-------------------------
 arch/x86/kernel/cpu/cpu_debug.c  |   14 +++---
 2 files changed, 41 insertions(+), 75 deletions(-)

diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
index d96c1ee..da5c221 100644
--- a/arch/x86/include/asm/cpu_debug.h
+++ b/arch/x86/include/asm/cpu_debug.h
@@ -10,84 +10,50 @@
 /* Register flags */
 enum cpu_debug_bit {
 /* Model Specific Registers (MSRs)					*/
-	CPU_MC_BIT,				/* Machine Check	*/
-	CPU_MONITOR_BIT,			/* Monitor		*/
-	CPU_TIME_BIT,				/* Time			*/
-	CPU_PMC_BIT,				/* Performance Monitor	*/
-	CPU_PLATFORM_BIT,			/* Platform		*/
-	CPU_APIC_BIT,				/* APIC			*/
-	CPU_POWERON_BIT,			/* Power-on		*/
-	CPU_CONTROL_BIT,			/* Control		*/
-	CPU_FEATURES_BIT,			/* Features control	*/
-	CPU_LBRANCH_BIT,			/* Last Branch		*/
-	CPU_BIOS_BIT,				/* BIOS			*/
-	CPU_FREQ_BIT,				/* Frequency		*/
-	CPU_MTTR_BIT,				/* MTRR			*/
-	CPU_PERF_BIT,				/* Performance		*/
-	CPU_CACHE_BIT,				/* Cache		*/
-	CPU_SYSENTER_BIT,			/* Sysenter		*/
-	CPU_THERM_BIT,				/* Thermal		*/
-	CPU_MISC_BIT,				/* Miscellaneous	*/
-	CPU_DEBUG_BIT,				/* Debug		*/
-	CPU_PAT_BIT,				/* PAT			*/
-	CPU_VMX_BIT,				/* VMX			*/
-	CPU_CALL_BIT,				/* System Call		*/
-	CPU_BASE_BIT,				/* BASE Address		*/
-	CPU_VER_BIT,				/* Version ID		*/
-	CPU_CONF_BIT,				/* Configuration	*/
-	CPU_SMM_BIT,				/* System mgmt mode	*/
-	CPU_SVM_BIT,				/*Secure Virtual Machine*/
-	CPU_OSVM_BIT,				/* OS-Visible Workaround*/
+	CPU_MC,					/* Machine Check	*/
+	CPU_MONITOR,				/* Monitor		*/
+	CPU_TIME,				/* Time			*/
+	CPU_PMC,				/* Performance Monitor	*/
+	CPU_PLATFORM,				/* Platform		*/
+	CPU_APIC,				/* APIC			*/
+	CPU_POWERON,				/* Power-on		*/
+	CPU_CONTROL,				/* Control		*/
+	CPU_FEATURES,				/* Features control	*/
+	CPU_LBRANCH,				/* Last Branch		*/
+	CPU_BIOS,				/* BIOS			*/
+	CPU_FREQ,				/* Frequency		*/
+	CPU_MTRR,				/* MTRR			*/
+	CPU_PERF,				/* Performance		*/
+	CPU_CACHE,				/* Cache		*/
+	CPU_SYSENTER,				/* Sysenter		*/
+	CPU_THERM,				/* Thermal		*/
+	CPU_MISC,				/* Miscellaneous	*/
+	CPU_DEBUG,				/* Debug		*/
+	CPU_PAT,				/* PAT			*/
+	CPU_VMX,				/* VMX			*/
+	CPU_CALL,				/* System Call		*/
+	CPU_BASE,				/* BASE Address		*/
+	CPU_VER,				/* Version ID		*/
+	CPU_CONF,				/* Configuration	*/
+	CPU_SMM,				/* System mgmt mode	*/
+	CPU_SVM,				/*Secure Virtual Machine*/
+	CPU_OSVM,				/* OS-Visible Workaround*/
 /* Standard Registers							*/
-	CPU_TSS_BIT,				/* Task Stack Segment	*/
-	CPU_CR_BIT,				/* Control Registers	*/
-	CPU_DT_BIT,				/* Descriptor Table	*/
+	CPU_TSS,				/* Task Stack Segment	*/
+	CPU_CR,					/* Control Registers	*/
+	CPU_DT,					/* Descriptor Table	*/
 /* End of Registers flags						*/
-	CPU_REG_ALL_BIT,			/* Select all Registers	*/
+	CPU_REG_MAX,				/* Max Registers flags	*/
 };
 
 #define	CPU_REG_ALL		(~0)		/* Select all Registers	*/
 
-#define	CPU_MC			(1 << CPU_MC_BIT)
-#define	CPU_MONITOR		(1 << CPU_MONITOR_BIT)
-#define	CPU_TIME		(1 << CPU_TIME_BIT)
-#define	CPU_PMC			(1 << CPU_PMC_BIT)
-#define	CPU_PLATFORM		(1 << CPU_PLATFORM_BIT)
-#define	CPU_APIC		(1 << CPU_APIC_BIT)
-#define	CPU_POWERON		(1 << CPU_POWERON_BIT)
-#define	CPU_CONTROL		(1 << CPU_CONTROL_BIT)
-#define	CPU_FEATURES		(1 << CPU_FEATURES_BIT)
-#define	CPU_LBRANCH		(1 << CPU_LBRANCH_BIT)
-#define	CPU_BIOS		(1 << CPU_BIOS_BIT)
-#define	CPU_FREQ		(1 << CPU_FREQ_BIT)
-#define	CPU_MTRR		(1 << CPU_MTTR_BIT)
-#define	CPU_PERF		(1 << CPU_PERF_BIT)
-#define	CPU_CACHE		(1 << CPU_CACHE_BIT)
-#define	CPU_SYSENTER		(1 << CPU_SYSENTER_BIT)
-#define	CPU_THERM		(1 << CPU_THERM_BIT)
-#define	CPU_MISC		(1 << CPU_MISC_BIT)
-#define	CPU_DEBUG		(1 << CPU_DEBUG_BIT)
-#define	CPU_PAT			(1 << CPU_PAT_BIT)
-#define	CPU_VMX			(1 << CPU_VMX_BIT)
-#define	CPU_CALL		(1 << CPU_CALL_BIT)
-#define	CPU_BASE		(1 << CPU_BASE_BIT)
-#define	CPU_VER			(1 << CPU_VER_BIT)
-#define	CPU_CONF		(1 << CPU_CONF_BIT)
-#define	CPU_SMM			(1 << CPU_SMM_BIT)
-#define	CPU_SVM			(1 << CPU_SVM_BIT)
-#define	CPU_OSVM		(1 << CPU_OSVM_BIT)
-#define	CPU_TSS			(1 << CPU_TSS_BIT)
-#define	CPU_CR			(1 << CPU_CR_BIT)
-#define	CPU_DT			(1 << CPU_DT_BIT)
-
 /* Register file flags */
 enum cpu_file_bit {
-	CPU_INDEX_BIT,				/* index		*/
-	CPU_VALUE_BIT,				/* value		*/
+	CPU_INDEX,				/* index		*/
+	CPU_VALUE,				/* value		*/
 };
 
-#define	CPU_FILE_VALUE		(1 << CPU_VALUE_BIT)
-
 #define MAX_CPU_FILES		512
 
 struct cpu_private {
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index 3aa3596..5c45c52 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -25,7 +25,7 @@
 #include <asm/apic.h>
 #include <asm/desc.h>
 
-static DEFINE_PER_CPU(struct cpu_cpuX_base, cpu_arr[CPU_REG_ALL_BIT]);
+static DEFINE_PER_CPU(struct cpu_cpuX_base, cpu_arr[CPU_REG_MAX]);
 static DEFINE_PER_CPU(struct cpu_private *, priv_arr[MAX_CPU_FILES]);
 static DEFINE_PER_CPU(int, cpu_priv_count);
 
@@ -399,12 +399,12 @@ static int cpu_seq_show(struct seq_file *seq, void *v)
 		smp_call_function_single(priv->cpu, print_dt, seq, 1);
 		break;
 	case CPU_DEBUG:
-		if (priv->file == CPU_INDEX_BIT)
+		if (priv->file == CPU_INDEX)
 			smp_call_function_single(priv->cpu, print_dr, seq, 1);
 		print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
 		break;
 	case CPU_APIC:
-		if (priv->file == CPU_INDEX_BIT)
+		if (priv->file == CPU_INDEX)
 			smp_call_function_single(priv->cpu, print_apic, seq, 1);
 		print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
 		break;
@@ -482,7 +482,7 @@ static int write_cpu_register(struct cpu_private *priv, const char *buf)
 		return ret;
 
 	/* Supporting only MSRs */
-	if (priv->type < CPU_TSS_BIT)
+	if (priv->type < CPU_TSS)
 		return write_msr(priv, val);
 
 	return ret;
@@ -525,7 +525,7 @@ static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
 	struct cpu_private *priv = NULL;
 
 	/* Already intialized */
-	if (file == CPU_INDEX_BIT)
+	if (file == CPU_INDEX)
 		if (per_cpu(cpu_arr[type].init, cpu))
 			return 0;
 
@@ -612,10 +612,10 @@ static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
 		cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry);
 		per_cpu(cpu_arr[type].dentry, cpu) = cpu_dentry;
 
-		if (type < CPU_TSS_BIT)
+		if (type < CPU_TSS)
 			err = cpu_init_msr(cpu, type, cpu_dentry);
 		else
-			err = cpu_create_file(cpu, type, 0, CPU_INDEX_BIT,
+			err = cpu_create_file(cpu, type, 0, CPU_INDEX,
 					      cpu_dentry);
 		if (err)
 			return err;
-- 
1.6.0.6




^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH 5/10 -tip] x86: cpu_debug update MSR list to support new architectures
  2009-06-13 16:30       ` [RFC][PATCH 4/10 -tip] x86: cpu_debug make room to support more categories Jaswinder Singh Rajput
@ 2009-06-13 16:31         ` Jaswinder Singh Rajput
  2009-06-13 16:32           ` [RFC][PATCH 6/10 -tip] x86: cpu_debug make room for more cpu registers Jaswinder Singh Rajput
  0 siblings, 1 reply; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 16:31 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: H. Peter Anvin, x86 maintainers, Andreas Herrmann, Andrew Morton,
	Andi Kleen, LKML, Yinghai Lu, Dave Jones, Linus Torvalds,
	Thomas Gleixner, Robert Richter


Added support for Intel Xeon MP 7400 series :

Intel Xeon MP 7400 series falls in Intel Core microarchitecture.
Intel Xeon MP 7400 series supports additional:
 0x419, 0x107CC-0x107D3 and 0x107D8

Added support for Intel Core i7, Xeon Processor 5500 series (Nehalem)

Added some extra registers for AMD Family 10h Processor

Also fixed some minor range issues.

Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
---
 arch/x86/include/asm/cpu_debug.h |    3 +++
 arch/x86/kernel/cpu/cpu_debug.c  |   36 +++++++++++++++++++++++++++---------
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
index da5c221..f2adad3 100644
--- a/arch/x86/include/asm/cpu_debug.h
+++ b/arch/x86/include/asm/cpu_debug.h
@@ -36,6 +36,9 @@ enum cpu_debug_bit {
 	CPU_VER,				/* Version ID		*/
 	CPU_CONF,				/* Configuration	*/
 	CPU_SMM,				/* System mgmt mode	*/
+	CPU_POWER,				/* Power mgmt		*/
+	CPU_PNAME,				/* Processor name	*/
+	CPU_IBS,				/* IBS			*/
 	CPU_SVM,				/*Secure Virtual Machine*/
 	CPU_OSVM,				/* OS-Visible Workaround*/
 /* Standard Registers							*/
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index 5c45c52..9435da4 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -60,6 +60,9 @@ static struct cpu_debug_base cpu_base[] = {
 	{ "ver",	CPU_VER,	0	},
 	{ "conf",	CPU_CONF,	0	},
 	{ "smm",	CPU_SMM,	0	},
+	{ "power",	CPU_POWER,	0	},
+	{ "pname",	CPU_PNAME,	0	},
+	{ "ibs",	CPU_IBS,	0	},
 	{ "svm",	CPU_SVM,	0	},
 	{ "osvm",	CPU_OSVM,	0	},
 	{ "tss",	CPU_TSS,	0	},
@@ -90,6 +93,7 @@ static struct cpu_debug_range cpu_reg_range[] = {
 	{ 0x00000088, 0x0000008A, CPU_CACHE,	},
 	{ 0x0000008B, 0x0000008B, CPU_BIOS,	},
 	{ 0x0000009B, 0x0000009B, CPU_MONITOR,	},
+	{ 0x000000A0, 0x000000A1, CPU_SMM,	},
 	{ 0x000000C1, 0x000000C4, CPU_PMC,	},
 	{ 0x000000CD, 0x000000CD, CPU_FREQ,	},
 	{ 0x000000E7, 0x000000E8, CPU_PERF,	},
@@ -98,40 +102,49 @@ static struct cpu_debug_range cpu_reg_range[] = {
 	{ 0x00000116, 0x0000011E, CPU_CACHE,	},
 	{ 0x00000174, 0x00000176, CPU_SYSENTER,	},
 	{ 0x00000179, 0x0000017B, CPU_MC,	},
+	{ 0x00000180, 0x00000185, CPU_MC,	},
 	{ 0x00000186, 0x00000189, CPU_PMC,	},
 	{ 0x00000198, 0x00000199, CPU_PERF,	},
 	{ 0x0000019A, 0x0000019A, CPU_TIME,	},
 	{ 0x0000019B, 0x0000019D, CPU_THERM,	},
 	{ 0x000001A0, 0x000001A0, CPU_MISC,	},
-	{ 0x000001C9, 0x000001C9, CPU_LBRANCH,	},
+	{ 0x000001A1, 0x000001A1, CPU_PLATFORM,	},
+	{ 0x000001A2, 0x000001A2, CPU_THERM,	},
+	{ 0x000001A6, 0x000001A6, CPU_PMC,	},
+	{ 0x000001AD, 0x000001AD, CPU_FREQ,	},
+	{ 0x000001C8, 0x000001C9, CPU_LBRANCH,	},
 	{ 0x000001D7, 0x000001D8, CPU_LBRANCH,	},
 	{ 0x000001D9, 0x000001D9, CPU_DEBUG,	},
 	{ 0x000001DA, 0x000001E0, CPU_LBRANCH,	},
+	{ 0x000001F2, 0x000001F3, CPU_SMM,	},
 
 	{ 0x00000200, 0x0000020F, CPU_MTRR,	},
 	{ 0x00000250, 0x00000250, CPU_MTRR,	},
 	{ 0x00000258, 0x00000259, CPU_MTRR,	},
 	{ 0x00000268, 0x0000026F, CPU_MTRR,	},
 	{ 0x00000277, 0x00000277, CPU_PAT,	},
+	{ 0x00000280, 0x00000288, CPU_MC,	},
 	{ 0x000002FF, 0x000002FF, CPU_MTRR,	},
 
 	{ 0x00000300, 0x00000311, CPU_PMC,	},
 	{ 0x00000345, 0x00000345, CPU_PMC,	},
 	{ 0x00000360, 0x00000371, CPU_PMC,	},
-	{ 0x0000038D, 0x00000390, CPU_PMC,	},
+	{ 0x0000038D, 0x00000396, CPU_PMC,	},
 	{ 0x000003A0, 0x000003BE, CPU_PMC,	},
 	{ 0x000003C0, 0x000003CD, CPU_PMC,	},
 	{ 0x000003E0, 0x000003E1, CPU_PMC,	},
-	{ 0x000003F0, 0x000003F2, CPU_PMC,	},
+	{ 0x000003F0, 0x000003FD, CPU_PMC,	},
 
-	{ 0x00000400, 0x00000417, CPU_MC,	},
+	{ 0x00000400, 0x00000421, CPU_MC,	},
 	{ 0x00000480, 0x0000048B, CPU_VMX,	},
 
 	{ 0x00000600, 0x00000600, CPU_DEBUG,	},
 	{ 0x00000680, 0x0000068F, CPU_LBRANCH,	},
 	{ 0x000006C0, 0x000006CF, CPU_LBRANCH,	},
 
-	{ 0x000107CC, 0x000107D3, CPU_PMC,	},
+	{ 0x00000800, 0x0000083F, CPU_APIC,	},
+
+	{ 0x000107CC, 0x000107D8, CPU_PMC,	},
 
 	{ 0xC0000080, 0xC0000080, CPU_FEATURES,	},
 	{ 0xC0000081, 0xC0000084, CPU_CALL,	},
@@ -144,18 +157,23 @@ static struct cpu_debug_range cpu_reg_range[] = {
 	{ 0xC0010016, 0xC001001A, CPU_MTRR,	},
 	{ 0xC001001D, 0xC001001D, CPU_MTRR,	},
 	{ 0xC001001F, 0xC001001F, CPU_CONF,	},
-	{ 0xC0010030, 0xC0010035, CPU_BIOS,	},
-	{ 0xC0010044, 0xC0010048, CPU_MC,	},
+	{ 0xC0010022, 0xC0010022, CPU_MC,	},
+	{ 0xC0010030, 0xC0010035, CPU_PNAME,	},
+	{ 0xC0010044, 0xC0010049, CPU_MC,	},
 	{ 0xC0010050, 0xC0010056, CPU_SMM,	},
 	{ 0xC0010058, 0xC0010058, CPU_CONF,	},
 	{ 0xC0010060, 0xC0010060, CPU_CACHE,	},
-	{ 0xC0010061, 0xC0010068, CPU_SMM,	},
-	{ 0xC0010069, 0xC001006B, CPU_SMM,	},
+	{ 0xC0010061, 0xC001006B, CPU_POWER,	},
 	{ 0xC0010070, 0xC0010071, CPU_SMM,	},
+	{ 0xC0010074, 0xC0010074, CPU_TIME,	},
 	{ 0xC0010111, 0xC0010113, CPU_SMM,	},
 	{ 0xC0010114, 0xC0010118, CPU_SVM,	},
 	{ 0xC0010140, 0xC0010141, CPU_OSVM,	},
+
+	{ 0xC0011004, 0xC0011005, CPU_FEATURES,	},
 	{ 0xC0011022, 0xC0011023, CPU_CONF,	},
+	{ 0xC001102A, 0xC001102A, CPU_CONF,	},
+	{ 0xC0011030, 0xC001103A, CPU_IBS,	},
 };
 
 static int is_typeflag_valid(unsigned cpu, unsigned flag)
-- 
1.6.0.6




^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH 6/10 -tip] x86: cpu_debug make room for more cpu registers
  2009-06-13 16:31         ` [RFC][PATCH 5/10 -tip] x86: cpu_debug update MSR list to support new architectures Jaswinder Singh Rajput
@ 2009-06-13 16:32           ` Jaswinder Singh Rajput
  2009-06-13 16:33             ` [RFC][PATCH 7/10 -tip] x86: cpu_debug support APIC_register_name with directory structure Jaswinder Singh Rajput
  0 siblings, 1 reply; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 16:32 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: H. Peter Anvin, x86 maintainers, Andreas Herrmann, Andrew Morton,
	Andi Kleen, LKML, Yinghai Lu, Dave Jones, Linus Torvalds,
	Thomas Gleixner, Robert Richter


Added Register category flags and define MSR_ for MSRs so that
we can add more cpu registers and distguish between them.

using name "state" do describe the state

Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
---
 arch/x86/include/asm/cpu_debug.h |    7 ++++
 arch/x86/kernel/cpu/cpu_debug.c  |   59 ++++++++++++++++++++++----------------
 2 files changed, 41 insertions(+), 25 deletions(-)

diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
index f2adad3..79710f2 100644
--- a/arch/x86/include/asm/cpu_debug.h
+++ b/arch/x86/include/asm/cpu_debug.h
@@ -57,6 +57,12 @@ enum cpu_file_bit {
 	CPU_VALUE,				/* value		*/
 };
 
+/* Register category flags */
+enum cpu_cat_bit {
+	CPU_REG_STD,				/* Standard registers	*/
+	CPU_REG_MSR,				/* MSRs			*/
+};
+
 #define MAX_CPU_FILES		512
 
 struct cpu_private {
@@ -64,6 +70,7 @@ struct cpu_private {
 	unsigned		type;
 	unsigned		reg;
 	unsigned		file;
+	unsigned		cat;
 };
 
 struct cpu_debug_base {
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index 9435da4..b03245e 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -72,12 +72,12 @@ static struct cpu_debug_base cpu_base[] = {
 };
 
 static struct cpu_file_base cpu_file[] = {
-	{ "index",	CPU_REG_ALL,	0	},
+	{ "state",	CPU_REG_ALL,	0	},
 	{ "value",	CPU_REG_ALL,	1	},
 };
 
 /* CPU Registers Range */
-static struct cpu_debug_range cpu_reg_range[] = {
+static struct cpu_debug_range cpu_msr_range[] = {
 	{ 0x00000000, 0x00000001, CPU_MC,	},
 	{ 0x00000006, 0x00000007, CPU_MONITOR,	},
 	{ 0x00000010, 0x00000010, CPU_TIME,	},
@@ -176,6 +176,7 @@ static struct cpu_debug_range cpu_reg_range[] = {
 	{ 0xC0011030, 0xC001103A, CPU_IBS,	},
 };
 
+/* Check validity of cpu debug flag */
 static int is_typeflag_valid(unsigned cpu, unsigned flag)
 {
 	int i;
@@ -184,8 +185,9 @@ static int is_typeflag_valid(unsigned cpu, unsigned flag)
 	if (flag >= CPU_TSS)
 		return 1;
 
-	for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
-		if (cpu_reg_range[i].flag == flag)
+	/* check MSR range */
+	for (i = 0; i < ARRAY_SIZE(cpu_msr_range); i++) {
+		if (cpu_msr_range[i].flag == flag)
 			return 1;
 	}
 
@@ -193,12 +195,13 @@ static int is_typeflag_valid(unsigned cpu, unsigned flag)
 	return 0;
 }
 
-static unsigned get_cpu_range(unsigned cpu, unsigned *min, unsigned *max,
+/* get MSR range */
+static unsigned get_msr_range(unsigned cpu, unsigned *min, unsigned *max,
 			      int index, unsigned flag)
 {
-	if (cpu_reg_range[index].flag == flag) {
-		*min = cpu_reg_range[index].min;
-		*max = cpu_reg_range[index].max;
+	if (cpu_msr_range[index].flag == flag) {
+		*min = cpu_msr_range[index].min;
+		*max = cpu_msr_range[index].max;
 	} else
 		*max = 0;
 
@@ -239,11 +242,12 @@ static void print_msr(struct seq_file *seq, unsigned cpu, unsigned flag)
 					       &low, &high))
 				print_cpu_data(seq, priv->reg, low, high);
 			return;
-		}
+		} else
+			seq_printf(seq, " MSR\t:\n");
 	}
 
-	for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
-		if (!get_cpu_range(cpu, &msr_min, &msr_max, i, flag))
+	for (i = 0; i < ARRAY_SIZE(cpu_msr_range); i++) {
+		if (!get_msr_range(cpu, &msr_min, &msr_max, i, flag))
 			continue;
 
 		for (msr = msr_min; msr <= msr_max; msr++) {
@@ -352,7 +356,7 @@ static void print_dr(void *arg)
 		seq_printf(seq, " dr%d\t: %016lx\n", i, dr);
 	}
 
-	seq_printf(seq, "\n MSR\t:\n");
+	seq_printf(seq, "\n");
 }
 
 static void print_apic(void *arg)
@@ -395,8 +399,8 @@ static void print_apic(void *arg)
 			seq_printf(seq, " EILVT%d\t\t: %08x\n", i, v);
 		}
 	}
+	seq_printf(seq, "\n");
 #endif /* CONFIG_X86_LOCAL_APIC */
-	seq_printf(seq, "\n MSR\t:\n");
 }
 
 static int cpu_seq_show(struct seq_file *seq, void *v)
@@ -419,16 +423,19 @@ static int cpu_seq_show(struct seq_file *seq, void *v)
 	case CPU_DEBUG:
 		if (priv->file == CPU_INDEX)
 			smp_call_function_single(priv->cpu, print_dr, seq, 1);
-		print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
+		if (priv->cat == CPU_REG_MSR)
+			print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
 		break;
 	case CPU_APIC:
 		if (priv->file == CPU_INDEX)
 			smp_call_function_single(priv->cpu, print_apic, seq, 1);
-		print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
+		if (priv->cat == CPU_REG_MSR)
+			print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
 		break;
 
 	default:
-		print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
+		if (priv->cat == CPU_REG_MSR)
+			print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
 		break;
 	}
 	seq_printf(seq, "\n");
@@ -538,7 +545,7 @@ static const struct file_operations cpu_fops = {
 };
 
 static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
-			   unsigned file, struct dentry *dentry)
+			   unsigned file, unsigned cat, struct dentry *dentry)
 {
 	struct cpu_private *priv = NULL;
 
@@ -555,6 +562,7 @@ static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
 	priv->type = type;
 	priv->reg = reg;
 	priv->file = file;
+	priv->cat = cat;
 	mutex_lock(&cpu_debug_lock);
 	per_cpu(priv_arr[type], cpu) = priv;
 	per_cpu(cpu_priv_count, cpu)++;
@@ -564,7 +572,7 @@ static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
 		debugfs_create_file(cpu_file[file].name, S_IRUGO,
 				    dentry, (void *)priv, &cpu_fops);
 	else {
-		debugfs_create_file(cpu_base[type].name, S_IRUGO,
+		debugfs_create_file(cpu_file[file].name, S_IRUGO,
 				    per_cpu(cpu_arr[type].dentry, cpu),
 				    (void *)priv, &cpu_fops);
 		mutex_lock(&cpu_debug_lock);
@@ -576,13 +584,13 @@ static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg,
 }
 
 static int cpu_init_regfiles(unsigned cpu, unsigned int type, unsigned reg,
-			     struct dentry *dentry)
+			     unsigned cat, struct dentry *dentry)
 {
 	unsigned file;
 	int err = 0;
 
 	for (file = 0; file <  ARRAY_SIZE(cpu_file); file++) {
-		err = cpu_create_file(cpu, type, reg, file, dentry);
+		err = cpu_create_file(cpu, type, reg, file, cat, dentry);
 		if (err)
 			return err;
 	}
@@ -598,8 +606,8 @@ static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry)
 	char reg_dir[12];
 	u32 low, high;
 
-	for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) {
-		if (!get_cpu_range(cpu, &reg_min, &reg_max, i,
+	for (i = 0; i < ARRAY_SIZE(cpu_msr_range); i++) {
+		if (!get_msr_range(cpu, &reg_min, &reg_max, i,
 				   cpu_base[type].flag))
 			continue;
 
@@ -607,9 +615,10 @@ static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry)
 			if (rdmsr_safe_on_cpu(cpu, reg, &low, &high))
 				continue;
 
-			sprintf(reg_dir, "0x%x", reg);
+			sprintf(reg_dir, "MSR_%x", reg);
 			cpu_dentry = debugfs_create_dir(reg_dir, dentry);
-			err = cpu_init_regfiles(cpu, type, reg, cpu_dentry);
+			err = cpu_init_regfiles(cpu, type, reg, CPU_REG_MSR,
+						cpu_dentry);
 			if (err)
 				return err;
 		}
@@ -634,7 +643,7 @@ static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
 			err = cpu_init_msr(cpu, type, cpu_dentry);
 		else
 			err = cpu_create_file(cpu, type, 0, CPU_INDEX,
-					      cpu_dentry);
+					      CPU_REG_STD, cpu_dentry);
 		if (err)
 			return err;
 	}
-- 
1.6.0.6




^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH 7/10 -tip] x86: cpu_debug support APIC_register_name with directory structure
  2009-06-13 16:32           ` [RFC][PATCH 6/10 -tip] x86: cpu_debug make room for more cpu registers Jaswinder Singh Rajput
@ 2009-06-13 16:33             ` Jaswinder Singh Rajput
  2009-06-13 16:34               ` [RFC][PATCH 8/10 -tip] x86: cpu_debug display PCI configuration registers for AMD Jaswinder Singh Rajput
  0 siblings, 1 reply; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 16:33 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: H. Peter Anvin, x86 maintainers, Andreas Herrmann, Andrew Morton,
	Andi Kleen, LKML, Yinghai Lu, Dave Jones, Linus Torvalds,
	Thomas Gleixner, Robert Richter


Added Register category flags and define APIC_ for APIC registers
so that we can distguish between them.

Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
---
 arch/x86/include/asm/cpu_debug.h |    1 +
 arch/x86/kernel/cpu/cpu_debug.c  |  132 +++++++++++++++++++++++++++++---------
 2 files changed, 102 insertions(+), 31 deletions(-)

diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
index 79710f2..fd20da7 100644
--- a/arch/x86/include/asm/cpu_debug.h
+++ b/arch/x86/include/asm/cpu_debug.h
@@ -61,6 +61,7 @@ enum cpu_file_bit {
 enum cpu_cat_bit {
 	CPU_REG_STD,				/* Standard registers	*/
 	CPU_REG_MSR,				/* MSRs			*/
+	CPU_REG_APIC,				/* APIC registers	*/
 };
 
 #define MAX_CPU_FILES		512
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index b03245e..fcfd22f 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -71,6 +71,37 @@ static struct cpu_debug_base cpu_base[] = {
 	{ "registers",	CPU_REG_ALL,	0	},
 };
 
+#ifdef CONFIG_X86_LOCAL_APIC
+static struct cpu_debug_base cpu_apic[] = {
+	{ "ID",		APIC_ID,	0	},
+	{ "LVR",	APIC_LVR,	0	},
+	{ "TASKPRI",	APIC_TASKPRI,	0	},
+	{ "ARBPRI",	APIC_ARBPRI,	0	},
+	{ "PROCPRI",	APIC_PROCPRI,	0	},
+	{ "LDR",	APIC_LDR,	0	},
+	{ "DFR",	APIC_DFR,	0	},
+	{ "SPIV",	APIC_SPIV,	0	},
+	{ "ISR",	APIC_ISR,	0	},
+	{ "ESR",	APIC_ESR,	0	},
+	{ "ICR",	APIC_ICR,	0	},
+	{ "ICR2",	APIC_ICR2,	0	},
+	{ "LVTT",	APIC_LVTT,	0	},
+	{ "LVTTHMR",	APIC_LVTTHMR,	0	},
+	{ "LVTPC",	APIC_LVTPC,	0	},
+	{ "LVT0",	APIC_LVT0,	0	},
+	{ "LVT1",	APIC_LVT1,	0	},
+	{ "LVTERR",	APIC_LVTERR,	0	},
+	{ "TMICT",	APIC_TMICT,	0	},
+	{ "TMCCT",	APIC_TMCCT,	0	},
+	{ "TDCR",	APIC_TDCR,	0	},
+};
+
+static struct cpu_debug_base cpu_xapic[] = {
+	{ "EFEAT",	APIC_EFEAT,	0	},
+	{ "ECTRL",	APIC_ECTRL,	0	},
+};
+#endif
+
 static struct cpu_file_base cpu_file[] = {
 	{ "state",	CPU_REG_ALL,	0	},
 	{ "value",	CPU_REG_ALL,	1	},
@@ -364,43 +395,42 @@ static void print_apic(void *arg)
 	struct seq_file *seq = arg;
 
 #ifdef CONFIG_X86_LOCAL_APIC
+	unsigned int i;
+
 	seq_printf(seq, " LAPIC\t:\n");
-	seq_printf(seq, " ID\t\t: %08x\n",  apic_read(APIC_ID) >> 24);
-	seq_printf(seq, " LVR\t\t: %08x\n",  apic_read(APIC_LVR));
-	seq_printf(seq, " TASKPRI\t: %08x\n",  apic_read(APIC_TASKPRI));
-	seq_printf(seq, " ARBPRI\t\t: %08x\n",  apic_read(APIC_ARBPRI));
-	seq_printf(seq, " PROCPRI\t: %08x\n",  apic_read(APIC_PROCPRI));
-	seq_printf(seq, " LDR\t\t: %08x\n",  apic_read(APIC_LDR));
-	seq_printf(seq, " DFR\t\t: %08x\n",  apic_read(APIC_DFR));
-	seq_printf(seq, " SPIV\t\t: %08x\n",  apic_read(APIC_SPIV));
-	seq_printf(seq, " ISR\t\t: %08x\n",  apic_read(APIC_ISR));
-	seq_printf(seq, " ESR\t\t: %08x\n",  apic_read(APIC_ESR));
-	seq_printf(seq, " ICR\t\t: %08x\n",  apic_read(APIC_ICR));
-	seq_printf(seq, " ICR2\t\t: %08x\n",  apic_read(APIC_ICR2));
-	seq_printf(seq, " LVTT\t\t: %08x\n",  apic_read(APIC_LVTT));
-	seq_printf(seq, " LVTTHMR\t: %08x\n",  apic_read(APIC_LVTTHMR));
-	seq_printf(seq, " LVTPC\t\t: %08x\n",  apic_read(APIC_LVTPC));
-	seq_printf(seq, " LVT0\t\t: %08x\n",  apic_read(APIC_LVT0));
-	seq_printf(seq, " LVT1\t\t: %08x\n",  apic_read(APIC_LVT1));
-	seq_printf(seq, " LVTERR\t\t: %08x\n",  apic_read(APIC_LVTERR));
-	seq_printf(seq, " TMICT\t\t: %08x\n",  apic_read(APIC_TMICT));
-	seq_printf(seq, " TMCCT\t\t: %08x\n",  apic_read(APIC_TMCCT));
-	seq_printf(seq, " TDCR\t\t: %08x\n",  apic_read(APIC_TDCR));
+	for (i = 0; i < ARRAY_SIZE(cpu_apic); i++) {
+		if (strlen(cpu_apic[i].name) < 7)
+			seq_printf(seq, " %s\t\t: %08x\n",  cpu_apic[i].name,
+				   apic_read(cpu_apic[i].flag));
+		else
+			seq_printf(seq, " %s\t: %08x\n",  cpu_apic[i].name,
+				   apic_read(cpu_apic[i].flag));
+	}
 	if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
-		unsigned int i, v, maxeilvt;
+		unsigned int maxeilvt;
 
-		v = apic_read(APIC_EFEAT);
-		maxeilvt = (v >> 16) & 0xff;
-		seq_printf(seq, " EFEAT\t\t: %08x\n", v);
-		seq_printf(seq, " ECTRL\t\t: %08x\n", apic_read(APIC_ECTRL));
+		for (i = 0; i < ARRAY_SIZE(cpu_xapic); i++)
+			seq_printf(seq, " %s\t\t: %08x\n",  cpu_xapic[i].name,
+				   apic_read(cpu_xapic[i].flag));
 
-		for (i = 0; i < maxeilvt; i++) {
-			v = apic_read(APIC_EILVTn(i));
-			seq_printf(seq, " EILVT%d\t\t: %08x\n", i, v);
-		}
+		maxeilvt = (apic_read(APIC_EFEAT) >> 16) & 0xff;
+		for (i = 0; i < maxeilvt; i++)
+			seq_printf(seq, " EILVT%d\t\t: %08x\n",
+				   i, apic_read(APIC_EILVTn(i)));
 	}
 	seq_printf(seq, "\n");
-#endif /* CONFIG_X86_LOCAL_APIC */
+#endif
+}
+
+static void print_apicval(void *arg)
+{
+	struct seq_file *seq = arg;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+	struct cpu_private *priv = seq->private;
+
+	seq_printf(seq, "0x%x\n", apic_read(priv->reg));
+#endif
 }
 
 static int cpu_seq_show(struct seq_file *seq, void *v)
@@ -431,6 +461,9 @@ static int cpu_seq_show(struct seq_file *seq, void *v)
 			smp_call_function_single(priv->cpu, print_apic, seq, 1);
 		if (priv->cat == CPU_REG_MSR)
 			print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
+		else if (priv->cat == CPU_REG_APIC)
+			smp_call_function_single(priv->cpu, print_apicval,
+						 seq, 1);
 		break;
 
 	default:
@@ -627,6 +660,41 @@ static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry)
 	return err;
 }
 
+static void cpu_init_apic(unsigned cpu, struct dentry *dentry)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	struct dentry *cpu_dentry;
+	char reg_dir[16];
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(cpu_apic); i++) {
+		sprintf(reg_dir, "APIC_%s", cpu_apic[i].name);
+		cpu_dentry = debugfs_create_dir(reg_dir, dentry);
+		cpu_create_file(cpu, CPU_APIC, cpu_apic[i].flag, CPU_VALUE,
+				CPU_REG_APIC, cpu_dentry);
+	}
+
+	if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
+		unsigned int maxeilvt;
+
+		for (i = 0; i < ARRAY_SIZE(cpu_xapic); i++) {
+			sprintf(reg_dir, "APIC_%s", cpu_xapic[i].name);
+			cpu_dentry = debugfs_create_dir(reg_dir, dentry);
+			cpu_create_file(cpu, CPU_APIC, cpu_xapic[i].flag,
+					CPU_VALUE, CPU_REG_APIC, cpu_dentry);
+		}
+
+		maxeilvt = (apic_read(APIC_EFEAT) >> 16) & 0xff;
+		for (i = 0; i < maxeilvt; i++) {
+			sprintf(reg_dir, "APIC_EILVT%d", i);
+			cpu_dentry = debugfs_create_dir(reg_dir, dentry);
+			cpu_create_file(cpu, CPU_APIC, APIC_EILVTn(i),
+					CPU_VALUE, CPU_REG_APIC, cpu_dentry);
+		}
+	}
+#endif
+}
+
 static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
 {
 	struct dentry *cpu_dentry = NULL;
@@ -639,6 +707,8 @@ static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
 		cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry);
 		per_cpu(cpu_arr[type].dentry, cpu) = cpu_dentry;
 
+		if (type == CPU_APIC)
+			cpu_init_apic(cpu, cpu_dentry);
 		if (type < CPU_TSS)
 			err = cpu_init_msr(cpu, type, cpu_dentry);
 		else
-- 
1.6.0.6




^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH 8/10 -tip] x86: cpu_debug display PCI configuration registers for AMD
  2009-06-13 16:33             ` [RFC][PATCH 7/10 -tip] x86: cpu_debug support APIC_register_name with directory structure Jaswinder Singh Rajput
@ 2009-06-13 16:34               ` Jaswinder Singh Rajput
  2009-06-13 16:35                 ` [RFC][PATCH 9/10 -tip] x86: cpu_debug display cpuid functions Jaswinder Singh Rajput
  0 siblings, 1 reply; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 16:34 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: H. Peter Anvin, x86 maintainers, Andreas Herrmann, Andrew Morton,
	Andi Kleen, LKML, Yinghai Lu, Dave Jones, Linus Torvalds,
	Thomas Gleixner, Robert Richter


PCI-defined configuration space PCIX_YYY:

  X specifies the function number
  YYY specifies the byte address of the configuration register in hex

  e.g., PCI3_040 specifies the register at function 3, address 0x40.

AMD processor supports five functions, 0 through 4.

Also updated MAX_CPU_FILES to 768 to handle pci files.

Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
---
 arch/x86/include/asm/cpu_debug.h |   11 ++-
 arch/x86/kernel/cpu/cpu_debug.c  |  280 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 288 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
index fd20da7..dc24338 100644
--- a/arch/x86/include/asm/cpu_debug.h
+++ b/arch/x86/include/asm/cpu_debug.h
@@ -41,10 +41,17 @@ enum cpu_debug_bit {
 	CPU_IBS,				/* IBS			*/
 	CPU_SVM,				/*Secure Virtual Machine*/
 	CPU_OSVM,				/* OS-Visible Workaround*/
+	CPU_NB,					/* North Bridge		*/
+	CPU_DRAM,				/* DRAM			*/
+	CPU_MMIO,				/* Memory based IO	*/
+	CPU_DISPLAY,				/* Display/VGA		*/
+	CPU_LINK,				/* HyperTransport	*/
+	CPU_CPUID,				/* CPUID		*/
 /* Standard Registers							*/
 	CPU_TSS,				/* Task Stack Segment	*/
 	CPU_CR,					/* Control Registers	*/
 	CPU_DT,					/* Descriptor Table	*/
+	CPU_PCI,				/* PCI configuration	*/
 /* End of Registers flags						*/
 	CPU_REG_MAX,				/* Max Registers flags	*/
 };
@@ -62,9 +69,11 @@ enum cpu_cat_bit {
 	CPU_REG_STD,				/* Standard registers	*/
 	CPU_REG_MSR,				/* MSRs			*/
 	CPU_REG_APIC,				/* APIC registers	*/
+	CPU_REG_PCI,				/* PCI conf registers	*/
 };
 
-#define MAX_CPU_FILES		512
+#define MAX_CPU_FILES		768		/* Max CPU debug files	*/
+#define MAX_CPU_PCI		5		/* AMD supports func 0-4*/
 
 struct cpu_private {
 	unsigned		cpu;
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index fcfd22f..b4dfddd 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/pci.h>
 #include <linux/smp.h>
 
 #include <asm/cpu_debug.h>
@@ -27,6 +28,7 @@
 
 static DEFINE_PER_CPU(struct cpu_cpuX_base, cpu_arr[CPU_REG_MAX]);
 static DEFINE_PER_CPU(struct cpu_private *, priv_arr[MAX_CPU_FILES]);
+static DEFINE_PER_CPU(struct pci_dev *, pci_arr[MAX_CPU_PCI]);
 static DEFINE_PER_CPU(int, cpu_priv_count);
 
 static DEFINE_MUTEX(cpu_debug_lock);
@@ -65,9 +67,16 @@ static struct cpu_debug_base cpu_base[] = {
 	{ "ibs",	CPU_IBS,	0	},
 	{ "svm",	CPU_SVM,	0	},
 	{ "osvm",	CPU_OSVM,	0	},
+	{ "nbridge",	CPU_NB,		0	},
+	{ "dram",	CPU_DRAM,	0	},
+	{ "mmio",	CPU_MMIO,	0	},
+	{ "display",	CPU_DISPLAY,	0	},
+	{ "link",	CPU_LINK,	0	},
+	{ "cpuid",	CPU_CPUID,	0	},
 	{ "tss",	CPU_TSS,	0	},
 	{ "cr",		CPU_CR,		0	},
 	{ "dt",		CPU_DT,		0	},
+	{ "pci",	CPU_PCI,	0	},
 	{ "registers",	CPU_REG_ALL,	0	},
 };
 
@@ -207,6 +216,93 @@ static struct cpu_debug_range cpu_msr_range[] = {
 	{ 0xC0011030, 0xC001103A, CPU_IBS,	},
 };
 
+/* PCI-defined configurations registers		*/
+
+/* Function 0 Link Configuration Registers	*/
+static struct cpu_debug_range cpu_amd_pci0[] = {
+	{ 0x000,	0x00C,	CPU_PCI		},
+	{ 0x034,	0x034,	CPU_PCI		},
+	{ 0x040,	0x06C,	CPU_LINK	},
+	{ 0x080,	0x098,	CPU_LINK	},
+	{ 0x0A0,	0x0B8,	CPU_LINK	},
+	{ 0x0C0,	0x0D8,	CPU_LINK	},
+	{ 0x0E0,	0x0F8,	CPU_LINK	},
+	{ 0x110,	0x150,	CPU_LINK	},
+	{ 0x164,	0x18C,	CPU_LINK	},
+	{ 0x1A0,	0x1A0,	CPU_LINK	},
+	{ 0x1A4,	0x1A4,	CPU_DISPLAY	},
+	{ 0x1D0,	0x1D4,	CPU_DISPLAY	},
+};
+
+/* Function 1 Address Map Registers		*/
+static struct cpu_debug_range cpu_amd_pci1[] = {
+	{ 0x000,	0x00C,	CPU_PCI		},
+	{ 0x034,	0x034,	CPU_PCI		},
+	{ 0x040,	0x07C,	CPU_DRAM	},
+	{ 0x080,	0x0BC,	CPU_MMIO	},
+	{ 0x0C0,	0x0DC,	CPU_PCI		},
+	{ 0x0E0,	0x0EC,	CPU_CONF	},
+	{ 0x0F0,	0x0F0,	CPU_DRAM	},
+	{ 0x0F4,	0x0F4,	CPU_DISPLAY	},
+	{ 0x110,	0x114,	CPU_MMIO	},
+	{ 0x120,	0x124,	CPU_DRAM	},
+	{ 0x140,	0x17C,	CPU_DRAM	},
+	{ 0x180,	0x184,	CPU_NB		},
+};
+
+/* Function 2 DRAM Controller Registers		*/
+static struct cpu_debug_range cpu_amd_pci2[] = {
+	{ 0x000,	0x00C,	CPU_PCI		},
+	{ 0x034,	0x034,	CPU_PCI		},
+	{ 0x040,	0x0A4,	CPU_DRAM	},
+	{ 0x10C,	0x11C,	CPU_DRAM	},
+	{ 0x140,	0x16C,	CPU_DRAM	},
+	{ 0x178,	0x1A0,	CPU_DRAM	},
+	{ 0x1B0,	0x1B0,	CPU_DRAM	},
+};
+
+/* Function 3 Misc. Configuration Registers	*/
+static struct cpu_debug_range cpu_amd_pci3[] = {
+	{ 0x000,	0x00C,	CPU_PCI		},
+	{ 0x034,	0x034,	CPU_PCI		},
+	{ 0x040,	0x054,	CPU_NB		},
+	{ 0x058,	0x060,	CPU_DRAM	},
+	{ 0x064,	0x068,	CPU_THERM	},
+	{ 0x06C,	0x06C,	CPU_POWER	},
+	{ 0x070,	0x07C,	CPU_DISPLAY	},
+	{ 0x080,	0x084,	CPU_POWER	},
+	{ 0x088,	0x08C,	CPU_NB		},
+	{ 0x090,	0x09C,	CPU_DISPLAY	},
+	{ 0x0A0,	0x0A0,	CPU_POWER	},
+	{ 0x0A4,	0x0A4,	CPU_THERM	},
+	{ 0x0B0,	0x0B0,	CPU_DISPLAY	},
+	{ 0x0D4,	0x0DC,	CPU_POWER	},
+	{ 0x0E4,	0x0E4,	CPU_THERM	},
+	{ 0x0E8,	0x0E8,	CPU_NB		},
+	{ 0x0F0,	0x0F0,	CPU_PCI		},
+	{ 0x0F4,	0x0F8,	CPU_PCI		},
+	{ 0x0FC,	0x0FC,	CPU_CPUID	},
+	{ 0x140,	0x180,	CPU_NB		},
+	{ 0x188,	0x188,	CPU_NB		},
+	{ 0x190,	0x190,	CPU_CONTROL	},
+	{ 0x1A0,	0x1A0,	CPU_CACHE	},
+	{ 0x1CC,	0x1CC,	CPU_IBS		},
+	{ 0x1E4,	0x1EC,	CPU_THERM	},
+	{ 0x1F0,	0x1F0,	CPU_CPUID	},
+	{ 0x1FC,	0x1FC,	CPU_NB		},
+};
+
+/* Function 4 Link Configuration Registers	*/
+static struct cpu_debug_range cpu_amd_pci4[] = {
+	{ 0x000,	0x00C,	CPU_PCI		},
+	{ 0x034,	0x034,	CPU_PCI		},
+	{ 0x080,	0x0F8,	CPU_LINK	},
+	{ 0x170,	0x174,	CPU_POWER	},
+	{ 0x180,	0x19C,	CPU_LINK	},
+	{ 0x1C4,	0x1C4,	CPU_POWER	},
+	{ 0x1E0,	0x1F0,	CPU_POWER	},
+};
+
 /* Check validity of cpu debug flag */
 static int is_typeflag_valid(unsigned cpu, unsigned flag)
 {
@@ -433,6 +529,92 @@ static void print_apicval(void *arg)
 #endif
 }
 
+static void print_pcival(void *arg)
+{
+	struct seq_file *seq = arg;
+	struct cpu_private *priv = seq->private;
+	struct pci_dev *dev;
+	u32 data = (priv->reg & 0xf0000) >> 16;
+
+	if (data >= MAX_CPU_PCI)
+		return;
+
+	dev = per_cpu(pci_arr[data], priv->cpu);
+	if (!pci_read_config_dword(dev, priv->reg & 0x0fff, &data))
+		seq_printf(seq, "0x%x\n", data);
+}
+
+#define PRINT_AMD_PCI(func) \
+static void print_amd_pci##func(struct seq_file *seq, struct pci_dev *dev) \
+{									\
+	unsigned int reg, i;						\
+	u32 data;							\
+									\
+	for (i = 0; i < ARRAY_SIZE(cpu_amd_pci##func); i++) {		\
+		for (reg = cpu_amd_pci##func[i].min; 			\
+		     reg <= cpu_amd_pci##func[i].max; reg++) {		\
+			if (!pci_read_config_dword(dev, reg, &data)) {	\
+				seq_printf(seq, " %03x\t: %08x\n", 	\
+					   reg, data);			\
+			}						\
+		}							\
+	}								\
+	seq_printf(seq, "\n");						\
+}
+
+PRINT_AMD_PCI(0)
+PRINT_AMD_PCI(1)
+PRINT_AMD_PCI(2)
+PRINT_AMD_PCI(3)
+PRINT_AMD_PCI(4)
+
+static void print_amd_pci(struct seq_file *seq)
+{
+	struct cpu_private *priv = seq->private;
+	struct pci_dev *dev;
+	unsigned int func;
+
+	for (func = 0; func < MAX_CPU_PCI; func++) {
+		dev = per_cpu(pci_arr[func], priv->cpu);
+		if (dev == NULL)
+			continue;
+
+		seq_printf(seq, " function : %d\n", func);
+
+		switch (func) {
+		case 0:
+			print_amd_pci0(seq, dev);
+			break;
+		case 1:
+			print_amd_pci1(seq, dev);
+			break;
+		case 2:
+			print_amd_pci2(seq, dev);
+			break;
+		case 3:
+			print_amd_pci3(seq, dev);
+			break;
+		case 4:
+			print_amd_pci4(seq, dev);
+			break;
+		}
+	}
+}
+
+static void print_pci(void *arg)
+{
+	struct seq_file *seq = arg;
+
+	seq_printf(seq, " PCI configuration regsiters :\n");
+	switch (boot_cpu_data.x86_vendor) {
+	case X86_VENDOR_AMD:
+		print_amd_pci(seq);
+		break;
+	default:
+		return;
+	}
+}
+
 static int cpu_seq_show(struct seq_file *seq, void *v)
 {
 	struct cpu_private *priv = seq->private;
@@ -450,6 +632,13 @@ static int cpu_seq_show(struct seq_file *seq, void *v)
 	case CPU_DT:
 		smp_call_function_single(priv->cpu, print_dt, seq, 1);
 		break;
+	case CPU_PCI:
+		if (priv->file == CPU_INDEX)
+			smp_call_function_single(priv->cpu, print_pci, seq, 1);
+		else
+			smp_call_function_single(priv->cpu, print_pcival,
+						 seq, 1);
+		break;
 	case CPU_DEBUG:
 		if (priv->file == CPU_INDEX)
 			smp_call_function_single(priv->cpu, print_dr, seq, 1);
@@ -469,6 +658,9 @@ static int cpu_seq_show(struct seq_file *seq, void *v)
 	default:
 		if (priv->cat == CPU_REG_MSR)
 			print_msr(seq, priv->cpu, cpu_base[priv->type].flag);
+		else if (priv->cat == CPU_REG_PCI)
+			smp_call_function_single(priv->cpu, print_pcival,
+						 seq, 1);
 		break;
 	}
 	seq_printf(seq, "\n");
@@ -695,6 +887,86 @@ static void cpu_init_apic(unsigned cpu, struct dentry *dentry)
 #endif
 }
 
+#define INIT_AMD_PCI(func) \
+static void init_amd_pci##func(unsigned cpu, struct dentry *dentry, 	\
+				struct pci_dev *dev)			\
+{									\
+	struct dentry *cdentry;						\
+	unsigned int reg, i, id;					\
+	char reg_dir[10];						\
+	u32 data;							\
+									\
+	for (i = 0; i < ARRAY_SIZE(cpu_amd_pci##func); i++) {		\
+		for (reg = cpu_amd_pci##func[i].min;			\
+		     reg <= cpu_amd_pci##func[i].max; reg++) {		\
+			if (!pci_read_config_dword(dev, reg, &data)) {	\
+				sprintf(reg_dir, "PCI%d_%03x",		\
+					func, reg);			\
+				id = cpu_amd_pci##func[i].flag;		\
+				cdentry = debugfs_create_dir(reg_dir,	\
+					per_cpu(cpu_arr[id].dentry, cpu)); \
+				cpu_create_file(cpu, 			\
+						cpu_amd_pci##func[i].flag, \
+						(func << 16) | reg,	\
+						CPU_VALUE, CPU_REG_PCI, \
+						cdentry);		\
+			}						\
+		}							\
+	}								\
+}
+
+/* AMD supports five functions, 0 through 4 */
+INIT_AMD_PCI(0)
+INIT_AMD_PCI(1)
+INIT_AMD_PCI(2)
+INIT_AMD_PCI(3)
+INIT_AMD_PCI(4)
+
+static void init_amd_pci(unsigned cpu, struct dentry *dentry)
+{
+	struct pci_dev *dev = NULL;
+	unsigned int func;
+
+	while ((dev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_ANY_ID, dev))
+	       != NULL) {
+		if ((dev->device >= 0x1100) && (dev->device < 0x2000)) {
+			func = dev->device & 0xff;
+			if (func >= MAX_CPU_PCI)
+				continue;
+
+			per_cpu(pci_arr[func], cpu) = dev;
+			switch (func) {
+			case 0:
+				init_amd_pci0(cpu, dentry, dev);
+				break;
+			case 1:
+				init_amd_pci1(cpu, dentry, dev);
+				break;
+			case 2:
+				init_amd_pci2(cpu, dentry, dev);
+				break;
+			case 3:
+				init_amd_pci3(cpu, dentry, dev);
+				break;
+			case 4:
+				init_amd_pci4(cpu, dentry, dev);
+				break;
+			}
+		}
+	}
+}
+
+static void cpu_init_pci(unsigned cpu, struct dentry *dentry)
+{
+	switch (boot_cpu_data.x86_vendor) {
+	case X86_VENDOR_AMD:
+		init_amd_pci(cpu, dentry);
+		break;
+	default:
+		return;
+	}
+}
+
 static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
 {
 	struct dentry *cpu_dentry = NULL;
@@ -702,13 +974,17 @@ static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
 	int err = 0;
 
 	for (type = 0; type <  ARRAY_SIZE(cpu_base) - 1; type++) {
-		if (!is_typeflag_valid(cpu, cpu_base[type].flag))
-			continue;
 		cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry);
 		per_cpu(cpu_arr[type].dentry, cpu) = cpu_dentry;
 
+		/* check before preparing "state" file */
+		if (!is_typeflag_valid(cpu, cpu_base[type].flag))
+			continue;
+
 		if (type == CPU_APIC)
 			cpu_init_apic(cpu, cpu_dentry);
+		if (type == CPU_PCI)
+			cpu_init_pci(cpu, cpu_dentry);
 		if (type < CPU_TSS)
 			err = cpu_init_msr(cpu, type, cpu_dentry);
 		else
-- 
1.6.0.6




^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH 9/10 -tip] x86: cpu_debug display cpuid functions
  2009-06-13 16:34               ` [RFC][PATCH 8/10 -tip] x86: cpu_debug display PCI configuration registers for AMD Jaswinder Singh Rajput
@ 2009-06-13 16:35                 ` Jaswinder Singh Rajput
  2009-06-13 16:35                   ` [RFC][PATCH 10/10 -tip] x86: cpu_debug display basic cpuinfo Jaswinder Singh Rajput
  2009-06-13 17:53                   ` [RFC][PATCH 9/10 -tip] x86: cpu_debug display cpuid functions Michael S. Zick
  0 siblings, 2 replies; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 16:35 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: H. Peter Anvin, x86 maintainers, Andreas Herrmann, Andrew Morton,
	Andi Kleen, LKML, Yinghai Lu, Dave Jones, Linus Torvalds,
	Thomas Gleixner, Robert Richter


Add support for cpuid standard and extended functions

Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
---
 arch/x86/include/asm/cpu_debug.h |    4 ++-
 arch/x86/kernel/cpu/cpu_debug.c  |   64 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
index dc24338..377f658 100644
--- a/arch/x86/include/asm/cpu_debug.h
+++ b/arch/x86/include/asm/cpu_debug.h
@@ -46,11 +46,11 @@ enum cpu_debug_bit {
 	CPU_MMIO,				/* Memory based IO	*/
 	CPU_DISPLAY,				/* Display/VGA		*/
 	CPU_LINK,				/* HyperTransport	*/
-	CPU_CPUID,				/* CPUID		*/
 /* Standard Registers							*/
 	CPU_TSS,				/* Task Stack Segment	*/
 	CPU_CR,					/* Control Registers	*/
 	CPU_DT,					/* Descriptor Table	*/
+	CPU_CPUID,				/* CPUID		*/
 	CPU_PCI,				/* PCI configuration	*/
 /* End of Registers flags						*/
 	CPU_REG_MAX,				/* Max Registers flags	*/
@@ -75,6 +75,8 @@ enum cpu_cat_bit {
 #define MAX_CPU_FILES		768		/* Max CPU debug files	*/
 #define MAX_CPU_PCI		5		/* AMD supports func 0-4*/
 
+#define CPUID_MASK		0xffff0000
+
 struct cpu_private {
 	unsigned		cpu;
 	unsigned		type;
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index b4dfddd..f7f702e 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -72,10 +72,10 @@ static struct cpu_debug_base cpu_base[] = {
 	{ "mmio",	CPU_MMIO,	0	},
 	{ "display",	CPU_DISPLAY,	0	},
 	{ "link",	CPU_LINK,	0	},
-	{ "cpuid",	CPU_CPUID,	0	},
 	{ "tss",	CPU_TSS,	0	},
 	{ "cr",		CPU_CR,		0	},
 	{ "dt",		CPU_DT,		0	},
+	{ "cpuid",	CPU_CPUID,	0	},
 	{ "pci",	CPU_PCI,	0	},
 	{ "registers",	CPU_REG_ALL,	0	},
 };
@@ -303,6 +303,13 @@ static struct cpu_debug_range cpu_amd_pci4[] = {
 	{ 0x1E0,	0x1F0,	CPU_POWER	},
 };
 
+/* Extended CPUID base address			*/
+static u32 cpu_ext_cpuid[] = {
+	0x80000000,		/* Intel, AMD	*/
+	0x80860000,		/* Transmeta	*/
+	0xC0000000,		/* Centaur	*/
+};
+
 /* Check validity of cpu debug flag */
 static int is_typeflag_valid(unsigned cpu, unsigned flag)
 {
@@ -518,6 +525,49 @@ static void print_apic(void *arg)
 #endif
 }
 
+/* Get extended CPUID level */
+static u32 get_extended_cpuid(void)
+{
+	u32 i, level;
+
+	for (i = 0; i < ARRAY_SIZE(cpu_ext_cpuid); i++) {
+		level = cpuid_eax(cpu_ext_cpuid[i]);
+		if ((level & CPUID_MASK) == cpu_ext_cpuid[i])
+			return level;
+	}
+
+	return 0;		/* Not found */
+}
+
+static void print_cpuidabcd(struct seq_file *seq, u32 min, u32 max)
+{
+	u32 i, eax, ebx, ecx, edx;
+
+	for (i = min; i <= max; i++) {
+		cpuid(i, &eax, &ebx, &ecx, &edx);
+		seq_printf(seq, " %08x  %08x  %08x  %08x  %08x\n",
+			   i, eax, ebx, ecx, edx);
+	}
+}
+
+static void print_cpuid(void *arg)
+{
+	struct seq_file *seq = arg;
+	u32 level;
+
+	seq_printf(seq, " CPUID\t:\n");
+	seq_printf(seq, "              eax       ebx       ecx       edx\n");
+
+	/* Standard CPUID functions */
+	level = cpuid_eax(0);
+	print_cpuidabcd(seq, 0, level);
+
+	/* Extended CPUID functions */
+	level = get_extended_cpuid();
+	if (level)
+		print_cpuidabcd(seq, (level & CPUID_MASK), level);
+}
+
 static void print_apicval(void *arg)
 {
 	struct seq_file *seq = arg;
@@ -632,6 +682,14 @@ static int cpu_seq_show(struct seq_file *seq, void *v)
 	case CPU_DT:
 		smp_call_function_single(priv->cpu, print_dt, seq, 1);
 		break;
+	case CPU_CPUID:
+		if (priv->file == CPU_INDEX)
+			smp_call_function_single(priv->cpu, print_cpuid,
+						 seq, 1);
+		else
+			smp_call_function_single(priv->cpu, print_pcival,
+						 seq, 1);
+		break;
 	case CPU_PCI:
 		if (priv->file == CPU_INDEX)
 			smp_call_function_single(priv->cpu, print_pci, seq, 1);
@@ -814,7 +872,7 @@ static int cpu_init_regfiles(unsigned cpu, unsigned int type, unsigned reg,
 	unsigned file;
 	int err = 0;
 
-	for (file = 0; file <  ARRAY_SIZE(cpu_file); file++) {
+	for (file = 0; file < ARRAY_SIZE(cpu_file); file++) {
 		err = cpu_create_file(cpu, type, reg, file, cat, dentry);
 		if (err)
 			return err;
@@ -973,7 +1031,7 @@ static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
 	unsigned type;
 	int err = 0;
 
-	for (type = 0; type <  ARRAY_SIZE(cpu_base) - 1; type++) {
+	for (type = 0; type < ARRAY_SIZE(cpu_base) - 1; type++) {
 		cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry);
 		per_cpu(cpu_arr[type].dentry, cpu) = cpu_dentry;
 
-- 
1.6.0.6




^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH 10/10 -tip] x86: cpu_debug display basic cpuinfo
  2009-06-13 16:35                 ` [RFC][PATCH 9/10 -tip] x86: cpu_debug display cpuid functions Jaswinder Singh Rajput
@ 2009-06-13 16:35                   ` Jaswinder Singh Rajput
  2009-06-13 17:53                   ` [RFC][PATCH 9/10 -tip] x86: cpu_debug display cpuid functions Michael S. Zick
  1 sibling, 0 replies; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 16:35 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: H. Peter Anvin, x86 maintainers, Andreas Herrmann, Andrew Morton,
	Andi Kleen, LKML, Yinghai Lu, Dave Jones, Linus Torvalds,
	Thomas Gleixner, Robert Richter


Add support for display struct cpuinfo_x86

Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
---
 arch/x86/include/asm/cpu_debug.h |    1 +
 arch/x86/kernel/cpu/cpu_debug.c  |   89 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
index 377f658..b75758e 100644
--- a/arch/x86/include/asm/cpu_debug.h
+++ b/arch/x86/include/asm/cpu_debug.h
@@ -51,6 +51,7 @@ enum cpu_debug_bit {
 	CPU_CR,					/* Control Registers	*/
 	CPU_DT,					/* Descriptor Table	*/
 	CPU_CPUID,				/* CPUID		*/
+	CPU_CPUINFO,				/* struct cpuinfo_x86	*/
 	CPU_PCI,				/* PCI configuration	*/
 /* End of Registers flags						*/
 	CPU_REG_MAX,				/* Max Registers flags	*/
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index f7f702e..993a5bc 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -26,6 +26,11 @@
 #include <asm/apic.h>
 #include <asm/desc.h>
 
+#ifdef MODULE
+#include "capflags.c"
+#include "powerflags.c"
+#endif
+
 static DEFINE_PER_CPU(struct cpu_cpuX_base, cpu_arr[CPU_REG_MAX]);
 static DEFINE_PER_CPU(struct cpu_private *, priv_arr[MAX_CPU_FILES]);
 static DEFINE_PER_CPU(struct pci_dev *, pci_arr[MAX_CPU_PCI]);
@@ -76,6 +81,7 @@ static struct cpu_debug_base cpu_base[] = {
 	{ "cr",		CPU_CR,		0	},
 	{ "dt",		CPU_DT,		0	},
 	{ "cpuid",	CPU_CPUID,	0	},
+	{ "cpuinfo",	CPU_CPUINFO,	0	},
 	{ "pci",	CPU_PCI,	0	},
 	{ "registers",	CPU_REG_ALL,	0	},
 };
@@ -568,6 +574,86 @@ static void print_cpuid(void *arg)
 		print_cpuidabcd(seq, (level & CPUID_MASK), level);
 }
 
+/* dump struct cpuinfo_x86 */
+static void print_cpuinfo(void *arg)
+{
+	struct seq_file *seq = arg;
+	struct cpu_private *priv = seq->private;
+	struct cpuinfo_x86 *cpui;
+	unsigned int i;
+
+	cpui = &cpu_data(priv->cpu);
+	seq_printf(seq, " CPUINFO\t:\n");
+	seq_printf(seq, " processor\t\t: %u\n", priv->cpu);
+
+	seq_printf(seq, " family\t\t\t: %u\n", cpui->x86);
+	seq_printf(seq, " vendor\t\t\t: %u\n", cpui->x86_vendor);
+	seq_printf(seq, " model\t\t\t: %u\n", cpui->x86_model);
+	seq_printf(seq, " mask\t\t\t: %u\n", cpui->x86_mask);
+#ifdef CONFIG_X86_32
+	seq_printf(seq, " wp_works_ok\t\t: %u\n", cpui->wp_works_ok);
+	seq_printf(seq, " halt_works_ok\t\t: %u\n", cpui->hlt_works_ok);
+	seq_printf(seq, " hard_math\t\t: %u\n", cpui->hard_math);
+	seq_printf(seq, " rfu\t\t\t: %u\n", cpui->rfu);
+	seq_printf(seq, " fdiv_bug\t\t: %u\n", cpui->fdiv_bug);
+	seq_printf(seq, " f00f_bug\t\t: %u\n", cpui->f00f_bug);
+	seq_printf(seq, " coma_bug\t\t: %u\n", cpui->coma_bug);
+#else
+	seq_printf(seq, " TLB size\t\t: %d 4K pages\n", cpui->x86_tlbsize);
+#endif
+	seq_printf(seq, " virtual bits\t\t: %u\n", cpui->x86_virt_bits);
+	seq_printf(seq, " physical bits\t\t: %u\n", cpui->x86_phys_bits);
+
+	seq_printf(seq, " extended cpuid level\t: %08x (%08x)\n",
+		   cpui->extended_cpuid_level, get_extended_cpuid());
+	seq_printf(seq, " cpuid level\t\t: %d\n", cpui->cpuid_level);
+
+	seq_printf(seq, " flags\t\t\t:");
+	for (i = 0; i < 32 * NCAPINTS; i++)
+		if (cpu_has(cpui, i) && x86_cap_flags[i] != NULL)
+			seq_printf(seq, " %s", x86_cap_flags[i]);
+
+	seq_printf(seq, "\n vendor id\t\t: %s\n",
+		   cpui->x86_vendor_id[0] ? cpui->x86_vendor_id : "unknown");
+	seq_printf(seq, " model id\t\t: %s\n",
+		   cpui->x86_model_id[0] ? cpui->x86_model_id : "unknown");
+
+	seq_printf(seq, " cache size\t\t: %d KB\n", cpui->x86_cache_size);
+	seq_printf(seq, " cache alignment\t: %d\n", cpui->x86_cache_alignment);
+
+	seq_printf(seq, " power management\t:");
+	for (i = 0; i < 32; i++) {
+		if (cpui->x86_power & (1 << i)) {
+			if (i < ARRAY_SIZE(x86_power_flags) &&
+			    x86_power_flags[i])
+				seq_printf(seq, "%s%s",
+					   x86_power_flags[i][0] ? " " : "",
+					   x86_power_flags[i]);
+			else
+				seq_printf(seq, " [%d]", i);
+		}
+	}
+
+	seq_printf(seq, "\n loops per jiffy\t: %lu\n", cpui->loops_per_jiffy);
+	seq_printf(seq, " bogomips\t\t: %lu.%02lu\n",
+		   cpui->loops_per_jiffy/(500000/HZ),
+		   (cpui->loops_per_jiffy/(5000/HZ)) % 100);
+
+	seq_printf(seq, " max cores\t\t: %d\n", cpui->x86_max_cores);
+	seq_printf(seq, " apic id\t\t: %d\n", cpui->apicid);
+	seq_printf(seq, " intial apic id\t\t: %d\n", cpui->initial_apicid);
+	seq_printf(seq, " clflush size\t\t: %u\n", cpui->x86_clflush_size);
+
+#ifdef CONFIG_SMP
+	seq_printf(seq, " cpu cores\t\t: %d\n", cpui->booted_cores);
+	seq_printf(seq, " physical id\t\t: %d\n", cpui->phys_proc_id);
+	seq_printf(seq, " core id\t\t: %d\n", cpui->cpu_core_id);
+	seq_printf(seq, " cpu index\t\t: %d\n", cpui->cpu_index);
+#endif
+
+	seq_printf(seq, " hyper vendor\t\t: %d\n", cpui->x86_hyper_vendor);
+}
+
 static void print_apicval(void *arg)
 {
 	struct seq_file *seq = arg;
@@ -690,6 +776,9 @@ static int cpu_seq_show(struct seq_file *seq, void *v)
 			smp_call_function_single(priv->cpu, print_pcival,
 						 seq, 1);
 		break;
+	case CPU_CPUINFO:
+		smp_call_function_single(priv->cpu, print_cpuinfo, seq, 1);
+		break;
 	case CPU_PCI:
 		if (priv->file == CPU_INDEX)
 			smp_call_function_single(priv->cpu, print_pci, seq, 1);
-- 
1.6.0.6




^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH 9/10 -tip] x86: cpu_debug display cpuid functions
  2009-06-13 16:35                 ` [RFC][PATCH 9/10 -tip] x86: cpu_debug display cpuid functions Jaswinder Singh Rajput
  2009-06-13 16:35                   ` [RFC][PATCH 10/10 -tip] x86: cpu_debug display basic cpuinfo Jaswinder Singh Rajput
@ 2009-06-13 17:53                   ` Michael S. Zick
  2009-06-13 18:25                     ` Jaswinder Singh Rajput
  1 sibling, 1 reply; 19+ messages in thread
From: Michael S. Zick @ 2009-06-13 17:53 UTC (permalink / raw)
  To: Jaswinder Singh Rajput
  Cc: Ingo Molnar, H. Peter Anvin, x86 maintainers, Andreas Herrmann,
	Andrew Morton, Andi Kleen, LKML, Yinghai Lu, Dave Jones,
	Linus Torvalds, Thomas Gleixner, Robert Richter

On Sat June 13 2009, Jaswinder Singh Rajput wrote:
> 
> Add support for cpuid standard and extended functions
> 
> Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
> ---
>  arch/x86/include/asm/cpu_debug.h |    4 ++-
>  arch/x86/kernel/cpu/cpu_debug.c  |   64 ++++++++++++++++++++++++++++++++++++--
>  2 files changed, 64 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
> index dc24338..377f658 100644
> --- a/arch/x86/include/asm/cpu_debug.h
> +++ b/arch/x86/include/asm/cpu_debug.h
> @@ -46,11 +46,11 @@ enum cpu_debug_bit {
>  	CPU_MMIO,				/* Memory based IO	*/
>  	CPU_DISPLAY,				/* Display/VGA		*/
>  	CPU_LINK,				/* HyperTransport	*/
> -	CPU_CPUID,				/* CPUID		*/
>  /* Standard Registers							*/
>  	CPU_TSS,				/* Task Stack Segment	*/
>  	CPU_CR,					/* Control Registers	*/
>  	CPU_DT,					/* Descriptor Table	*/
> +	CPU_CPUID,				/* CPUID		*/
>  	CPU_PCI,				/* PCI configuration	*/
>  /* End of Registers flags						*/
>  	CPU_REG_MAX,				/* Max Registers flags	*/
> @@ -75,6 +75,8 @@ enum cpu_cat_bit {
>  #define MAX_CPU_FILES		768		/* Max CPU debug files	*/
>  #define MAX_CPU_PCI		5		/* AMD supports func 0-4*/
>  
> +#define CPUID_MASK		0xffff0000
> +
>  struct cpu_private {
>  	unsigned		cpu;
>  	unsigned		type;
> diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
> index b4dfddd..f7f702e 100644
> --- a/arch/x86/kernel/cpu/cpu_debug.c
> +++ b/arch/x86/kernel/cpu/cpu_debug.c
> @@ -72,10 +72,10 @@ static struct cpu_debug_base cpu_base[] = {
>  	{ "mmio",	CPU_MMIO,	0	},
>  	{ "display",	CPU_DISPLAY,	0	},
>  	{ "link",	CPU_LINK,	0	},
> -	{ "cpuid",	CPU_CPUID,	0	},
>  	{ "tss",	CPU_TSS,	0	},
>  	{ "cr",		CPU_CR,		0	},
>  	{ "dt",		CPU_DT,		0	},
> +	{ "cpuid",	CPU_CPUID,	0	},
>  	{ "pci",	CPU_PCI,	0	},
>  	{ "registers",	CPU_REG_ALL,	0	},
>  };
> @@ -303,6 +303,13 @@ static struct cpu_debug_range cpu_amd_pci4[] = {
>  	{ 0x1E0,	0x1F0,	CPU_POWER	},
>  };
>  
> +/* Extended CPUID base address			*/
> +static u32 cpu_ext_cpuid[] = {
> +	0x80000000,		/* Intel, AMD	*/
> +	0x80860000,		/* Transmeta	*/
> +	0xC0000000,		/* Centaur	*/
>

VIA/Centaur has both 0xC0000000 and 0x8000000

Mike
> +};
> +
>  /* Check validity of cpu debug flag */
>  static int is_typeflag_valid(unsigned cpu, unsigned flag)
>  {
> @@ -518,6 +525,49 @@ static void print_apic(void *arg)
>  #endif
>  }
>  
> +/* Get extended CPUID level */
> +static u32 get_extended_cpuid(void)
> +{
> +	u32 i, level;
> +
> +	for (i = 0; i < ARRAY_SIZE(cpu_ext_cpuid); i++) {
> +		level = cpuid_eax(cpu_ext_cpuid[i]);
> +		if ((level & CPUID_MASK) == cpu_ext_cpuid[i])
> +			return level;
> +	}
> +
> +	return 0;		/* Not found */
> +}
> +
> +static void print_cpuidabcd(struct seq_file *seq, u32 min, u32 max)
> +{
> +	u32 i, eax, ebx, ecx, edx;
> +
> +	for (i = min; i <= max; i++) {
> +		cpuid(i, &eax, &ebx, &ecx, &edx);
> +		seq_printf(seq, " %08x  %08x  %08x  %08x  %08x\n",
> +			   i, eax, ebx, ecx, edx);
> +	}
> +}
> +
> +static void print_cpuid(void *arg)
> +{
> +	struct seq_file *seq = arg;
> +	u32 level;
> +
> +	seq_printf(seq, " CPUID\t:\n");
> +	seq_printf(seq, "              eax       ebx       ecx       edx\n");
> +
> +	/* Standard CPUID functions */
> +	level = cpuid_eax(0);
> +	print_cpuidabcd(seq, 0, level);
> +
> +	/* Extended CPUID functions */
> +	level = get_extended_cpuid();
> +	if (level)
> +		print_cpuidabcd(seq, (level & CPUID_MASK), level);
> +}
> +
>  static void print_apicval(void *arg)
>  {
>  	struct seq_file *seq = arg;
> @@ -632,6 +682,14 @@ static int cpu_seq_show(struct seq_file *seq, void *v)
>  	case CPU_DT:
>  		smp_call_function_single(priv->cpu, print_dt, seq, 1);
>  		break;
> +	case CPU_CPUID:
> +		if (priv->file == CPU_INDEX)
> +			smp_call_function_single(priv->cpu, print_cpuid,
> +						 seq, 1);
> +		else
> +			smp_call_function_single(priv->cpu, print_pcival,
> +						 seq, 1);
> +		break;
>  	case CPU_PCI:
>  		if (priv->file == CPU_INDEX)
>  			smp_call_function_single(priv->cpu, print_pci, seq, 1);
> @@ -814,7 +872,7 @@ static int cpu_init_regfiles(unsigned cpu, unsigned int type, unsigned reg,
>  	unsigned file;
>  	int err = 0;
>  
> -	for (file = 0; file <  ARRAY_SIZE(cpu_file); file++) {
> +	for (file = 0; file < ARRAY_SIZE(cpu_file); file++) {
>  		err = cpu_create_file(cpu, type, reg, file, cat, dentry);
>  		if (err)
>  			return err;
> @@ -973,7 +1031,7 @@ static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
>  	unsigned type;
>  	int err = 0;
>  
> -	for (type = 0; type <  ARRAY_SIZE(cpu_base) - 1; type++) {
> +	for (type = 0; type < ARRAY_SIZE(cpu_base) - 1; type++) {
>  		cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry);
>  		per_cpu(cpu_arr[type].dentry, cpu) = cpu_dentry;
>  



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH 9/10 -tip] x86: cpu_debug display cpuid functions
  2009-06-13 17:53                   ` [RFC][PATCH 9/10 -tip] x86: cpu_debug display cpuid functions Michael S. Zick
@ 2009-06-13 18:25                     ` Jaswinder Singh Rajput
  0 siblings, 0 replies; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-13 18:25 UTC (permalink / raw)
  To: lkml
  Cc: Ingo Molnar, H. Peter Anvin, x86 maintainers, Andreas Herrmann,
	Andrew Morton, Andi Kleen, LKML, Yinghai Lu, Dave Jones,
	Linus Torvalds, Thomas Gleixner, Robert Richter

On Sat, 2009-06-13 at 12:53 -0500, Michael S. Zick wrote:
> On Sat June 13 2009, Jaswinder Singh Rajput wrote:
> > 
> > Add support for cpuid standard and extended functions
> > 
> > Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
> > ---
> >  arch/x86/include/asm/cpu_debug.h |    4 ++-
> >  arch/x86/kernel/cpu/cpu_debug.c  |   64 ++++++++++++++++++++++++++++++++++++--
> >  2 files changed, 64 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
> > index dc24338..377f658 100644
> > --- a/arch/x86/include/asm/cpu_debug.h
> > +++ b/arch/x86/include/asm/cpu_debug.h
> > @@ -46,11 +46,11 @@ enum cpu_debug_bit {
> >  	CPU_MMIO,				/* Memory based IO	*/
> >  	CPU_DISPLAY,				/* Display/VGA		*/
> >  	CPU_LINK,				/* HyperTransport	*/
> > -	CPU_CPUID,				/* CPUID		*/
> >  /* Standard Registers							*/
> >  	CPU_TSS,				/* Task Stack Segment	*/
> >  	CPU_CR,					/* Control Registers	*/
> >  	CPU_DT,					/* Descriptor Table	*/
> > +	CPU_CPUID,				/* CPUID		*/
> >  	CPU_PCI,				/* PCI configuration	*/
> >  /* End of Registers flags						*/
> >  	CPU_REG_MAX,				/* Max Registers flags	*/
> > @@ -75,6 +75,8 @@ enum cpu_cat_bit {
> >  #define MAX_CPU_FILES		768		/* Max CPU debug files	*/
> >  #define MAX_CPU_PCI		5		/* AMD supports func 0-4*/
> >  
> > +#define CPUID_MASK		0xffff0000
> > +
> >  struct cpu_private {
> >  	unsigned		cpu;
> >  	unsigned		type;
> > diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
> > index b4dfddd..f7f702e 100644
> > --- a/arch/x86/kernel/cpu/cpu_debug.c
> > +++ b/arch/x86/kernel/cpu/cpu_debug.c
> > @@ -72,10 +72,10 @@ static struct cpu_debug_base cpu_base[] = {
> >  	{ "mmio",	CPU_MMIO,	0	},
> >  	{ "display",	CPU_DISPLAY,	0	},
> >  	{ "link",	CPU_LINK,	0	},
> > -	{ "cpuid",	CPU_CPUID,	0	},
> >  	{ "tss",	CPU_TSS,	0	},
> >  	{ "cr",		CPU_CR,		0	},
> >  	{ "dt",		CPU_DT,		0	},
> > +	{ "cpuid",	CPU_CPUID,	0	},
> >  	{ "pci",	CPU_PCI,	0	},
> >  	{ "registers",	CPU_REG_ALL,	0	},
> >  };
> > @@ -303,6 +303,13 @@ static struct cpu_debug_range cpu_amd_pci4[] = {
> >  	{ 0x1E0,	0x1F0,	CPU_POWER	},
> >  };
> >  
> > +/* Extended CPUID base address			*/
> > +static u32 cpu_ext_cpuid[] = {
> > +	0x80000000,		/* Intel, AMD	*/
> > +	0x80860000,		/* Transmeta	*/
> > +	0xC0000000,		/* Centaur	*/
> >
> 
> VIA/Centaur has both 0xC0000000 and 0x8000000
> 

hmm, then this patch will work for multiple extended cpuid levels :

[PATCH 9/10 -tip] x86: cpu_debug display cpuid functions

Add support for cpuid standard and extended functions

Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com>
---
 arch/x86/include/asm/cpu_debug.h |    4 ++-
 arch/x86/kernel/cpu/cpu_debug.c  |   52 +++++++++++++++++++++++++++++++++++--
 2 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
index dc24338..377f658 100644
--- a/arch/x86/include/asm/cpu_debug.h
+++ b/arch/x86/include/asm/cpu_debug.h
@@ -46,11 +46,11 @@ enum cpu_debug_bit {
 	CPU_MMIO,				/* Memory based IO	*/
 	CPU_DISPLAY,				/* Display/VGA		*/
 	CPU_LINK,				/* HyperTransport	*/
-	CPU_CPUID,				/* CPUID		*/
 /* Standard Registers							*/
 	CPU_TSS,				/* Task Stack Segment	*/
 	CPU_CR,					/* Control Registers	*/
 	CPU_DT,					/* Descriptor Table	*/
+	CPU_CPUID,				/* CPUID		*/
 	CPU_PCI,				/* PCI configuration	*/
 /* End of Registers flags						*/
 	CPU_REG_MAX,				/* Max Registers flags	*/
@@ -75,6 +75,8 @@ enum cpu_cat_bit {
 #define MAX_CPU_FILES		768		/* Max CPU debug files	*/
 #define MAX_CPU_PCI		5		/* AMD supports func 0-4*/
 
+#define CPUID_MASK		0xffff0000
+
 struct cpu_private {
 	unsigned		cpu;
 	unsigned		type;
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index b4dfddd..4d881a3 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -72,10 +72,10 @@ static struct cpu_debug_base cpu_base[] = {
 	{ "mmio",	CPU_MMIO,	0	},
 	{ "display",	CPU_DISPLAY,	0	},
 	{ "link",	CPU_LINK,	0	},
-	{ "cpuid",	CPU_CPUID,	0	},
 	{ "tss",	CPU_TSS,	0	},
 	{ "cr",		CPU_CR,		0	},
 	{ "dt",		CPU_DT,		0	},
+	{ "cpuid",	CPU_CPUID,	0	},
 	{ "pci",	CPU_PCI,	0	},
 	{ "registers",	CPU_REG_ALL,	0	},
 };
@@ -303,6 +303,13 @@ static struct cpu_debug_range cpu_amd_pci4[] = {
 	{ 0x1E0,	0x1F0,	CPU_POWER	},
 };
 
+/* Extended CPUID base address			*/
+static u32 cpu_ext_cpuid[] = {
+	0x80000000,		/* Intel, AMD	*/
+	0x80860000,		/* Transmeta	*/
+	0xC0000000,		/* Centaur	*/
+};
+
 /* Check validity of cpu debug flag */
 static int is_typeflag_valid(unsigned cpu, unsigned flag)
 {
@@ -518,6 +525,37 @@ static void print_apic(void *arg)
 #endif
 }
 
+static void print_cpuidabcd(struct seq_file *seq, u32 min, u32 max)
+{
+	u32 i, eax, ebx, ecx, edx;
+
+	for (i = min; i <= max; i++) {
+		cpuid(i, &eax, &ebx, &ecx, &edx);
+		seq_printf(seq, " %08x  %08x  %08x  %08x  %08x\n",
+			   i, eax, ebx, ecx, edx);
+	}
+}
+
+static void print_cpuid(void *arg)
+{
+	struct seq_file *seq = arg;
+	u32 i, level;
+
+	seq_printf(seq, " CPUID\t:\n");
+	seq_printf(seq, "              eax       ebx       ecx       edx\n");
+
+	/* Standard CPUID functions */
+	level = cpuid_eax(0);
+	print_cpuidabcd(seq, 0, level);
+
+	/* Extended CPUID functions */
+	for (i = 0; i < ARRAY_SIZE(cpu_ext_cpuid); i++) {
+		level = cpuid_eax(cpu_ext_cpuid[i]);
+		if ((level & CPUID_MASK) == cpu_ext_cpuid[i])
+			print_cpuidabcd(seq, cpu_ext_cpuid[i], level);
+	}
+}
+
 static void print_apicval(void *arg)
 {
 	struct seq_file *seq = arg;
@@ -632,6 +670,14 @@ static int cpu_seq_show(struct seq_file *seq, void *v)
 	case CPU_DT:
 		smp_call_function_single(priv->cpu, print_dt, seq, 1);
 		break;
+	case CPU_CPUID:
+		if (priv->file == CPU_INDEX)
+			smp_call_function_single(priv->cpu, print_cpuid,
+						 seq, 1);
+		else
+			smp_call_function_single(priv->cpu, print_pcival,
+						 seq, 1);
+		break;
 	case CPU_PCI:
 		if (priv->file == CPU_INDEX)
 			smp_call_function_single(priv->cpu, print_pci, seq, 1);
@@ -814,7 +860,7 @@ static int cpu_init_regfiles(unsigned cpu, unsigned int type, unsigned reg,
 	unsigned file;
 	int err = 0;
 
-	for (file = 0; file <  ARRAY_SIZE(cpu_file); file++) {
+	for (file = 0; file < ARRAY_SIZE(cpu_file); file++) {
 		err = cpu_create_file(cpu, type, reg, file, cat, dentry);
 		if (err)
 			return err;
@@ -973,7 +1019,7 @@ static int cpu_init_allreg(unsigned cpu, struct dentry *dentry)
 	unsigned type;
 	int err = 0;
 
-	for (type = 0; type <  ARRAY_SIZE(cpu_base) - 1; type++) {
+	for (type = 0; type < ARRAY_SIZE(cpu_base) - 1; type++) {
 		cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry);
 		per_cpu(cpu_arr[type].dentry, cpu) = cpu_dentry;
 
-- 
1.6.0.6




^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613
  2009-06-13 16:27 [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613 Jaswinder Singh Rajput
  2009-06-13 16:28 ` [RFC][PATCH 1/10 -tip] x86: cpu_debug update Kconfig entry Jaswinder Singh Rajput
@ 2009-06-13 22:27 ` Thomas Gleixner
  2009-06-14  5:35   ` Jaswinder Singh Rajput
  2009-06-15 13:57   ` Andreas Herrmann
  1 sibling, 2 replies; 19+ messages in thread
From: Thomas Gleixner @ 2009-06-13 22:27 UTC (permalink / raw)
  To: Jaswinder Singh Rajput
  Cc: Ingo Molnar, H. Peter Anvin, x86 maintainers, Andreas Herrmann,
	Andrew Morton, Andi Kleen, LKML, Yinghai Lu, Dave Jones,
	Linus Torvalds, Robert Richter

On Sat, 13 Jun 2009, Jaswinder Singh Rajput wrote:

> Please let me know how we can improve it and add more features so it
> becomes more useful.

I really have to ask, why this is useful at all.

> 1. Standard Registers

What's the point of printing task_pt_regs(current) ? 

We dump info of "cat debug/.../tss". Where is the value of this ? Just
because we can ?

> 2. Control Registers

I can see some value in dumping CR0 and CR4, but the rest is pretty useless

CR2 is the pagefault address, which is uninteresting as there is no
context

CR3 is the pagedir, which is pretty uninteresting as well. If we
read it on the current CPU we read the pagedir of "cat ..../cr3" and
if we read it on some other CPU its completely out of context. We
see a pagedir entry and have no information about the context.

CR8 is unused in Linux and always 0

> 3. Debug Registers

Again, where is the point? These registers are only interesting when
we know about the context. This interface just provides the access to
random information.

We already have debuggers which use that and they know the context
they are operating in.

> 4. Descriptor Tables

What's the value of pointers to IDT, GDT tables ? The interesting
information is in the tables, where IDT is static and uninteresting
though GDT table contents can change

Again, LDT and TR are task context dependent values. Where is the
information at which context we are looking ?

> 5. APIC Registers

Dunno, what we gain from that information.

> 6. Model specific Register (MSRs)

Where is the difference of poking in

/sys/kernel/debug/x86/cpu/cpu0/msr/MSR_c0010006/value

and

rdmsr,wrmsr poking on the same MSR ?

There is no difference at all. The information difference is
_ZERO_. The only difference is memory consumption in the kernel and a
even more horrible user interface than we have with mrs-tools.

7. PCI configuration registers (for AMD)

What's the value add over lspci ?

> 8. Basic cpuinfo

Why do we need another incarnation of /proc/cpuinfo ? 

Also cpuid provides more useful decoded information than this.

> 9. CPUID Functions

Again, cpuid can do this already w/o a single line of kernel code.


Can we please get some coherent explanation why we need this in the
kernel? 

Granted there are about 4 interesting registers where we have no
interface yet and where user space tools can not look into, but 99% of
the information exposed by this module is either useless or redundant
or both.

The worst stuff is the reinvention of exising and _useful_ userspace
tools. Just one example:

AMD specific PCI registers

   Current solution:

   Ask user to run lscpi -vvv and lspci -xxx[x] and provide the
   output, which is for -vvv very well decoded and for -xxxx the same
   raw data as we get from cpu_debug (except for the line count)

   Single point of failure: lspci is not installed, which is unlikely,
   but easy to solve and users/bugreporters usually know how to do
   that. Worst case you have to tell him how to do it.

   cpu_debug solution:

   Ask user to compile the module, load the module, mount debugfs and
   provide the output of debug/..... The output is a HEX dump of the
   PCI configuration space and has no more information than the lscpi
   -xxxx dump, indeed it has less:

   lspci -xxxx tells me at which device it is looking in clear text
   with a useful description while this tells me:

   PCI configuration regsiters :
   function : 0
   000  : 13001022
   
   So i need to look at the code to see at which pci config space this
   is looking and what "function 0" is all about. How useful.

   Multiple points of failure:
   	    user can not compile the module
	    user fails to load the module
	    user fails to mount debugfs

Same applies for cpuid and msr access. This cpu_debug stuff is harder
to use and provides the same of mostly less information. What's the
gain ?
 

I'm a full supporter of _useful_ debug interfaces, but this is
definitely not what I call useful and useable.

The reinvention of useful tools like lspci, cpuid, rdmsr, wrmsr inside
of the kernel with a worse user interface and less information
provided is just a waste of time and resources.

Dumping random information out of any context is not helping us to
debug problems. There is no value to look at debug registers, context
registers and tss->regs without the context of the task we look at.

Can we please stop adding more random features to this?

This needs to be done the other way round. First we need to remove all
redundant and useless interfaces from cpu_debug and then think
carefully about in which way we want to expose the few really missing
interesting things either by extending existing user space tools or by
providing context aware and debug relevant interfaces in the kernel.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613
  2009-06-13 22:27 ` [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613 Thomas Gleixner
@ 2009-06-14  5:35   ` Jaswinder Singh Rajput
  2009-06-14 11:19     ` Thomas Gleixner
  2009-06-15 13:57   ` Andreas Herrmann
  1 sibling, 1 reply; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-14  5:35 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Ingo Molnar, H. Peter Anvin, x86 maintainers, Andreas Herrmann,
	Andrew Morton, Andi Kleen, LKML, Yinghai Lu, Dave Jones,
	Linus Torvalds, Robert Richter, rth, starvik, geert, dhowells,
	lethal, chris, linux, dhowells, tony.luck, philb, kyle, davem,
	hskinnemoen, monstr, benh, vapier, ysato, takata, ralf,
	schwidefsky

On Sun, 2009-06-14 at 00:27 +0200, Thomas Gleixner wrote:
> On Sat, 13 Jun 2009, Jaswinder Singh Rajput wrote:
> 
> > Please let me know how we can improve it and add more features so it
> > becomes more useful.
> 
> I really have to ask, why this is useful at all.
> 

Currently for X86 I can do :

1. read complete state (dump all registers like for MTRR, APIC)
2. read individual register
3. write to individual register
4. read/write these registers/info with shell through debugfs
5. read these registers/info before getting shell

And I did this for complete X86 CPU registers and info:
1. Standard Registers
2. Control Registers
3. Debug Registers
4. Descriptor Tables
5. APIC Registers
6. Model specific Register (MSRs)
7. PCI configuration registers (for AMD)
8. Basic cpuinfo
9. CPUID Functions

This will be really useful for :
1. developer who is porting/developing the kernel or drivers.
2. User who is reading hardware manual and want to see these value on
its CPU

Of course you need a Hardware manual to check address and detail
information. I do not want to keep detail for each register.

In X86 many tools are available which can read many registers but not
available for many architectures (I CCed some architecture maintainers
so that they can also specify issues they face when supporting new
CPU/architecture), they can also take advantage of it if we move
cpu_debug architecture independent portion outside X86.

I am not against of any tool but some issues about tools are :
1. Not supported for all architectures
2. Do not support latest or upcoming hardware
3. You need to mount filesystem and execute some shell to give commands
4. you need different tools to access different registers

So I want to know how can we can make cpu_debug more useful.


> The reinvention of useful tools like lspci, cpuid, rdmsr, wrmsr inside
> of the kernel with a worse user interface and less information
> provided is just a waste of time and resources.
> 

what user interface and information you want ?

Thanks,
--
JSR


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613
  2009-06-14  5:35   ` Jaswinder Singh Rajput
@ 2009-06-14 11:19     ` Thomas Gleixner
  2009-06-14 13:19       ` Jaswinder Singh Rajput
  0 siblings, 1 reply; 19+ messages in thread
From: Thomas Gleixner @ 2009-06-14 11:19 UTC (permalink / raw)
  To: Jaswinder Singh Rajput; +Cc: Ingo Molnar, H. Peter Anvin, x86 maintainers, LKML

Jaswinder,

[ I sanitized the cc list to restrict the annoyance to those who have
to deal with that. Please stop adding people who are not affected by
this. ]

On Sun, 14 Jun 2009, Jaswinder Singh Rajput wrote:

> On Sun, 2009-06-14 at 00:27 +0200, Thomas Gleixner wrote:
> > On Sat, 13 Jun 2009, Jaswinder Singh Rajput wrote:
> > 
> > > Please let me know how we can improve it and add more features so it
> > > becomes more useful.
> > 
> > I really have to ask, why this is useful at all.
> > 
> 
> Currently for X86 I can do :
> 
> 1. read complete state (dump all registers like for MTRR, APIC)
> 2. read individual register
> 3. write to individual register
> 4. read/write these registers/info with shell through debugfs
> 5. read these registers/info before getting shell
> 
> And I did this for complete X86 CPU registers and info:
> 1. Standard Registers
> 2. Control Registers
> 3. Debug Registers
> 4. Descriptor Tables
> 5. APIC Registers
> 6. Model specific Register (MSRs)
> 7. PCI configuration registers (for AMD)
> 8. Basic cpuinfo
> 9. CPUID Functions

I did not ask what it can do. I did ask what's the usefulness of
it. Your answer is the same list on which I commented on already in
technical detail, but you ignored those comments.

> This will be really useful for :
> 1. developer who is porting/developing the kernel or drivers.

We can access all this information already with existing tools.

> 2. User who is reading hardware manual and want to see these value on
> its CPU

Same here.
 
> Of course you need a Hardware manual to check address and detail
> information. I do not want to keep detail for each register.

That's why anyone with common sense will use lspci, cpuid to get the
information in both raw and decoded format.
 
> In X86 many tools are available which can read many registers but not
> available for many architectures (I CCed some architecture maintainers
> so that they can also specify issues they face when supporting new
> CPU/architecture), they can also take advantage of it if we move

I have ported Linux to a couple of new platforms and the problem you
face is that the kernel does not boot at all in the early stage of the
boot process. 

How does cpu_debug help in that situation ? It does not help at all.

> cpu_debug architecture independent portion outside X86.

There is nothing x86 independent in cpu_debug.
 
> I am not against of any tool but some issues about tools are :
> 1. Not supported for all architectures

Again cpu_debug can not made generic as it is poking in architecture
specific hardware.

> 2. Do not support latest or upcoming hardware

All these tools show the raw values, which also covers latest hardware.

> 3. You need to mount filesystem and execute some shell to give commands

Are you saying that the access to your debugfs based cpu_debug
information does neither require a mounted file system nor a shell nor
commands? It provides the information by telepathy, right?

> 4. you need different tools to access different registers

Write a wrapper script if that annoys you.
 
> So I want to know how can we can make cpu_debug more useful.

I have not yet seen a single technical argument for what it is useful
at all.

So please stop hand waving about what it might do as long as you can
not provide a single technical reason why cpu_debug should be in the
kernel at all.

Go through the kernel.org bugzilla and show me _one_ single bug which
I debugged with the bug reporter, which could have been resolved
faster by using cpu_debug. And think careful about it before you
provide me that information.

> > The reinvention of useful tools like lspci, cpuid, rdmsr, wrmsr inside
> > of the kernel with a worse user interface and less information
> > provided is just a waste of time and resources.
> > 
> 
> what user interface and information you want ?

I'm happy to use the existing tools and their user interface. There is
no value of having inferior reimplementations of those tools in the
kernel.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613
  2009-06-14 11:19     ` Thomas Gleixner
@ 2009-06-14 13:19       ` Jaswinder Singh Rajput
  2009-06-14 14:32         ` Thomas Gleixner
  0 siblings, 1 reply; 19+ messages in thread
From: Jaswinder Singh Rajput @ 2009-06-14 13:19 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: Ingo Molnar, H. Peter Anvin, x86 maintainers, LKML

On Sun, 2009-06-14 at 13:19 +0200, Thomas Gleixner wrote:
> Jaswinder,
> 
> [ I sanitized the cc list to restrict the annoyance to those who have
> to deal with that. Please stop adding people who are not affected by
> this. ]
> 

I wrote cpu_debug because of past issues I faced working with Hitachi
and ARM processor. I just start working on X86 from last few months, I
wrote cpu_debug for X86 because currently I have only X86 machine, I am
planning to divide cpu_debug into architecture dependent and
non-dependent code so that other architectures can also benefit from it.

That's why I CCed other architecture's maintainers.


> > This will be really useful for :
> > 1. developer who is porting/developing the kernel or drivers.
> 
> We can access all this information already with existing tools.
> 

Why you are thinking about X86 ?

I worked on embedded processors more than 10 year, I never found any
tools, and sometimes we get the first lot of the boards.

Only tool which I used is printk.

Even though the code I used in cpu_debug I wrote that code to support :
1. Performance counters for AMD
2. Support Temperature sensor for AMD 11H

>  
> > Of course you need a Hardware manual to check address and detail
> > information. I do not want to keep detail for each register.
> 
> That's why anyone with common sense will use lspci, cpuid to get the
> information in both raw and decoded format.


These does not make sense if the kernel is not booting and filesystem is
not available.
To use the tools I need to build the tools, build filesystem for my
processor and load on filesystem.

>  
> > In X86 many tools are available which can read many registers but not
> > available for many architectures (I CCed some architecture maintainers
> > so that they can also specify issues they face when supporting new
> > CPU/architecture), they can also take advantage of it if we move
> 
> I have ported Linux to a couple of new platforms and the problem you
> face is that the kernel does not boot at all in the early stage of the
> boot process. 
> 
> How does cpu_debug help in that situation ? It does not help at all.
> 

I supported functions if you pass seq = NULL then it will print on
screen, then you do need any filesystem or debugfs.

> > cpu_debug architecture independent portion outside X86.
> 
> There is nothing x86 independent in cpu_debug.
>  

There is, I will show you.

> > I am not against of any tool but some issues about tools are :
> > 1. Not supported for all architectures
> 
> Again cpu_debug can not made generic as it is poking in architecture
> specific hardware.
> 

Ok I will show you.

> > 2. Do not support latest or upcoming hardware
> 
> All these tools show the raw values, which also covers latest hardware.
> 

But when I used them they said processor not supported.

> > 3. You need to mount filesystem and execute some shell to give commands
> 
> Are you saying that the access to your debugfs based cpu_debug
> information does neither require a mounted file system nor a shell nor
> commands? It provides the information by telepathy, right?
> 

you can call the function, and pass seq as NULL, it will use printk and
dump state on screen. I just did this for MSR, I can also support for
other registers.

> > 4. you need different tools to access different registers
> 
> Write a wrapper script if that annoys you.
>  

when tools, filesystem and shell is not available where you will run
your script ?

> > So I want to know how can we can make cpu_debug more useful.
> 
> I have not yet seen a single technical argument for what it is useful
> at all.
> 

Because your eyes are closed, please open it.

Thanks,
--
JSR



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613
  2009-06-14 13:19       ` Jaswinder Singh Rajput
@ 2009-06-14 14:32         ` Thomas Gleixner
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Gleixner @ 2009-06-14 14:32 UTC (permalink / raw)
  To: Jaswinder Singh Rajput; +Cc: Ingo Molnar, H. Peter Anvin, x86 maintainers, LKML

Jaswinder,

On Sun, 14 Jun 2009, Jaswinder Singh Rajput wrote:
> On Sun, 2009-06-14 at 13:19 +0200, Thomas Gleixner wrote:
> > > This will be really useful for :
> > > 1. developer who is porting/developing the kernel or drivers.
> > 
> > We can access all this information already with existing tools.
> > 
> 
> Why you are thinking about X86 ?

Because I work on it and that code is in the area which I'm
responsible for. And I want useful code in that area, not something
which causes a lot of churn for no value at all.

> I worked on embedded processors more than 10 year, I never found any
> tools, and sometimes we get the first lot of the boards.

I have worked on ARM, MIPS, SH, PPC often enough and I never needed
such a tool.

> Only tool which I used is printk.

Which is perfectly fine to do low level debugging.

> Even though the code I used in cpu_debug I wrote that code to support :
> 1. Performance counters for AMD
> 2. Support Temperature sensor for AMD 11H

And you needed cpu_debug to do this ? 

Sorry, I really do not understand that. Ingo and I wrote the inital
code of performance counters (both the generic parts and Intel
support) in a couple of days w/o feeling the need of cpu_debug even
once.

If you need cpu_debug for doing your work, fine. Maintain it somewhere
and figure out how many people come along and find it useful. But do
not impose this on the x86 code base.

> > > In X86 many tools are available which can read many registers but not
> > > available for many architectures (I CCed some architecture maintainers
> > > so that they can also specify issues they face when supporting new
> > > CPU/architecture), they can also take advantage of it if we move
> > 
> > I have ported Linux to a couple of new platforms and the problem you
> > face is that the kernel does not boot at all in the early stage of the
> > boot process. 
> > 
> > How does cpu_debug help in that situation ? It does not help at all.
> > 
> I supported functions if you pass seq = NULL then it will print on
> screen, then you do need any filesystem or debugfs.

Fine. And what is triggering the printout of a particular register ?

You need to hack the kernel to call the print functions in cpu_debug,
right ?

So where is the value of this? It is ad hoc debugging and there is no
gain to replace a printk(THE INFO I NEED) with a call to
cpu_debug().

Actually its worse. If I need the information of an APIC register,
then I print excaclty this register and not the whole lot of registers,
which then will scroll the screen with the important information
away.

Also I need information of a register in context with the content of
some variables of the code I'm debugging. printk() allows me to add
sensible and useful information in a compact format. cpu_debug does
not.

> > > 2. Do not support latest or upcoming hardware
> > 
> > All these tools show the raw values, which also covers latest hardware.
> > 
> 
> But when I used them they said processor not supported.

And why didn't you get the source and fix it? Instead of improving an
existing tool you impose a ridicolous amount of useless code on x86.

> > > 3. You need to mount filesystem and execute some shell to give commands
> > 
> > Are you saying that the access to your debugfs based cpu_debug
> > information does neither require a mounted file system nor a shell nor
> > commands? It provides the information by telepathy, right?
> > 
> 
> you can call the function, and pass seq as NULL, it will use printk and
> dump state on screen. I just did this for MSR, I can also support for
> other registers.

As I said above. There is no gain in doing so. Ad hoc debugging is the
same with printk and cpu_debug except that cpu_debug is inferior.

> > > So I want to know how can we can make cpu_debug more useful.
> > 
> > I have not yet seen a single technical argument for what it is useful
> > at all.
> > 
> 
> Because your eyes are closed, please open it.

I have my eyes open and I looked at the existing code and the proposed
patches in detail. I also looked at your arguments which can be boiled
down to:

1) Jaswinder prefers to have cpu_debug_print_whatever() instead of
   printk(THE INFO I NEED) for ad hoc debugging.

2) Jaswinder cannot work without cpu_debug.

Both are not really convincing technical arguments. cpu_debug has
_ZERO_ gain over printk() based debugging and it adds _ZERO_ value
with its debugfs based interface.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613
  2009-06-13 22:27 ` [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613 Thomas Gleixner
  2009-06-14  5:35   ` Jaswinder Singh Rajput
@ 2009-06-15 13:57   ` Andreas Herrmann
  1 sibling, 0 replies; 19+ messages in thread
From: Andreas Herrmann @ 2009-06-15 13:57 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Jaswinder Singh Rajput, Ingo Molnar, H. Peter Anvin,
	x86 maintainers, Andrew Morton, Andi Kleen, LKML, Yinghai Lu,
	Dave Jones, Linus Torvalds, Robert Richter

On Sun, Jun 14, 2009 at 12:27:42AM +0200, Thomas Gleixner wrote:
> On Sat, 13 Jun 2009, Jaswinder Singh Rajput wrote:
> 
> > Please let me know how we can improve it and add more features so it
> > becomes more useful.

I second almost all of Thomas points. (The more I am wondering why
cpu_debug was merged at all.)

IMHO removing the cpuid, msr etc. stuff is the right thing to do.

But hey, I even can provide a "use case" for cpu_debug.

Recently I wanted to check some APIC registers. Instead of rebooting
the machine with apic=debug I loaded the module, mounted debugfs and
looked at the cpu_debug stuff to experience that ...

  The registers that I was interested in were not provided.

So I had to add some code to print some of the regs in the extended
APIC register with apic=debug code.  When submitting the patch
upstream I added the same regs to cpu_debug code. This really good
shows another weak point of cpu_debug:

  If the kernel has already code for debugging output cpu_debug just
  reinvents the wheel and does not even try to reuse existing code.

So in the end cpu_debug wasn't useful for me at all.

   <snip>

> Dumping random information out of any context is not helping us to
> debug problems. There is no value to look at debug registers, context
> registers and tss->regs without the context of the task we look at.
> 
> Can we please stop adding more random features to this?
> 
> This needs to be done the other way round. First we need to remove all
> redundant and useless interfaces from cpu_debug and then think
> carefully about in which way we want to expose the few really missing
> interesting things either by extending existing user space tools or by
> providing context aware and debug relevant interfaces in the kernel.

IMHO the cpu_debug feature should be renamed to platform_debug and
then already existing kernel debug code could be modified such that it
can also be called from this new platform_debug facility.  This would
allow to check certain things not only when booting Linux with certain
debug parameters but also on the fly when mounting the debugfs ...

The registers that come into my mind that would make some kind
of sense to provide with that interface are
- APIC stuff
- HPET stuff

Neither MSR, CPUID, CPU regs nor PCI config space stuff should be
added. Other facilities/tools exist for those (e.g. x86info,
msr-tools, pciutils or Magic SysRq).

... just my two cents.


Regards,

Andreas



^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2009-06-15 13:58 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-13 16:27 [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613 Jaswinder Singh Rajput
2009-06-13 16:28 ` [RFC][PATCH 1/10 -tip] x86: cpu_debug update Kconfig entry Jaswinder Singh Rajput
2009-06-13 16:29   ` [RFC][PATCH 2/10 -tip] x86: cpu_debug.c remove some not required header files Jaswinder Singh Rajput
2009-06-13 16:30     ` [RFC][PATCH 3/10 -tip] x86: cpu_debug.c use a WARN_ONCE() instead of a pr_err() Jaswinder Singh Rajput
2009-06-13 16:30       ` [RFC][PATCH 4/10 -tip] x86: cpu_debug make room to support more categories Jaswinder Singh Rajput
2009-06-13 16:31         ` [RFC][PATCH 5/10 -tip] x86: cpu_debug update MSR list to support new architectures Jaswinder Singh Rajput
2009-06-13 16:32           ` [RFC][PATCH 6/10 -tip] x86: cpu_debug make room for more cpu registers Jaswinder Singh Rajput
2009-06-13 16:33             ` [RFC][PATCH 7/10 -tip] x86: cpu_debug support APIC_register_name with directory structure Jaswinder Singh Rajput
2009-06-13 16:34               ` [RFC][PATCH 8/10 -tip] x86: cpu_debug display PCI configuration registers for AMD Jaswinder Singh Rajput
2009-06-13 16:35                 ` [RFC][PATCH 9/10 -tip] x86: cpu_debug display cpuid functions Jaswinder Singh Rajput
2009-06-13 16:35                   ` [RFC][PATCH 10/10 -tip] x86: cpu_debug display basic cpuinfo Jaswinder Singh Rajput
2009-06-13 17:53                   ` [RFC][PATCH 9/10 -tip] x86: cpu_debug display cpuid functions Michael S. Zick
2009-06-13 18:25                     ` Jaswinder Singh Rajput
2009-06-13 22:27 ` [RFC][GIT PULL][PATCH 0/10 -tip] cpu_debug patches 20090613 Thomas Gleixner
2009-06-14  5:35   ` Jaswinder Singh Rajput
2009-06-14 11:19     ` Thomas Gleixner
2009-06-14 13:19       ` Jaswinder Singh Rajput
2009-06-14 14:32         ` Thomas Gleixner
2009-06-15 13:57   ` Andreas Herrmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.