Updated `README.md` with instructions for building/using the kernel module.
[xeon-phi-kernel-module] / trace_capture / trace_capture.c
CommitLineData
800f879a
AT
1/*
2 * Copyright 2010-2017 Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * Disclaimer: The codes contained in these modules may be specific to
14 * the Intel Software Development Platform codenamed Knights Ferry,
15 * and the Intel product codenamed Knights Corner, and are not backward
16 * compatible with other Intel products. Additionally, Intel will NOT
17 * support the codes or instruction set in future products.
18 *
19 * Intel offers no warranty of any kind regarding the code. This code is
20 * licensed on an "AS IS" basis and Intel is not obligated to provide
21 * any support, assistance, installation, training, or other services
22 * of any kind. Intel is also not obligated to provide any updates,
23 * enhancements or extensions. Intel specifically disclaims any warranty
24 * of merchantability, non-infringement, fitness for any particular
25 * purpose, and any other warranty.
26 *
27 * Further, Intel disclaims all liability of any kind, including but
28 * not limited to liability for infringement of any proprietary rights,
29 * relating to the use of the code, even if Intel is notified of the
30 * possibility of such liability. Except as expressly stated in an Intel
31 * license agreement provided with this code and agreed upon with Intel,
32 * no license, express or implied, by estoppel or otherwise, to any
33 * intellectual property rights is granted herein.
34 */
35
36/*
37 * Trace Capture Driver
38 *
39 * Contains code to handle trace_capture syscall, stop all cpus
40 * and dump their state, then dump all physical memeory.
41 */
42
43#include "trace_capture.h"
44
45//#define DEBUG
46
47int always_false = 0;
48
49#define BARRIER(epd, string) { \
50 printk("%s\n", string); \
51 if ((err = scif_send(epd, &control_msg, sizeof(control_msg), 1)) <= 0) { \
52 pr_crit("%s:%s:%d scif_send failed with err %ld\n", __FILE__, __FUNCTION__, __LINE__, err); \
53 goto close; \
54 } \
55 if ((err = scif_recv(epd, &control_msg, sizeof(control_msg), 1)) <= 0) { \
56 pr_crit("%s:%s:%d scif_recv failed with err %ld\n", __FILE__, __FUNCTION__, __LINE__, err); \
57 goto close; \
58 } \
59}
60
61/* SPU privileged gates (per specification) */
62#define SPU_SPBA_OFFSET 0x1000 /* offset of Privileged gates in SPU MMIO */
63#define SPU_XQ_SIZE 0x040
64#define SPU_XQ_BASE 0x080
65#define SPU_XQ_INDEX 0x0C0
66#define SPU_CR 0x100
67#define SPU_CONTROL 0x100
68#define SPU_SAMPLER_BASE 0x140
69#define SPU_ABORT 0x180
70#define SPU_ABORT_STATUS 0x1C0
71#define SPU_FLUSH 0x200
72#define SPU_FLUSH_STATUS 0x240
73#define SPU_INVALPG_4K 0x280
74#define SPU_INVALPG_64K 0x2C0
75#define SPU_INVALPG_2M 0x300
76#define SPU_EMPTY 0x340
77#define SPU_ACTIVE 0x340
78#define SPU_FULL 0x380
79#define SPU_SOFT_RESET 0x3C0
80#define SPU_PMU_EVENT_SEL 0x400
81#define SPU_CONTROL2 0x440
82#define SPU_CONTROL3 0x480
83
84#define SPU_MEM_BW_LIMIT 0x4C0 // This is 64 bit register
85
86#define SPU_TCU_CREDITS 0x700
87#define SPU_FER 0x800
88#define SPU_ALT_FER 0x840
89#define SPU_MATCH_ACTION 0x880
90#define SPU_INVAL 0xB00
91#define SPU_COUNTER0_SET 0x500
92#define SPU_COUNTER1_SET 0x540
93#define SPU_COUNTER2_SET 0x580
94#define SPU_COUNTER3_SET 0x5C0
95#define SPU_COUNTER4_SET 0x600
96#define SPU_COUNTER5_SET 0x640
97#define SPU_COUNTER6_SET 0x680
98#define SPU_COUNTER7_SET 0x6C0
99
100#define CBOX_SPU_PA_MSR 0x0000017E
101#define CBOX_SPU_SAMPLER_BIND_MSR 0x0000017F
102
103#define MSR_SF_MASK 0xc0000084 /* syscall flags mask */
104#define MSR_FSBASE 0xc0000100 /* base address of the %fs "segment" */
105#define MSR_GSBASE 0xc0000101 /* base address of the %gs "segment" */
106#define MSR_KGSBASE 0xc0000102 /* base address of the kernel %gs */
107
108// MSR's defined in the trace file sent during REQs
109// Are these all valid for L1OM??
110#define P6_CR_TSC 0x10
111#define X86_CR_APICBASE 0x1b
112#define MIC_CR_SPUBASE 0x1c
113#define IA32_CR_MISC 0x1a0
114#define WMT_CR_LASTBRANCH_0 0x1db
115#define WMT_CR_LASTBRANCH_1 0x1dc
116#define X86_CR_MTRRphysMask0 0x201
117#define X86_CR_MTRRphysMask1 0x203
118#define X86_CR_MTRRphysMask2 0x205
119#define X86_CR_MTRRphysMask3 0x207
120#define X86_CR_MTRRphysMask4 0x209
121#define X86_CR_MTRRphysMask5 0x20b
122#define X86_CR_MTRRphysMask6 0x20d
123#define X86_CR_MTRRphysMask7 0x20f
124#define IA32_CR_PAT 0x277
125#define IA32_MTRR_DEF_TYPE 0x2ff
126#define VMX_MSR_BASE 0x480
127#define VMX_MSR_BASE_PLUS_1 0x481
128#define VMX_MSR_BASE_PLUS_2 0x482
129#define VMX_MSR_BASE_PLUS_3 0x483
130#define VMX_MSR_BASE_PLUS_4 0x484
131#define VMX_MSR_BASE_PLUS_5 0x485
132#define VMX_MSR_BASE_PLUS_6 0x486
133#define VMX_MSR_BASE_PLUS_7 0x487
134#define VMX_MSR_BASE_PLUS_8 0x488
135#define VMX_MSR_BASE_PLUS_9 0x489
136#define TIME 0x4711
137#define PINFO 0x4712
138#define X86_CR_MTRRdefType 0x2ff
139#define X86_CR_MTRRcap 0xfe
140#define X86_CR_MTRRphysBase0 0x200
141#define X86_CR_MTRRphysBase1 0x202
142#define X86_CR_MTRRphysBase2 0x204
143#define X86_CR_MTRRphysBase3 0x206
144#define X86_CR_MTRRphysBase4 0x208
145#define X86_CR_MTRRphysBase5 0x20a
146#define X86_CR_MTRRphysBase6 0x20c
147#define X86_CR_MTRRphysBase7 0x20e
148#define X86_CR_MTRRfix64K_00000 0x250
149#define X86_CR_MTRRfix16K_80000 0x258
150#define X86_CR_MTRRfix16K_A0000 0x259
151#define X86_CR_MTRRfix4K_C0000 0x268
152#define X86_CR_MTRRfix4K_C8000 0x269
153#define X86_CR_MTRRfix4K_D0000 0x26a
154#define X86_CR_MTRRfix4K_D8000 0x26b
155#define X86_CR_MTRRfix4K_E0000 0x26c
156#define X86_CR_MTRRfix4K_E8000 0x26d
157#define X86_CR_MTRRfix4K_F0000 0x26e
158#define X86_CR_MTRRfix4K_F8000 0x26f
159#define P5_MC_ADDR 0x0
160#define P5_MC_TYPE 0x1
161#define MSR_TR1 0x2
162#define MSR_TR2 0x4
163#define MSR_TR3 0x5
164#define MSR_TR4 0x6
165#define MSR_TR5 0x7
166#define MSR_TR6 0x8
167#define MSR_TR7 0x9
168#define MSR_TR9 0xb
169#define MSR_TR10 0xc
170#define MSR_TR11 0xd
171#define MSR_TR12 0xe
172#define IA32_APIC_BASE 0x1b
173#define IA32_TIME_STAMP_COUNTER 0x10
174#define IA32_PerfCntr0 0x20
175#define IA32_PerfCntr1 0x21
176#define IA32_PerfCntr2 0x22
177#define IA32_PerfCntr3 0x23
178#define PerfFilteredCntr0 0x24
179#define PerfFilteredCntr1 0x25
180#define PerfFilteredCntr2 0x26
181#define PerfFilteredCntr3 0x27
182#define IA32_PerfEvtSel0 0x28
183#define IA32_PerfEvtSel1 0x29
184#define IA32_PerfEvtSel2 0x2a
185#define IA32_PerfEvtSel3 0x2b
186#define PerfFilterMask 0x2c
187#define IA32_PERF_GLOBAL_STATUS 0x2d
188#define IA32_PERF_GLOBAL_OVF_CONTROL 0x2e
189#define IA32_PERF_GLOBAL_CTRL 0x2f
190#define IA32_MCG_CTL 0x17b
191#define IA32_MC0_CTRL 0x400
192#define IA32_MC0_STAT 0x401
193#define IA32_MC0_ADDR 0x402
194#define IA32_MC0_MISC 0x403
195#define IA32_MC1_CTRL 0x404
196#define IA32_MC1_STAT 0x405
197#define IA32_MC1_ADDR 0x406
198#define IA32_MC1_MISC 0x407
199#define STAR 0xc0000081
200#define LSTAR 0xc0000082
201#define SYSCALL_FLAG_MASK 0xc0000084
202#define X86_PAT 0x277
203#define SPU_BASE 0x1C
204
205// Kernel virtual address to physical page at 0xfee03000
206// This is created by an ioremap outside of interrupt context.
207static uint8_t *spu_addr;
208
209struct mictc_seg {
210 struct desc_struct desc;
211 char zero[8];
212 u16 selector;
213 uint64_t base;
214};
215
216struct mictc_tss {
217 tss_desc desc;
218 u16 selector;
219 uint64_t base;
220};
221
222struct mictc_segment_reg
223{
224 struct mictc_seg cs;
225 struct mictc_seg ds;
226 struct mictc_seg es;
227 struct mictc_seg ss;
228 struct mictc_seg fs;
229 struct mictc_seg gs;
230 struct mictc_tss ldtr;
231 struct mictc_tss tr;
232};
233
234#define MAX_SEG_REG 8
235
236static char *SegRegNames[MAX_SEG_REG] = {"CS","DS","ES","SS", "FS","GS","LDTR","TR"};
237
238//static struct i387_fxsave_struct fpu;
239
240struct mictc_trace
241{
242 struct mictc_segment_reg segment;
243 struct vpustate_struct vpustate;
244 struct i387_fxsave_struct fpu;
245};
246
247struct mictc_trace *trace;
248
249// fxsave definition copied from fpu.c
250//#define mictc_fxsave(addr) __asm __volatile("fxsave %0" : "=m" (*(addr)))
251#define mictc_fxsave(addr) __asm __volatile("fxsave (%0)" : "=a" (addr) : [fx] "a" (addr))
252
253
254// Spinlock to serialize access in IPI handler
255static DEFINE_SPINLOCK(mictc_lock);
256
257// Used to count the cpus waiting
258static atomic_t cpus_stopped = ATOMIC_INIT(0);
259
260// Used to count the cpus released
261static atomic_t cpus_released = ATOMIC_INIT(0);
262
263// End points for SCIF
264//static scif_epd_t mictc_endp_cmd;
265static scif_epd_t mictc_endp_data;
266
267// SCIF ports - temp hack; move to scif.h
268#define MICTC_SCIF_PORT_DATA 300
269
270// Used to prevent concurent access into the same device .
271static int Device_Open = 0;
272
273#define PS_BUF_SIZE 150
274//static char print_string_buf[PS_BUF_SIZE] = "";
275
276#define print_str(fmt, ...) \
277{ \
278 snprintf(print_string_buf, PS_BUF_SIZE, fmt, ##__VA_ARGS__); \
279 print_string(print_string_buf); \
280}
281
282//#define printk(fmt, ...) print_str(fmt, ##__VA_ARGS__)
283//#undef pr_crit
284//#define pr_crit(fmt, ...) print_str(fmt, ##__VA_ARGS__)
285
286// Interrupts off / on
287#define cli __asm (" cli\n")
288#define sti __asm (" sti\n")
289
290// Debug code to display low 16 bits of eflags register.
291#define print_eflags \
292 {unsigned long kernel_eflags; \
293 raw_local_save_flags(kernel_eflags); \
294 printk("%s:%d eflags %lx\n", __FUNCTION__, __LINE__, kernel_eflags); \
295 }
296
297
298// Find another definition of this in some .h file
299static __inline void
300mictc_cpuid(u_int ax, u_int *p)
301{
302 __asm __volatile("cpuid"
303 : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
304 : "0" (ax));
305}
306
307static inline
308uint32_t get_dr(int regno)
309{
310 unsigned long val = 0; /* Damn you, gcc! */
311
312 switch (regno) {
313 case 0:
314 asm("mov %%db0, %0" :"=r" (val));
315 break;
316 case 1:
317 asm("mov %%db1, %0" :"=r" (val));
318 break;
319 case 2:
320 asm("mov %%db2, %0" :"=r" (val));
321 break;
322 case 3:
323 asm("mov %%db3, %0" :"=r" (val));
324 break;
325 case 4:
326 asm("mov %%db4, %0" :"=r" (val));
327 break;
328 case 5:
329 asm("mov %%db5, %0" :"=r" (val));
330 break;
331 case 6:
332 asm("mov %%db6, %0" :"=r" (val));
333 break;
334 case 7:
335 asm("mov %%db7, %0" :"=r" (val));
336 break;
337 default:
338 BUG();
339 }
340 return val;
341}
342
343
344static inline void mictc_store_ldt(u16 *dtr)
345{
346 asm volatile("sldt %0":"=m" (*dtr));
347}
348
349
350static inline void mictc_store_tr(u16 *dtr)
351{
352 asm volatile("str %0":"=m" (*dtr));
353}
354
355
356static inline void read_gdt_entry(struct desc_struct *gdt, int entry,
357 void *desc, int type)
358{
359 unsigned int size;
360 switch (type) {
361 case DESC_TSS:
362 size = sizeof(tss_desc);
363 break;
364 case DESC_LDT:
365 size = sizeof(ldt_desc);
366 break;
367 default:
368 size = sizeof(struct desc_struct);
369 break;
370 }
371 memcpy(desc, &gdt[entry], size);
372#if 0 // Helpful for debug
373 { u64 *p = (u64 *)&gdt[entry];
374 printk("GDT[entry] = %p %llx %llx\n", &gdt[entry], p[0], p[1]);
375 }
376#endif
377}
378
379
380static inline void __get_tss_desc(unsigned cpu, unsigned int entry, void *dest)
381{
382 struct desc_struct *d = get_cpu_gdt_table(cpu);
383 read_gdt_entry(d, entry, dest, DESC_TSS);
384}
385
386#define get_tss_desc(cpu, addr) __get_tss_desc(cpu, GDT_ENTRY_TSS, addr)
387
388
389static inline void __get_seg_desc(unsigned cpu, unsigned int entry, void *dest)
390{
391 struct desc_struct *d = get_cpu_gdt_table(cpu);
392
393 read_gdt_entry(d, entry, dest, 0);
394}
395
396#define get_seg_desc(cpu, seg, addr) __get_seg_desc(cpu, ((seg & 0xffff) >> 3), addr)
397
398// Redefine rdmsr to work like BSD.
399
400//#undef rdmsr
401//#define rdmsr(msr) tc_msr((msr))
402
403static inline
404uint64_t tc_rdmsr(uint32_t msrid)
405{
406 uint32_t lower, upper;
407 rdmsr(msrid, lower, upper);
408 return (uint64_t)upper << 32 | lower;
409}
410
411// Number of Retries before it is assumed that the Host will not respond
412#define TRACE_CAPTURE_TIMEOUT 50000000
413
414static void *g_traceBufferAllocated;
415
416// Global variable used by initiator to wait for everyone to complete trace captures
417//static volatile u32 g_smpTraceCaptureWait;
418
419// Global variable to keep track of how much data we are writing to the shared buffer
420// with the Host.
421static volatile u64 g_sizeXferred = 0;
422
423static s64 g_triggerFound = -1;
424
425static volatile u64 *g_traceBufferStatusOffset = NULL;
426static volatile u64 *g_traceBufferSizeOffset = NULL;
427static volatile u32 *g_traceBufferDataOffset = 0;
428static volatile u32 *g_traceBufferTriggerOffset = NULL;
429
430// This is an array of trigger numbers. The value TRACE_EOL is ignored.
431static u32 g_traceTriggers[TRACE_TRIGGER_MAX];
432static u32 g_traceCurrentTrigger;
433
434static long scif_offset_xml;
435//static long scif_offset_xml_dst;
436static long scif_offset_mem;
437static long scif_offset_dst;
438
439#if MIC_TRACE_CAPTURE_MEMORY_TEST
440static volatile u64 *g_traceBufferChecksumOffset = NULL;
441
442// The maximum size allowed for a DMA transfer is 1MB - 4K. The size of this array
443// is 1MB to allow this to be used as the dst memory while dumping entire GDDR
444// For Debug purposes only.
445static u32 g_dstMemoryDump[4096/sizeof(u32)] __attribute__ ((aligned(4096)));
446#endif
447
448#define TRACE_SPRINTF(...) \
449 (g_sizeXferred += sprintf(((char*)g_traceBufferDataOffset + g_sizeXferred), __VA_ARGS__))
450
451#define ADD_SPU_REG_TO_HEADER(x) \
452 TRACE_SPRINTF("\t\t\t\t<reg offset=\"0x%x\">\n\t\t\t\t\t<name>%s</name>\n\t\t\t\t</reg>\n", (x), #x)
453
454#define ADD_MSR_TO_HEADER(x) \
455 TRACE_SPRINTF("\t\t\t\t<reg addr=\"0x%x\"/>\n", (x))
456
457#define TRACE_SPRINTF_MSR(x) \
458 TRACE_SPRINTF("\t\t\t\t<reg addr=\"0x%x\">0x%llx</reg>\n", (x), tc_rdmsr((x)))
459
460#define TRACE_SPRINTF_SPU(x) \
461 TRACE_SPRINTF("\t\t\t\t<reg offset=\"0x%x\">0x%llx</reg>\n", (x), *(volatile u64*)((u8*)spu_addr + (x)))
462
463#define TRACE_SPRINTF_VECTOR(x, vpu) \
464 PrintVector((u8*)&(vpu), (x))
465
466
467//------------------------------------------------------------------------------
468// FUNCTION: mictc_trace_capture_prep_SPU_header
469//
470// DESCRIPTION:
471// Perform all the tasks related to preparing the SPU Trace Header
472//
473// PARAMETERS: None
474//
475// RETURNS: None
476//
477// TODOS:
478//
479static void
480mictc_trace_capture_prep_SPU_header(void)
481{
482 TRACE_SPRINTF("\t\t\t<spu>\n");
483 ADD_SPU_REG_TO_HEADER(SPU_XQ_SIZE);
484 ADD_SPU_REG_TO_HEADER(SPU_XQ_BASE);
485 ADD_SPU_REG_TO_HEADER(SPU_XQ_INDEX);
486 ADD_SPU_REG_TO_HEADER(SPU_CONTROL);
487 ADD_SPU_REG_TO_HEADER(SPU_SAMPLER_BASE);
488 ADD_SPU_REG_TO_HEADER(SPU_PMU_EVENT_SEL);
489 ADD_SPU_REG_TO_HEADER(SPU_CONTROL2);
490 ADD_SPU_REG_TO_HEADER(SPU_CONTROL3);
491 TRACE_SPRINTF("\t\t\t</spu>\n");
492}
493
494
495//------------------------------------------------------------------------------
496// FUNCTION: mictc_trace_capture_prep_cpuid_header
497//
498// DESCRIPTION:
499// Perform all the tasks related to preparing the CPUID Trace Header
500//
501// PARAMETERS: None
502//
503// RETURNS: None
504//
505// TODOS:
506//
507static void
508mictc_trace_capture_prep_cpuid_header(void)
509{
510 u_int regs[4];
511 int i =0;
512 TRACE_SPRINTF("\t\t\t<cpuid>\n");
513 for (i = 0; i < 0x4; i++)
514 {
515 mictc_cpuid(i, regs);
516 TRACE_SPRINTF("\t\t\t\t<reg eax=\"0x%x\">0x%x-0x%x-0x%x-0x%x</reg>\n",
517 i, regs[0], regs[1], regs[2], regs[3]);
518 }
519 TRACE_SPRINTF("\t\t\t</cpuid>\n");
520}
521
522
523//------------------------------------------------------------------------------
524// FUNCTION: mictc_trace_capture_prep_msr_header
525//
526// DESCRIPTION:
527// Perform all the tasks related to preparing the MSR Trace Header
528//
529// PARAMETERS: None
530//
531// RETURNS: None
532//
533// TODOS:
534//
535static void
536mictc_trace_capture_prep_msr_header(void)
537{
538 TRACE_SPRINTF("\t\t\t<msr>\n");
539 ADD_MSR_TO_HEADER(P6_CR_TSC);
540 ADD_MSR_TO_HEADER(X86_CR_APICBASE);
541 ADD_MSR_TO_HEADER(CBOX_SPU_PA_MSR);
542 ADD_MSR_TO_HEADER(SPU_BASE);
543 ADD_MSR_TO_HEADER(CBOX_SPU_SAMPLER_BIND_MSR);
544 ADD_MSR_TO_HEADER(X86_CR_MTRRphysMask0);
545 ADD_MSR_TO_HEADER(X86_CR_MTRRphysMask1);
546 ADD_MSR_TO_HEADER(X86_CR_MTRRphysMask2);
547 ADD_MSR_TO_HEADER(X86_CR_MTRRphysMask3);
548 ADD_MSR_TO_HEADER(X86_CR_MTRRphysMask4);
549 ADD_MSR_TO_HEADER(X86_CR_MTRRphysMask5);
550 ADD_MSR_TO_HEADER(X86_CR_MTRRphysMask6);
551 ADD_MSR_TO_HEADER(X86_CR_MTRRphysMask7);
552 ADD_MSR_TO_HEADER(MSR_EFER);
553 ADD_MSR_TO_HEADER(MSR_SF_MASK);
554 ADD_MSR_TO_HEADER(MSR_FSBASE);
555 ADD_MSR_TO_HEADER(MSR_GSBASE);
556 ADD_MSR_TO_HEADER(X86_CR_MTRRdefType);
557 ADD_MSR_TO_HEADER(X86_CR_MTRRcap);
558 ADD_MSR_TO_HEADER(X86_CR_MTRRphysBase2);
559 ADD_MSR_TO_HEADER(X86_CR_MTRRphysBase0);
560 ADD_MSR_TO_HEADER(X86_CR_MTRRphysBase1);
561 ADD_MSR_TO_HEADER(X86_CR_MTRRphysBase3);
562 ADD_MSR_TO_HEADER(X86_CR_MTRRphysBase4);
563 ADD_MSR_TO_HEADER(X86_CR_MTRRphysBase5);
564 ADD_MSR_TO_HEADER(X86_CR_MTRRphysBase6);
565 ADD_MSR_TO_HEADER(X86_CR_MTRRphysBase7);
566 ADD_MSR_TO_HEADER(STAR);
567 ADD_MSR_TO_HEADER(LSTAR);
568 ADD_MSR_TO_HEADER(MSR_KGSBASE);
569
570 // The following MSR's are currently ifdef'd out
571 // because LarrySim barfs on these.
572 // We might need these later.
573#if 0
574 ADD_MSR_TO_HEADER(X86_CR_MTRRfix64K_00000);
575 ADD_MSR_TO_HEADER(X86_CR_MTRRfix16K_80000);
576 ADD_MSR_TO_HEADER(X86_CR_MTRRfix16K_A0000);
577 ADD_MSR_TO_HEADER(X86_CR_MTRRfix4K_C0000);
578 ADD_MSR_TO_HEADER(X86_CR_MTRRfix4K_C8000);
579 ADD_MSR_TO_HEADER(X86_CR_MTRRfix4K_D0000);
580 ADD_MSR_TO_HEADER(X86_CR_MTRRfix4K_D8000);
581 ADD_MSR_TO_HEADER(X86_CR_MTRRfix4K_E0000);
582 ADD_MSR_TO_HEADER(X86_CR_MTRRfix4K_E8000);
583 ADD_MSR_TO_HEADER(X86_CR_MTRRfix4K_F0000);
584 ADD_MSR_TO_HEADER(X86_CR_MTRRfix4K_F8000);
585 ADD_MSR_TO_HEADER(P5_MC_ADDR);
586 ADD_MSR_TO_HEADER(P5_MC_TYPE);
587 ADD_MSR_TO_HEADER(MSR_TR1);
588 ADD_MSR_TO_HEADER(MSR_TR2);
589 ADD_MSR_TO_HEADER(MSR_TR3);
590 ADD_MSR_TO_HEADER(MSR_TR4);
591 ADD_MSR_TO_HEADER(MSR_TR5);
592 ADD_MSR_TO_HEADER(MSR_TR6);
593 ADD_MSR_TO_HEADER(MSR_TR7);
594 ADD_MSR_TO_HEADER(MSR_TR9);
595 ADD_MSR_TO_HEADER(MSR_TR10);
596 ADD_MSR_TO_HEADER(MSR_TR11);
597 ADD_MSR_TO_HEADER(MSR_TR12);
598 ADD_MSR_TO_HEADER(IA32_APIC_BASE);
599 ADD_MSR_TO_HEADER(IA32_TIME_STAMP_COUNTER);
600 ADD_MSR_TO_HEADER(IA32_PerfCntr0);
601 ADD_MSR_TO_HEADER(IA32_PerfCntr1);
602 ADD_MSR_TO_HEADER(IA32_PerfCntr2);
603 ADD_MSR_TO_HEADER(IA32_PerfCntr3);
604 ADD_MSR_TO_HEADER(PerfFilteredCntr0);
605 ADD_MSR_TO_HEADER(PerfFilteredCntr1);
606 ADD_MSR_TO_HEADER(PerfFilteredCntr2);
607 ADD_MSR_TO_HEADER(PerfFilteredCntr3);
608 ADD_MSR_TO_HEADER(IA32_PerfEvtSel0);
609 ADD_MSR_TO_HEADER(IA32_PerfEvtSel1);
610 ADD_MSR_TO_HEADER(IA32_PerfEvtSel2);
611 ADD_MSR_TO_HEADER(IA32_PerfEvtSel3);
612 ADD_MSR_TO_HEADER(PerfFilterMask);
613 ADD_MSR_TO_HEADER(IA32_PERF_GLOBAL_STATUS);
614 ADD_MSR_TO_HEADER(IA32_PERF_GLOBAL_OVF_CONTROL);
615 ADD_MSR_TO_HEADER(IA32_PERF_GLOBAL_CTRL);
616 ADD_MSR_TO_HEADER(IA32_MCG_CTL);
617 ADD_MSR_TO_HEADER(IA32_MC0_CTRL);
618 ADD_MSR_TO_HEADER(IA32_MC0_STAT);
619 ADD_MSR_TO_HEADER(IA32_MC0_ADDR);
620 ADD_MSR_TO_HEADER(IA32_MC0_MISC);
621 ADD_MSR_TO_HEADER(IA32_MC1_CTRL);
622 ADD_MSR_TO_HEADER(IA32_MC1_STAT);
623 ADD_MSR_TO_HEADER(IA32_MC1_ADDR);
624 ADD_MSR_TO_HEADER(IA32_MC1_MISC);
625 ADD_MSR_TO_HEADER(SYSCALL_FLAG_MASK);
626 ADD_MSR_TO_HEADER(X86_PAT);
627#endif
628 TRACE_SPRINTF("\t\t\t</msr>\n");
629}
630
631
632//------------------------------------------------------------------------------
633// FUNCTION: mictc_prep_header
634//
635// DESCRIPTION:
636// Perform all the tasks related to preparing the Trace Header
637//
638// PARAMETERS: None
639//
640// RETURNS: None
641//
642// TODOS:
643//
644static void
645mictc_prep_header(void)
646{
647 int i;
648
649 TRACE_SPRINTF("<?xml version=\"1.0\" standalone=\"yes\"?>\n");
650 TRACE_SPRINTF("<arch_data>\n");
651 TRACE_SPRINTF("<!-- The format of this file is defined in https://cpu-sim.intel.com/twiki/bin/view/CpuSim/TraceFileFormats. -->\n");
652 TRACE_SPRINTF("\t<header>\n");
653 TRACE_SPRINTF("\t\t<format_version>1.0</format_version>\n");
654 TRACE_SPRINTF("\t\t<creation_date>Nov 19 2009</creation_date>\n");
655 TRACE_SPRINTF("\t\t<arch_xml_ver>1.1</arch_xml_ver>\n");
656 TRACE_SPRINTF("\t\t<arch_xml_date>Oct 21 2009</arch_xml_date>\n");
657 TRACE_SPRINTF("\t\t<created_by>archlib</created_by>\n");
658 TRACE_SPRINTF("\t\t<comment>Warnings! This is based on the state available in archlib.</comment>\n");
659 TRACE_SPRINTF("\t\t<comment> This state dump is primarily good for capturing frequently used architectural register state.</comment>\n");
660 TRACE_SPRINTF("\t\t<comment> Support for CPUId, MSRs, APIC, and x87 state is currently incomplete.</comment>\n");
661 TRACE_SPRINTF("\t\t<comment> There is no support for state not specifically modeled in archlib.</comment>\n");
662 TRACE_SPRINTF("\t\t<comment> Have also noticed inconsistencies in the final value of the RFLAGS reg.</comment>\n");
663 if (g_triggerFound != -1)
664 {
665 TRACE_SPRINTF("\t\t<comment> This capture is generated for HOST BASED TRIGGER # %lld.</comment>\n", g_triggerFound);
666 g_triggerFound = -1;
667 }
668 TRACE_SPRINTF("\t</header>\n");
669 TRACE_SPRINTF("\t<cpu_definition>\n");
670 TRACE_SPRINTF("\t\t<num_cpus>%d</num_cpus>\n", num_online_cpus());
671 TRACE_SPRINTF("<!-- the number of \"cpu\" definitions must correspond to the \"num_cpus\" data item -->\n");
672
673 for (i = 0; i < num_online_cpus(); i++)
674 {
675 TRACE_SPRINTF("\t\t<cpu num=\"%d\">\n", i);
676// SPU is not supported in Linux
677 if (always_false) mictc_trace_capture_prep_SPU_header();
678 mictc_trace_capture_prep_cpuid_header();
679 mictc_trace_capture_prep_msr_header();
680 TRACE_SPRINTF("\t\t</cpu>\n");
681 }
682
683 TRACE_SPRINTF("\t</cpu_definition>\n");
684 TRACE_SPRINTF("\t<platform_definition>\n");
685 TRACE_SPRINTF("\t\t<physical_memory/>\n");
686 TRACE_SPRINTF("\t</platform_definition>\n");
687 TRACE_SPRINTF("\t<cpu_state>\n");
688 TRACE_SPRINTF("<!-- the number of \"cpu\" definitions must correspond to the \"num_cpus\" data item -->\n");
689}
690
691
692//------------------------------------------------------------------------------
693// FUNCTION: mictc_capture_general_purpose_reg
694//
695// DESCRIPTION:
696// Capture all general purpose registers.
697//
698// PARAMETERS: None
699//
700// RETURNS: None
701//
702// TODOS:
703//
704static void
705mictc_capture_general_purpose_reg(struct pt_regs *regs)
706{
707 // printk("starting reg dump regs=%llx\n", (uint64_t)regs);
708
709 if (!regs) {
710 printk("Null pointer found. cpu %d %s\n", smp_processor_id(), current->comm);
711 return;
712 }
713
714 TRACE_SPRINTF("\t\t\t<general>\n");
715 TRACE_SPRINTF("\t\t\t\t<reg name=\"RAX\">0x%lx</reg>\n", regs->ax);
716 TRACE_SPRINTF("\t\t\t\t<reg name=\"RBX\">0x%lx</reg>\n", regs->bx);
717 TRACE_SPRINTF("\t\t\t\t<reg name=\"RCX\">0x%lx</reg>\n", regs->cx);
718 TRACE_SPRINTF("\t\t\t\t<reg name=\"RDX\">0x%lx</reg>\n", regs->dx);
719 TRACE_SPRINTF("\t\t\t\t<reg name=\"RBP\">0x%lx</reg>\n", regs->bp);
720 TRACE_SPRINTF("\t\t\t\t<reg name=\"RSP\">0x%lx</reg>\n", regs->sp);
721 TRACE_SPRINTF("\t\t\t\t<reg name=\"RSI\">0x%lx</reg>\n", regs->si);
722 TRACE_SPRINTF("\t\t\t\t<reg name=\"RDI\">0x%lx</reg>\n", regs->di);
723 TRACE_SPRINTF("\t\t\t\t<reg name=\"R8\">0x%lx</reg>\n", regs->r8);
724 TRACE_SPRINTF("\t\t\t\t<reg name=\"R9\">0x%lx</reg>\n", regs->r9);
725 TRACE_SPRINTF("\t\t\t\t<reg name=\"R10\">0x%lx</reg>\n", regs->r10);
726 TRACE_SPRINTF("\t\t\t\t<reg name=\"R11\">0x%lx</reg>\n", regs->r11);
727 TRACE_SPRINTF("\t\t\t\t<reg name=\"R12\">0x%lx</reg>\n", regs->r12);
728 TRACE_SPRINTF("\t\t\t\t<reg name=\"R13\">0x%lx</reg>\n", regs->r13);
729 TRACE_SPRINTF("\t\t\t\t<reg name=\"R14\">0x%lx</reg>\n", regs->r14);
730 TRACE_SPRINTF("\t\t\t\t<reg name=\"R15\">0x%lx</reg>\n", regs->r15);
731// In cases where a CPU is halted and is woken up from halt by the trace capture IPI
732// we want to report the RIP as the one pointing to the halt instruction itself
733// and not the one on the trap frame. This is to avoid the condition where the simulator-run
734// for these halted CPUs ends up running extra cycles (before going back idle)
735// which would not happen under actual conditions. Problem reported by Jason S.
736//// if(regs->tf_rip == (register_t)ExitIdle)
737//// TRACE_SPRINTF("\t\t\t\t<reg name=\"RIP\">0x%lx</reg>\n", regs->ip-1);
738//// else
739 TRACE_SPRINTF("\t\t\t\t<reg name=\"RIP\">0x%lx</reg>\n", regs->ip);
740 TRACE_SPRINTF("\t\t\t\t<reg name=\"RFLAGS\">0x%lx</reg>\n", regs->flags);
741 TRACE_SPRINTF("\t\t\t</general>\n");
742
743 // printk("ending reg dump\n");
744}
745
746
747//------------------------------------------------------------------------------
748// FUNCTION: mictc_capture_segment_reg
749//
750// DESCRIPTION:
751// Capture all segment registers.
752//
753// PARAMETERS: None
754//
755// RETURNS: None
756//
757// TODOS:
758//
759static void
760mictc_capture_segment_reg(struct mictc_segment_reg *segment, struct pt_regs *regs)
761{
762 int i, v;
763 struct desc_ptr gdtr;
764 struct desc_ptr idtr;
765 struct mictc_seg *segreg;
766
767// printk("Segment registers on cpu %d\n", smp_processor_id());
768
769 // This is only useful during initial development.
770 if (!regs) {
771 printk("Null pointer found. cpu %d %s\n", smp_processor_id(), current->comm);
772 return;
773 }
774
775 segment->cs.selector = (u16)regs->cs;
776 segment->ss.selector = (u16)regs->ss;
777#if 0
778 if (ISPL(regs->tf_cs) == SEL_KPL && curthread->td_pcb->pcb_ds == 0x0) {
779 // Specifically required for kernel IDLE thread
780 segment->ds = 0x10;
781 segment->es = 0x10;
782 segment->fs = 0x10;
783 segment->gs = 0x10;
784 } else {
785#endif
786 asm("movl %%ds,%0" : "=r" (v)); segment->ds.selector = v;
787 asm("movl %%es,%0" : "=r" (v)); segment->es.selector = v;
788 segment->fs.selector = current->thread.fs;
789 segment->gs.selector = current->thread.gs;
790// }
791 mictc_store_tr(&(segment->tr.selector));
792 get_tss_desc(smp_processor_id(), &(segment->tr.desc));
793 store_gdt(&gdtr);
794 store_idt(&idtr);
795 mictc_store_ldt(&(segment->ldtr.selector));
796 // LDT is not used, so zeros will be printed.
797
798 TRACE_SPRINTF("\t\t\t<segment>\n");
799 segreg = (struct mictc_seg *)&(segment->cs);
800
801 for(i=0; i < MAX_SEG_REG; i++) {
802 if (strcmp(SegRegNames[i], "GS") == 0) {
803 segreg->base = tc_rdmsr(MSR_KGSBASE);
804 }
805 if (strcmp(SegRegNames[i], "FS") == 0) {
806 segreg->base = tc_rdmsr(MSR_FSBASE);
807 }
808
809 // Fill in the segment descriptor for cs to gs
810 if (i <= 5) {
811 get_seg_desc(smp_processor_id(), segreg->selector, &(segreg->desc));
812 }
813
814 TRACE_SPRINTF("\t\t\t\t<reg name=\"%s\">\n",SegRegNames[i]);
815 if (i > 5) { // LDT and TSS
816 struct mictc_tss *segreg1 =(struct mictc_tss *)segreg;
817
818 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"base\">0x%llx</attr>\n", ((uint64_t)segreg1->desc.base3 << 32) | (uint64_t)((segreg1->desc.base2 << 24) | (segreg1->desc.base1 << 16) | segreg1->desc.base0));
819 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"limit\">0x%x</attr>\n", (segreg1->desc.limit1 << 16) | segreg1->desc.limit0);
820 TRACE_SPRINTF("\t\t\t\t\t<selector>0x%x</selector>\n", segreg1->selector);
821 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"G\">0x%x</attr>\n", segreg1->desc.g);
822 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"DB\">0x%x</attr>\n", 0); // double word of base and limit
823 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"L\">0x%x</attr>\n", 0);
824 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"AVL\">0x0</attr>\n");//AVL bit not populated in the gdt[] array
825 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"P\">0x%x</attr>\n", segreg1->desc.p);
826 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"DPL\">0x%x</attr>\n", segreg1->desc.dpl);
827 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"S\">0x%x</attr>\n", segreg1->desc.type & 0x10 ? 1 : 0); //The S bit (descriptor type) is clubbed along with the ssd_type element.
828 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"TYPE\">0x%x</attr>\n", (segreg1->desc.type & 0xf));
829 } else {
830 if (segreg->base) {
831 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"base\">0x%llx</attr>\n", segreg->base);
832 } else {
833 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"base\">0x%x</attr>\n", (segreg->desc.base2 << 24) | (segreg->desc.base1 << 16) |segreg->desc.base0);
834 }
835 if (segreg->desc.l) segreg->desc.a = 0;
836 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"limit\">0x%x</attr>\n", (segreg->desc.limit << 16) | segreg->desc.limit0);
837 TRACE_SPRINTF("\t\t\t\t\t<selector>0x%x</selector>\n", segreg->selector);
838 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"G\">0x%x</attr>\n", segreg->desc.g);
839 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"DB\">0x%x</attr>\n", segreg->desc.a & 1); // double word of base and limit
840 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"L\">0x%x</attr>\n", segreg->desc.l);
841 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"AVL\">0x0</attr>\n");//AVL bit not populated in the gdt[] array
842 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"P\">0x%x</attr>\n", segreg->desc.p);
843 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"DPL\">0x%x</attr>\n", segreg->desc.dpl);
844 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"S\">0x%x</attr>\n", segreg->desc.type & 0x10 ? 1 : 0); //The S bit (descriptor type) is clubbed along with the ssd_type element.
845 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"TYPE\">0x%x</attr>\n", (segreg->desc.type & 0xf));
846 }
847 TRACE_SPRINTF("\t\t\t\t</reg>\n");
848 segreg++;
849 }
850
851 TRACE_SPRINTF("\t\t\t\t<reg name=\"GDTR\">\n");
852 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"base\">0x%lx</attr>\n", gdtr.address);
853 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"limit\">0x%x</attr>\n", gdtr.size);
854 TRACE_SPRINTF("\t\t\t\t</reg>\n");
855 TRACE_SPRINTF("\t\t\t\t<reg name=\"IDTR\">\n");
856 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"base\">0x%lx</attr>\n", idtr.address);
857 TRACE_SPRINTF("\t\t\t\t\t<attr name=\"limit\">0x%x</attr>\n", idtr.size);
858 TRACE_SPRINTF("\t\t\t\t</reg>\n");
859
860 TRACE_SPRINTF("\t\t\t</segment>\n");
861
862// printk("End of mictc_capture_segment_reg\n");
863
864}
865
866
867//------------------------------------------------------------------------------
868// FUNCTION: mictc_capture_debug_reg
869//
870// DESCRIPTION:
871// Capture all debug registers.
872//
873// PARAMETERS: None
874//
875// RETURNS: None
876//
877// TODOS:
878//
879static void
880mictc_capture_debug_reg(void)
881{
882 TRACE_SPRINTF("\t\t\t<debug>\n");
883 TRACE_SPRINTF("\t\t\t\t<reg name=\"DR0\">0x%x</reg>\n", get_dr(0));
884 TRACE_SPRINTF("\t\t\t\t<reg name=\"DR1\">0x%x</reg>\n", get_dr(1));
885 TRACE_SPRINTF("\t\t\t\t<reg name=\"DR2\">0x%x</reg>\n", get_dr(2));
886 TRACE_SPRINTF("\t\t\t\t<reg name=\"DR3\">0x%x</reg>\n", get_dr(3));
887// These don't exist.
888// TRACE_SPRINTF("\t\t\t\t<reg name=\"DR4\">0x%x</reg>\n", get_dr(4));
889// TRACE_SPRINTF("\t\t\t\t<reg name=\"DR5\">0x%x</reg>\n", get_dr(5));
890 TRACE_SPRINTF("\t\t\t\t<reg name=\"DR6\">0x%x</reg>\n", get_dr(6));
891 TRACE_SPRINTF("\t\t\t\t<reg name=\"DR7\">0x%x</reg>\n", get_dr(7));
892 TRACE_SPRINTF("\t\t\t</debug>\n");
893}
894
895
896//------------------------------------------------------------------------------
897// FUNCTION: mictc_capture_control_reg
898//
899// DESCRIPTION:
900// Capture all control registers.
901//
902// PARAMETERS: None
903//
904// RETURNS: None
905//
906// TODOS:
907//
908static void
909mictc_capture_control_reg(void)
910{
911 TRACE_SPRINTF("\t\t\t<control>\n");
912 TRACE_SPRINTF("\t\t\t\t<reg name=\"CR0\">0x%lx</reg>\n", (read_cr0()) & 0xffffffff);
913 TRACE_SPRINTF("\t\t\t\t<reg name=\"CR2\">0x%lx</reg>\n", read_cr2());
914 TRACE_SPRINTF("\t\t\t\t<reg name=\"CR3\">0x%lx</reg>\n", read_cr3());
915 TRACE_SPRINTF("\t\t\t\t<reg name=\"CR4\">0x%lx</reg>\n", (read_cr4()) & 0xffffffff);
916 TRACE_SPRINTF("\t\t\t\t<reg name=\"CR8\">0x%lx</reg>\n", read_cr8());
917 TRACE_SPRINTF("\t\t\t</control>\n");
918}
919
920
921//------------------------------------------------------------------------------
922// FUNCTION: mictc_capture_SPU_reg
923//
924// DESCRIPTION:
925// Capture all SPU registers.
926//
927// PARAMETERS: None
928//
929// RETURNS: None
930//
931// TODOS:
932//
933static void
934mictc_capture_SPU_reg(void)
935{
936#if 0
937 // FIXME - The SPU is not setup currently in Linux
938
939 TRACE_SPRINTF("\t\t\t<spu>\n");
940 TRACE_SPRINTF_SPU(SPU_XQ_SIZE);
941 TRACE_SPRINTF_SPU(SPU_XQ_BASE);
942 TRACE_SPRINTF_SPU(SPU_XQ_INDEX);
943 TRACE_SPRINTF_SPU(SPU_CONTROL);
944 TRACE_SPRINTF_SPU(SPU_SAMPLER_BASE);
945 TRACE_SPRINTF_SPU(SPU_PMU_EVENT_SEL);
946 TRACE_SPRINTF_SPU(SPU_CONTROL2);
947 TRACE_SPRINTF_SPU(SPU_CONTROL3);
948 TRACE_SPRINTF("\t\t\t</spu>\n");
949#endif
950}
951
952
953//------------------------------------------------------------------------------
954// FUNCTION: PrintVector
955//
956// DESCRIPTION:
957// Prints _m512 vectors
958//
959// PARAMETERS: None
960//
961// RETURNS: None
962//
963// TODOS:
964//
965static void
966PrintVector(u8 *res_mem, int reg_num)
967{
968 TRACE_SPRINTF("\t\t\t\t<reg name=\"V%d\">0x"
969 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
970 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
971 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
972 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x</reg>\n",
973 reg_num,
974 res_mem[63], res_mem[62], res_mem[61], res_mem[60], res_mem[59], res_mem[58], res_mem[57], res_mem[56],
975 res_mem[55], res_mem[54], res_mem[53], res_mem[52], res_mem[51], res_mem[50], res_mem[49], res_mem[48],
976 res_mem[47], res_mem[46], res_mem[45], res_mem[44], res_mem[43], res_mem[42], res_mem[41], res_mem[40],
977 res_mem[39], res_mem[38], res_mem[37], res_mem[36], res_mem[35], res_mem[34], res_mem[33], res_mem[32],
978 res_mem[31], res_mem[30], res_mem[29], res_mem[28], res_mem[27], res_mem[26], res_mem[25], res_mem[24],
979 res_mem[23], res_mem[22], res_mem[21], res_mem[20], res_mem[19], res_mem[18], res_mem[17], res_mem[16],
980 res_mem[15], res_mem[14], res_mem[13], res_mem[12], res_mem[11], res_mem[10], res_mem[9], res_mem[8],
981 res_mem[7], res_mem[6], res_mem[5], res_mem[4], res_mem[3], res_mem[2], res_mem[1], res_mem[0]);
982}
983
984
985//------------------------------------------------------------------------------
986// FUNCTION: PrintFPRegister
987//
988// DESCRIPTION:
989// Prints 10 byte FP register contents
990//
991// PARAMETERS: None
992//
993// RETURNS: None
994//
995// TODOS:
996//
997static void
998PrintFPRegister(u8 *res_mem, int reg_num)
999{
1000 TRACE_SPRINTF("\t\t\t\t<reg name=\"FR%d\">0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x</reg>\n",
1001 reg_num,
1002 res_mem[9],
1003 res_mem[8],
1004 res_mem[7],
1005 res_mem[6],
1006 res_mem[5],
1007 res_mem[4],
1008 res_mem[3],
1009 res_mem[2],
1010 res_mem[1],
1011 res_mem[0]);
1012}
1013
1014
1015// VPU Instructions
1016
1017#ifdef CONFIG_ML1OM
1018#define VSTORED_DISP32_EAX(v, disp32) " vstored %%v" #v "," #disp32 "(%%rax)\n"
1019
1020#define VKSTORE_DISP32_EAX(k, disp32) \
1021 " vkmov %%k" #k ",%%ebx\n" \
1022 " movw %%bx, " #disp32 "(%%rax)\n"
1023
1024#define STVXCSR_DISP32_EAX(disp32) " stvxcsr " #disp32 "(%%rax)\n"
1025
1026#else
1027// For K1OM
1028#define VSTORED_DISP32_EAX(v, disp32) " vpackstorelps %%zmm" #v "," #disp32 "(%%rax)\n"
1029
1030#define VKSTORE_DISP32_EAX(k, disp32) \
1031 " kmov %%k" #k ",%%ebx\n" \
1032 " movw %%bx, " #disp32 "(%%rax)\n"
1033
1034#define STVXCSR_DISP32_EAX(disp32) " stmxcsr " #disp32 "(%%rax)\n"
1035#endif
1036
1037static inline void save_vpu(struct vpustate_struct *vpustate)
1038{
1039 asm volatile(
1040 VSTORED_DISP32_EAX(0, 0x00)
1041 VSTORED_DISP32_EAX(1, 0x40)
1042 VSTORED_DISP32_EAX(2, 0x80)
1043 VSTORED_DISP32_EAX(3, 0xc0)
1044 VSTORED_DISP32_EAX(4, 0x100)
1045 VSTORED_DISP32_EAX(5, 0x140)
1046 VSTORED_DISP32_EAX(6, 0x180)
1047 VSTORED_DISP32_EAX(7, 0x1c0)
1048 VSTORED_DISP32_EAX(8, 0x200)
1049 VSTORED_DISP32_EAX(9, 0x240)
1050 VSTORED_DISP32_EAX(10, 0x280)
1051 VSTORED_DISP32_EAX(11, 0x2c0)
1052 VSTORED_DISP32_EAX(12, 0x300)
1053 VSTORED_DISP32_EAX(13, 0x340)
1054 VSTORED_DISP32_EAX(14, 0x380)
1055 VSTORED_DISP32_EAX(15, 0x3c0)
1056 VSTORED_DISP32_EAX(16, 0x400)
1057 VSTORED_DISP32_EAX(17, 0x440)
1058 VSTORED_DISP32_EAX(18, 0x480)
1059 VSTORED_DISP32_EAX(19, 0x4c0)
1060 VSTORED_DISP32_EAX(20, 0x500)
1061 VSTORED_DISP32_EAX(21, 0x540)
1062 VSTORED_DISP32_EAX(22, 0x580)
1063 VSTORED_DISP32_EAX(23, 0x5c0)
1064 VSTORED_DISP32_EAX(24, 0x600)
1065 VSTORED_DISP32_EAX(25, 0x640)
1066 VSTORED_DISP32_EAX(26, 0x680)
1067 VSTORED_DISP32_EAX(27, 0x6c0)
1068 VSTORED_DISP32_EAX(28, 0x700)
1069 VSTORED_DISP32_EAX(29, 0x740)
1070 VSTORED_DISP32_EAX(30, 0x780)
1071 VSTORED_DISP32_EAX(31, 0x7c0)
1072 VKSTORE_DISP32_EAX(0, 0x800)
1073 VKSTORE_DISP32_EAX(1, 0x802)
1074 VKSTORE_DISP32_EAX(2, 0x804)
1075 VKSTORE_DISP32_EAX(3, 0x806)
1076 VKSTORE_DISP32_EAX(4, 0x808)
1077 VKSTORE_DISP32_EAX(5, 0x80a)
1078 VKSTORE_DISP32_EAX(6, 0x80c)
1079 VKSTORE_DISP32_EAX(7, 0x80e)
1080 STVXCSR_DISP32_EAX(0x810)
1081 : "=m" (vpustate) : [fx] "a" (vpustate) : "ebx"
1082 );
1083}
1084
1085
1086//------------------------------------------------------------------------------
1087// FUNCTION: mictc_capture_vector_reg
1088//
1089// DESCRIPTION:
1090// Capture all vector registers.
1091//
1092// PARAMETERS: None
1093//
1094// RETURNS: None
1095//
1096// TODOS:
1097//
1098static void
1099mictc_capture_vector_reg(struct vpustate_struct *vpustate)
1100{
1101 // printk("vpustate = %p\n", vpustate);
1102
1103 save_vpu(vpustate);
1104
1105 TRACE_SPRINTF("\t\t\t<vpu>\n");
1106 TRACE_SPRINTF("\t\t\t\t<reg name=\"K0\">0x%x</reg>\n", vpustate->k[0]);
1107 TRACE_SPRINTF("\t\t\t\t<reg name=\"K1\">0x%x</reg>\n", vpustate->k[1]);
1108 TRACE_SPRINTF("\t\t\t\t<reg name=\"K2\">0x%x</reg>\n", vpustate->k[2]);
1109 TRACE_SPRINTF("\t\t\t\t<reg name=\"K3\">0x%x</reg>\n", vpustate->k[3]);
1110 TRACE_SPRINTF("\t\t\t\t<reg name=\"K4\">0x%x</reg>\n", vpustate->k[4]);
1111 TRACE_SPRINTF("\t\t\t\t<reg name=\"K5\">0x%x</reg>\n", vpustate->k[5]);
1112 TRACE_SPRINTF("\t\t\t\t<reg name=\"K6\">0x%x</reg>\n", vpustate->k[6]);
1113 TRACE_SPRINTF("\t\t\t\t<reg name=\"K7\">0x%x</reg>\n", vpustate->k[7]);
1114 TRACE_SPRINTF_VECTOR(0, vpustate->vector_space[0]);
1115 TRACE_SPRINTF_VECTOR(1, vpustate->vector_space[16]);
1116 TRACE_SPRINTF_VECTOR(2, vpustate->vector_space[32]);
1117 TRACE_SPRINTF_VECTOR(3, vpustate->vector_space[48]);
1118 TRACE_SPRINTF_VECTOR(4, vpustate->vector_space[64]);
1119 TRACE_SPRINTF_VECTOR(5, vpustate->vector_space[80]);
1120 TRACE_SPRINTF_VECTOR(6, vpustate->vector_space[96]);
1121 TRACE_SPRINTF_VECTOR(7, vpustate->vector_space[112]);
1122 TRACE_SPRINTF_VECTOR(8, vpustate->vector_space[128]);
1123 TRACE_SPRINTF_VECTOR(9, vpustate->vector_space[144]);
1124 TRACE_SPRINTF_VECTOR(10, vpustate->vector_space[160]);
1125 TRACE_SPRINTF_VECTOR(11, vpustate->vector_space[176]);
1126 TRACE_SPRINTF_VECTOR(12, vpustate->vector_space[192]);
1127 TRACE_SPRINTF_VECTOR(13, vpustate->vector_space[208]);
1128 TRACE_SPRINTF_VECTOR(14, vpustate->vector_space[224]);
1129 TRACE_SPRINTF_VECTOR(15, vpustate->vector_space[240]);
1130 TRACE_SPRINTF_VECTOR(16, vpustate->vector_space[256]);
1131 TRACE_SPRINTF_VECTOR(17, vpustate->vector_space[272]);
1132 TRACE_SPRINTF_VECTOR(18, vpustate->vector_space[288]);
1133 TRACE_SPRINTF_VECTOR(19, vpustate->vector_space[304]);
1134 TRACE_SPRINTF_VECTOR(20, vpustate->vector_space[320]);
1135 TRACE_SPRINTF_VECTOR(21, vpustate->vector_space[336]);
1136 TRACE_SPRINTF_VECTOR(22, vpustate->vector_space[352]);
1137 TRACE_SPRINTF_VECTOR(23, vpustate->vector_space[368]);
1138 TRACE_SPRINTF_VECTOR(24, vpustate->vector_space[384]);
1139 TRACE_SPRINTF_VECTOR(25, vpustate->vector_space[400]);
1140 TRACE_SPRINTF_VECTOR(26, vpustate->vector_space[416]);
1141 TRACE_SPRINTF_VECTOR(27, vpustate->vector_space[432]);
1142 TRACE_SPRINTF_VECTOR(28, vpustate->vector_space[448]);
1143 TRACE_SPRINTF_VECTOR(29, vpustate->vector_space[464]);
1144 TRACE_SPRINTF_VECTOR(30, vpustate->vector_space[480]);
1145 TRACE_SPRINTF_VECTOR(31, vpustate->vector_space[496]);
1146 TRACE_SPRINTF("\t\t\t\t<reg name=\"VXCSR\">0x%x</reg>\n", vpustate->vxcsr);
1147 TRACE_SPRINTF("\t\t\t</vpu>\n");
1148}
1149
1150//------------------------------------------------------------------------------
1151// FUNCTION: mictc_capture_FPU_reg
1152//
1153// DESCRIPTION:
1154// Capture all FPU registers.
1155//
1156// PARAMETERS: None
1157//
1158// RETURNS: None
1159//
1160// TODOS:
1161//
1162static void
1163mictc_capture_FPU_reg(struct i387_fxsave_struct *fpu)
1164{
1165
1166/*
1167 Get FPU contents from the registers instead of the PCB.
1168 fxsave on L1OM saves only the x87 FPU registers and not the SSE2 and MMX registers.
1169 For format of the data below refer Intel 64 and IA-32 Arch. SDM Vol 2A Instr Set Ref A-M
1170 tables 3-59 & 3-60.
1171*/
1172 mictc_fxsave(fpu);
1173
1174 TRACE_SPRINTF("\t\t\t<fp>\n");
1175 TRACE_SPRINTF("\t\t\t\t<reg name=\"CW\">0x%x</reg>\n", fpu->cwd);
1176 TRACE_SPRINTF("\t\t\t\t<reg name=\"SW\">0x%x</reg>\n", fpu->swd);
1177 TRACE_SPRINTF("\t\t\t\t<reg name=\"TW\">0x%x</reg>\n", (fpu->twd));
1178 TRACE_SPRINTF("\t\t\t\t<reg name=\"FCS\">0x%x</reg>\n", (fpu->fcs & 0xffff));
1179 TRACE_SPRINTF("\t\t\t\t<reg name=\"OPCODE\">0x%x</reg>\n", fpu->fop);
1180 TRACE_SPRINTF("\t\t\t\t<reg name=\"FDS\">0x%x</reg>\n", (fpu->fos & 0xffff));
1181 TRACE_SPRINTF("\t\t\t\t<reg name=\"FIP\">0x%x</reg>\n", fpu->fip);
1182 TRACE_SPRINTF("\t\t\t\t<reg name=\"DATAOP\">0x%x</reg>\n", (fpu->foo));
1183 PrintFPRegister((u8 *)&(fpu->st_space[0]), 0);
1184 PrintFPRegister((u8 *)&(fpu->st_space[4]), 1);
1185 PrintFPRegister((u8 *)&(fpu->st_space[8]), 2);
1186 PrintFPRegister((u8 *)&(fpu->st_space[12]), 3);
1187 PrintFPRegister((u8 *)&(fpu->st_space[16]), 4);
1188 PrintFPRegister((u8 *)&(fpu->st_space[20]), 5);
1189 PrintFPRegister((u8 *)&(fpu->st_space[24]), 6);
1190 PrintFPRegister((u8 *)&(fpu->st_space[28]), 7);
1191 TRACE_SPRINTF("\t\t\t</fp>\n");
1192
1193#if 0
1194 printk("00 %08x %08x\n", ((u32*)fpu)[0], ((u32*)fpu)[1]);
1195 printk("08 %08x %08x\n", ((u32*)fpu)[2], ((u32*)fpu)[3]);
1196 printk("10 %08x %08x\n", ((u32*)fpu)[4], ((u32*)fpu)[5]);
1197 printk("18 %08x %08x\n", ((u32*)fpu)[6], ((u32*)fpu)[7]);
1198 printk("20 %08x %08x\n", ((u32*)fpu)[8], ((u32*)fpu)[9]);
1199 printk("28 %08x %08x\n", ((u32*)fpu)[10], ((u32*)fpu)[11]);
1200 printk("30 %08x %08x\n", ((u32*)fpu)[12], ((u32*)fpu)[13]);
1201 printk("38 %08x %08x\n", ((u32*)fpu)[14], ((u32*)fpu)[15]);
1202 printk("40 %08x %08x\n", ((u32*)fpu)[16], ((u32*)fpu)[17]);
1203 printk("48 %08x %08x\n", ((u32*)fpu)[18], ((u32*)fpu)[19]);
1204 printk("50 %08x %08x\n", ((u32*)fpu)[20], ((u32*)fpu)[21]);
1205 printk("58 %08x %08x\n", ((u32*)fpu)[22], ((u32*)fpu)[23]);
1206 printk("60 %08x %08x\n", ((u32*)fpu)[24], ((u32*)fpu)[25]);
1207 printk("68 %08x %08x\n", ((u32*)fpu)[26], ((u32*)fpu)[27]);
1208 printk("70 %08x %08x\n", ((u32*)fpu)[28], ((u32*)fpu)[29]);
1209 printk("78 %08x %08x\n", ((u32*)fpu)[30], ((u32*)fpu)[31]);
1210 printk("80 %08x %08x\n", ((u32*)fpu)[32], ((u32*)fpu)[33]);
1211 printk("88 %08x %08x\n", ((u32*)fpu)[34], ((u32*)fpu)[35]);
1212 printk("90 %08x %08x\n", ((u32*)fpu)[36], ((u32*)fpu)[37]);
1213 printk("98 %08x %08x\n", ((u32*)fpu)[38], ((u32*)fpu)[39]);
1214#endif
1215}
1216
1217
1218//------------------------------------------------------------------------------
1219// FUNCTION: mictc_capture_MSR
1220//
1221// DESCRIPTION:
1222// Capture all MSR
1223//
1224// PARAMETERS: None
1225//
1226// RETURNS: None
1227//
1228// TODOS:
1229//
1230static void
1231mictc_capture_MSR(void)
1232{
1233 // u32 me_cpu = PCPU_GET(cpuid);
1234#if 0
1235 //msr->msrMIC_CR_SPUBASE = tc_rdmsr(MIC_CR_SPUBASE);
1236 //msr->msrIA32_CR_MISC = tc_rdmsr(IA32_CR_MISC);
1237 //msr->msrWMT_CR_LASTBRANCH_0 = tc_rdmsr(WMT_CR_LASTBRANCH_0);
1238 //msr->msrWMT_CR_LASTBRANCH_1 = tc_rdmsr(WMT_CR_LASTBRANCH_1);
1239 msr->msrVMX_MSR_BASE = tc_rdmsr(VMX_MSR_BASE);
1240 msr->msrVMX_MSR_BASE_PLUS_1 = tc_rdmsr(VMX_MSR_BASE_PLUS_1);
1241 msr->msrVMX_MSR_BASE_PLUS_2 = tc_rdmsr(VMX_MSR_BASE_PLUS_2);
1242 msr->msrVMX_MSR_BASE_PLUS_3 = tc_rdmsr(VMX_MSR_BASE_PLUS_3);
1243 msr->msrVMX_MSR_BASE_PLUS_4 = tc_rdmsr(VMX_MSR_BASE_PLUS_4);
1244 msr->msrVMX_MSR_BASE_PLUS_5 = tc_rdmsr(VMX_MSR_BASE_PLUS_5);
1245 msr->msrVMX_MSR_BASE_PLUS_6 = tc_rdmsr(VMX_MSR_BASE_PLUS_6);
1246 msr->msrVMX_MSR_BASE_PLUS_7 = tc_rdmsr(VMX_MSR_BASE_PLUS_7);
1247 msr->msrVMX_MSR_BASE_PLUS_8 = tc_rdmsr(VMX_MSR_BASE_PLUS_8);
1248 msr->msrVMX_MSR_BASE_PLUS_9 = tc_rdmsr(VMX_MSR_BASE_PLUS_9);
1249 msr->msrTIME = tc_rdmsr(TIME);
1250 msr->msrPINFO = tc_rdmsr(PINFO);
1251#endif
1252 TRACE_SPRINTF("\t\t\t<msr>\n");
1253 TRACE_SPRINTF_MSR(P6_CR_TSC);
1254 TRACE_SPRINTF_MSR(X86_CR_APICBASE);
1255 TRACE_SPRINTF_MSR(CBOX_SPU_PA_MSR);
1256 // This is being added since it is included in the ITP dump as well.
1257 TRACE_SPRINTF("\t\t\t\t<reg addr=\"0x%x\">0x%llx</reg>\n", SPU_BASE, (tc_rdmsr(CBOX_SPU_PA_MSR) & 0x7fffffffffffffff) + 0x1000);
1258 TRACE_SPRINTF_MSR(CBOX_SPU_SAMPLER_BIND_MSR);
1259 TRACE_SPRINTF_MSR(X86_CR_MTRRphysMask0);
1260 TRACE_SPRINTF_MSR(X86_CR_MTRRphysMask1);
1261 TRACE_SPRINTF_MSR(X86_CR_MTRRphysMask2);
1262 TRACE_SPRINTF_MSR(X86_CR_MTRRphysMask3);
1263 TRACE_SPRINTF_MSR(X86_CR_MTRRphysMask4);
1264 TRACE_SPRINTF_MSR(X86_CR_MTRRphysMask5);
1265 TRACE_SPRINTF_MSR(X86_CR_MTRRphysMask6);
1266 TRACE_SPRINTF_MSR(X86_CR_MTRRphysMask7);
1267 TRACE_SPRINTF_MSR(MSR_EFER & ~0x800); // Force bit 11 to 0
1268 TRACE_SPRINTF_MSR(MSR_SF_MASK);
1269 TRACE_SPRINTF_MSR(MSR_FSBASE);
1270 TRACE_SPRINTF_MSR(MSR_GSBASE);
1271 TRACE_SPRINTF_MSR(X86_CR_MTRRcap);
1272 TRACE_SPRINTF_MSR(X86_CR_MTRRdefType);
1273 TRACE_SPRINTF_MSR(X86_CR_MTRRphysBase2);
1274 TRACE_SPRINTF_MSR(X86_CR_MTRRphysBase0);
1275 TRACE_SPRINTF_MSR(X86_CR_MTRRphysBase1);
1276 TRACE_SPRINTF_MSR(X86_CR_MTRRphysBase3);
1277 TRACE_SPRINTF_MSR(X86_CR_MTRRphysBase4);
1278 TRACE_SPRINTF_MSR(X86_CR_MTRRphysBase5);
1279 TRACE_SPRINTF_MSR(X86_CR_MTRRphysBase6);
1280 TRACE_SPRINTF_MSR(X86_CR_MTRRphysBase7);
1281 TRACE_SPRINTF_MSR(STAR);
1282 TRACE_SPRINTF_MSR(LSTAR);
1283
1284 // MSR_KGSBASE needs some special handling.
1285 // On Silicon when a thread transitions from Ring 3->Ring 0 the
1286 // first instruction it executes is swapgs which swaps the value
1287 // of the current GSBase (which could be 0x0) with the value in
1288 // MSR_KGSBASE to get to the per cpu data structure and onwards to the kernel stack.
1289 // On Silicon, when the same thread transitions from Ring 0->Ring 3 MSR_KGSBASE gets
1290 // the right value as a result of another swapgs on the way back.
1291 // Where Trace Capture differs from Silicon is that we take a snapshot while executing
1292 // in Ring 0 (when MSR_KGSBASE could be 0x0) but the first instruction
1293 // which executes on LarrySim is a Ring 3 instruction.
1294 // On the first syscall in LarrySim when it executes a swapgs it sees a MSR_KGSBASE value of 0x0.
1295 // LarrySim cannot get to the kernel stack and we correctly hit a double fault (Bang!).
1296 // The correct fix is to ensure that LarrySim sees a correct value of
1297 // MSR_KGSBASE when it is provided a snapshot.
1298//FIXME
1299// TRACE_SPRINTF("\t\t\t\t<reg addr=\"0x%x\">0x%lx</reg>\n", MSR_KGSBASE, &__pcpu[me_cpu]);
1300
1301 // The following MSR's are currently ifdef'd out
1302 // because LarrySim barfs on these.
1303 // We might need these later.
1304#if 0
1305 TRACE_SPRINTF_MSR(X86_CR_MTRRfix64K_00000);
1306 TRACE_SPRINTF_MSR(X86_CR_MTRRfix16K_80000);
1307 TRACE_SPRINTF_MSR(X86_CR_MTRRfix16K_A0000);
1308 TRACE_SPRINTF_MSR(X86_CR_MTRRfix4K_C0000);
1309 TRACE_SPRINTF_MSR(X86_CR_MTRRfix4K_C8000);
1310 TRACE_SPRINTF_MSR(X86_CR_MTRRfix4K_D0000);
1311 TRACE_SPRINTF_MSR(X86_CR_MTRRfix4K_D8000);
1312 TRACE_SPRINTF_MSR(X86_CR_MTRRfix4K_E0000);
1313 TRACE_SPRINTF_MSR(X86_CR_MTRRfix4K_E8000);
1314 TRACE_SPRINTF_MSR(X86_CR_MTRRfix4K_F0000);
1315 TRACE_SPRINTF_MSR(X86_CR_MTRRfix4K_F8000);
1316 TRACE_SPRINTF_MSR(P5_MC_ADDR);
1317 TRACE_SPRINTF_MSR(P5_MC_TYPE);
1318 TRACE_SPRINTF_MSR(MSR_TR1);
1319 TRACE_SPRINTF_MSR(MSR_TR2);
1320 TRACE_SPRINTF_MSR(MSR_TR3);
1321 TRACE_SPRINTF_MSR(MSR_TR4);
1322 TRACE_SPRINTF_MSR(MSR_TR5);
1323 TRACE_SPRINTF_MSR(MSR_TR6);
1324 TRACE_SPRINTF_MSR(MSR_TR7);
1325 TRACE_SPRINTF_MSR(MSR_TR9);
1326 TRACE_SPRINTF_MSR(MSR_TR10);
1327 TRACE_SPRINTF_MSR(MSR_TR11);
1328 TRACE_SPRINTF_MSR(MSR_TR12);
1329 TRACE_SPRINTF_MSR(IA32_APIC_BASE);
1330 TRACE_SPRINTF_MSR(IA32_TIME_STAMP_COUNTER);
1331 TRACE_SPRINTF_MSR(IA32_PerfCntr0);
1332 TRACE_SPRINTF_MSR(IA32_PerfCntr1);
1333 TRACE_SPRINTF_MSR(IA32_PerfCntr2);
1334 TRACE_SPRINTF_MSR(IA32_PerfCntr3);
1335 TRACE_SPRINTF_MSR(PerfFilteredCntr0);
1336 TRACE_SPRINTF_MSR(PerfFilteredCntr1);
1337 TRACE_SPRINTF_MSR(PerfFilteredCntr2);
1338 TRACE_SPRINTF_MSR(PerfFilteredCntr3);
1339 TRACE_SPRINTF_MSR(IA32_PerfEvtSel0);
1340 TRACE_SPRINTF_MSR(IA32_PerfEvtSel1);
1341 TRACE_SPRINTF_MSR(IA32_PerfEvtSel2);
1342 TRACE_SPRINTF_MSR(IA32_PerfEvtSel3);
1343 TRACE_SPRINTF_MSR(PerfFilterMask);
1344 TRACE_SPRINTF_MSR(IA32_PERF_GLOBAL_STATUS);
1345 TRACE_SPRINTF_MSR(IA32_PERF_GLOBAL_OVF_CONTROL);
1346 TRACE_SPRINTF_MSR(IA32_PERF_GLOBAL_CTRL);
1347 TRACE_SPRINTF_MSR(IA32_MCG_CTL);
1348 TRACE_SPRINTF_MSR(IA32_MC0_CTRL);
1349 TRACE_SPRINTF_MSR(IA32_MC0_STAT);
1350 TRACE_SPRINTF_MSR(IA32_MC0_ADDR);
1351 TRACE_SPRINTF_MSR(IA32_MC0_MISC);
1352 TRACE_SPRINTF_MSR(IA32_MC1_CTRL);
1353 TRACE_SPRINTF_MSR(IA32_MC1_STAT);
1354 TRACE_SPRINTF_MSR(IA32_MC1_ADDR);
1355 TRACE_SPRINTF_MSR(IA32_MC1_MISC);
1356 TRACE_SPRINTF_MSR(SYSCALL_FLAG_MASK);
1357 TRACE_SPRINTF_MSR(X86_PAT);
1358#endif
1359 TRACE_SPRINTF("\t\t\t</msr>\n");
1360}
1361
1362
1363//u64 rdtsccount = 0, dmasetuptime = 0, dmacomptime=0, hostacktime=0;
1364
1365#if MIC_TRACE_CAPTURE_MEMORY_TEST
1366// Local function to count the number of bytes in a U32
1367// This is only used for the memory test.
1368static U32 AddBytes(U32 add)
1369{
1370 U32 sum = 0x0;
1371 for (int i=0; i < sizeof(U32); i++)
1372 {
1373 sum += (add & 0xFF);
1374 add = (add >> 8);
1375 }
1376 return sum;
1377}
1378#endif
1379
1380
1381//------------------------------------------------------------------------------
1382// FUNCTION: mictc_capture_memory
1383//
1384// DESCRIPTION:
1385// Trace Capture IPI Handler
1386//
1387// PARAMETERS: None
1388//
1389// RETURNS: None
1390//
1391// TODOS:
1392//
1393static int
1394mictc_capture_memory(void)
1395{
1396 long err;
1397 long i;
1398 long delay_count;
1399 long total_transfered = 0;
1400
1401 g_sizeXferred = 0;
1402
1403 // Transfer a full buffer.
1404 for (i = 0; total_transfered < (max_pfn << PAGE_SHIFT); i++) {
1405 printk("before scif_writeto, i = %ld\n", i);
1406
1407 // Transfer any remainder
1408 if ((max_pfn << PAGE_SHIFT) - total_transfered < MICTC_MEM_BUFFER_SIZE) {
1409 long remainder = ((uint64_t)max_pfn << PAGE_SHIFT) % MICTC_MEM_BUFFER_SIZE;
1410
1411 printk("Writing %ld bytes, max_pfn = %ld\n", remainder, max_pfn);
1412
1413 if ((err = scif_writeto(mictc_endp_data, scif_offset_mem + (i * MICTC_MEM_BUFFER_SIZE),
1414 remainder, scif_offset_dst, 0)) < 0) {
1415 pr_crit("%s:%s:%d scif_writeto failed with error %ld\n", __FILE__, __FUNCTION__, __LINE__, err);
1416 return 1;
1417 }
1418 total_transfered += remainder;
1419 g_sizeXferred = remainder;
1420 } else {
1421 if ((err = scif_writeto(mictc_endp_data, scif_offset_mem + (i * MICTC_MEM_BUFFER_SIZE),
1422 MICTC_MEM_BUFFER_SIZE, scif_offset_dst, 0)) < 0) {
1423 pr_crit("%s:%s:%d scif_writeto failed with error %ld\n", __FILE__, __FUNCTION__, __LINE__, err);
1424 return 1;
1425 }
1426 total_transfered += MICTC_MEM_BUFFER_SIZE;
1427 g_sizeXferred = MICTC_MEM_BUFFER_SIZE;
1428 }
1429 *g_traceBufferSizeOffset = g_sizeXferred;
1430 printk("before fence\n");
1431 err = scif_fence_signal(mictc_endp_data, (off_t)scif_offset_xml + TRACE_STATUS_OFFSET,
1432 TRACE_PAGE_READY, 0, 0, SCIF_FENCE_INIT_SELF | SCIF_SIGNAL_LOCAL);
1433
1434 if (err < 0) {
1435 printk("scif_fence_signal failed. err = %ld\n", err);
1436 return 1;
1437 }
1438 printk("TRACE_PAGE_READY %lld bytes\n", g_sizeXferred);
1439 g_sizeXferred = 0;
1440
1441 delay_count = 0;
1442 printk("waiting for TRACE_HOST_READY\n");
1443
1444 while (*g_traceBufferStatusOffset != TRACE_HOST_READY) {
1445 cpu_relax();
1446 delay_count++;
1447 if (delay_count == TRACE_CAPTURE_TIMEOUT) {
1448 printk("Memory Dump Timeout. Host did not update @physAddr 0x%lx\n", i << PAGE_SHIFT);
1449 return -EBUSY;
1450 }
1451 }
1452 }
1453 *g_traceBufferSizeOffset = 0;
1454 *g_traceBufferStatusOffset = TRACE_MEM_COMPLETE;
1455
1456 delay_count = 0;
1457
1458 while (*g_traceBufferStatusOffset != TRACE_COMPLETE) {
1459 cpu_relax();
1460 delay_count++;
1461 if (delay_count == TRACE_CAPTURE_TIMEOUT) {
1462 printk("Trace completion timeout.\n");
1463 return -EBUSY;
1464 }
1465 }
1466
1467 return 0;
1468}
1469
1470
1471//------------------------------------------------------------------------------
1472// FUNCTION: mictc_trace_capture
1473//
1474// DESCRIPTION:
1475// Perform all the tasks related to Trace Capture
1476// for a particular Hardware Thread.
1477// The tasks currently include:
1478// General purpose registers
1479// Segment registers
1480// Debug registers
1481// Control registers
1482// VPU registers
1483// MSRs
1484//
1485// Note: The SPU is not setup in Linux.
1486//
1487// PARAMETERS: regs - pointer to the task's registers
1488//
1489// RETURNS: None
1490//
1491// TODOS:
1492//
1493static void
1494mictc_trace_capture(struct pt_regs *regs)
1495{
1496 long delay_count;
1497
1498// printk("Entering mictc_trace_capture on cpu %d, for process = %s\n", smp_processor_id(), current->comm);
1499
1500 // Logic to let threads in one by one in order
1501
1502 while (atomic_read(&cpus_stopped) != smp_processor_id()) {
1503 cpu_relax();
1504//STH touch_nmi_watchdog();
1505 }
1506
1507 if (smp_processor_id() == 0)
1508 {
1509 // CPU0 is responsible for preparing the
1510 // Trace Capture Header.
1511 mictc_prep_header();
1512 }
1513
1514 TRACE_SPRINTF("\t\t<cpu num=\"%d\">\n", smp_processor_id());
1515 mictc_capture_general_purpose_reg(regs);
1516 mictc_capture_segment_reg(&(trace->segment), regs);
1517 mictc_capture_debug_reg();
1518 mictc_capture_control_reg();
1519 mictc_capture_vector_reg(&(trace->vpustate));
1520
1521//STH touch_nmi_watchdog(); // Just to be safe
1522
1523 // The SPU is not setup currently in Linux
1524 if (always_false) mictc_capture_SPU_reg();
1525
1526 mictc_capture_FPU_reg(&(trace->fpu));
1527 mictc_capture_MSR();
1528
1529// printk("In mictc_trace_capture on cpu %d, after MSRs\n", smp_processor_id());
1530
1531 TRACE_SPRINTF("\t\t</cpu>\n");
1532
1533 // Each core should flush their caches
1534 // as the initiator is going to take a memory
1535 // dump soon after.
1536 // Not required since DMA should snoop the caches.
1537 //wbinvd();
1538
1539// printk("In mictc_trace_capture on cpu %d, before check for last cpu\n", smp_processor_id());
1540
1541 if (smp_processor_id() == (num_online_cpus() - 1))
1542 {
1543 // The last CPU is responsible for preparing the
1544 // Trace Capture Trailer.
1545 TRACE_SPRINTF("\t</cpu_state>\n");
1546
1547 TRACE_SPRINTF("</arch_data>\n");
1548
1549 // Update the size as the Host App needs this information.
1550 *g_traceBufferSizeOffset = g_sizeXferred;
1551
1552 g_sizeXferred = 0;
1553
1554 // Update the status for the Host App. The CPU register state has been written by all
1555 // the hardware threads. The host app polls for this status.
1556 *g_traceBufferStatusOffset = TRACE_REG_COMPLETE;
1557
1558 printk("Completed Arch Dump. Now Beginning Memory Dump. Be patient (~1 min is ETA)..\n");
1559
1560 delay_count = 0;
1561
1562 while (*g_traceBufferStatusOffset != TRACE_GET_FILE)
1563 {
1564 cpu_relax();
1565 delay_count++;
1566 if (delay_count == TRACE_CAPTURE_TIMEOUT)
1567 {
1568 printk("Arch Dump Timeout. Host did not update status.\n");
1569 break;
1570 }
1571 }
1572 printk("%s out of wait loop.\n", __FUNCTION__);
1573 }
1574
1575// printk("Exiting mictc_trace_capture on cpu %d\n", smp_processor_id());
1576}
1577
1578
1579// Starting point for trace_capture.
1580static void
1581mictc_start_capture(void)
1582{
1583 long ret;
1584 long err;
1585 struct scif_portID portID_data;
1586 int control_msg = 0;
1587 int i;
1588 int found_it = 0;
1589
1590 spin_lock(&mictc_lock);
1591 printk("Starting tracecapture on cpu %d. Taking lock.\n", smp_processor_id());
1592
1593 if (!(g_traceBufferAllocated = kmalloc(MICTC_XML_BUFFER_SIZE, GFP_KERNEL))) {
1594 pr_crit("%s:%s:%d kmalloc failed failed with ENOMEM\n", __FILE__, __FUNCTION__, __LINE__);
1595 goto done0;
1596 }
1597
1598 pr_crit("%s:%s:%d kmalloc returned %llx\n", __FILE__, __FUNCTION__, __LINE__, (uint64_t)g_traceBufferAllocated);
1599
1600 g_traceBufferStatusOffset = (u64*)((u64)g_traceBufferAllocated + TRACE_STATUS_OFFSET);
1601 g_traceBufferSizeOffset = (u64*)((u64)g_traceBufferAllocated + TRACE_SIZE_OFFSET);
1602 g_traceBufferDataOffset = (u32*)((u64)g_traceBufferAllocated + TRACE_DATA_OFFSET);
1603 g_traceBufferTriggerOffset = (u32*)((u64)g_traceBufferAllocated + TRACE_TRIGGER_OFFSET);
1604
1605 *g_traceBufferStatusOffset = TRACE_DATA;
1606#if MIC_TRACE_CAPTURE_MEMORY_TEST
1607 g_traceBufferChecksumOffset = (u64*)((u64)g_traceBufferAllocated + TRACE_CHECKSUM_OFFSET);
1608#endif
1609
1610 if (!(trace = (struct mictc_trace *)kmalloc(sizeof(struct mictc_trace), GFP_KERNEL))) {
1611 pr_crit("%s:%s:%d kmalloc failed failed with ENOMEM\n", __FILE__, __FUNCTION__, __LINE__);
1612 goto done1a;
1613 }
1614
1615 pr_crit("%s:%s:%d kmalloc returned %llx\n", __FILE__, __FUNCTION__, __LINE__, (uint64_t)trace);
1616
1617 memset(trace, 0, sizeof(struct mictc_trace));
1618
1619 pr_crit("g_traceBufferStatusOffset %llx\n", (uint64_t)g_traceBufferStatusOffset);
1620 pr_crit("g_traceBufferSizeOffset %llx\n", (uint64_t)g_traceBufferSizeOffset);
1621 pr_crit("g_traceBufferDataOffset %llx\n", (uint64_t)g_traceBufferDataOffset);
1622
1623 // Data channel
1624 if (!(mictc_endp_data = scif_open())) {
1625 pr_crit("%s:%s:%d scif_open failed with ENOMEM\n", __FILE__, __FUNCTION__, __LINE__);
1626 return;
1627 }
1628
1629 if ((ret = scif_bind(mictc_endp_data, MICTC_SCIF_PORT_DATA)) < 0) {
1630 pr_crit("%s:%s:%d scif_bind failed with error %ld\n", __FILE__, __FUNCTION__, __LINE__, ret);
1631 goto done1;
1632 }
1633
1634 portID_data.node = 0;
1635 portID_data.port = MICTC_SCIF_PORT_DATA;
1636
1637 if ((ret = scif_connect(mictc_endp_data, &portID_data)) < 0) {
1638 pr_crit("%s:%s:%d scif_connect failed with error %ld\n", __FILE__, __FUNCTION__, __LINE__, ret);
1639 goto done1;
1640 }
1641
1642 if ((ret = (long)scif_register(mictc_endp_data,
1643 g_traceBufferAllocated,
1644 MICTC_XML_BUFFER_SIZE,
1645 0, // suggested_offset,
1646 SCIF_PROT_READ | SCIF_PROT_WRITE,
1647 SCIF_MAP_KERNEL)) < 0) {
1648 if (ret > -300) {
1649 pr_crit("%s:%s:%d scif_register failed failed with %ld\n", __FILE__, __FUNCTION__, __LINE__, ret);
1650 goto done2;
1651 }
1652 }
1653 scif_offset_xml = ret;
1654 pr_crit("%s:%s:%d scif_register scif_offset_xml = %lx\n", __FILE__, __FUNCTION__, __LINE__, scif_offset_xml);
1655
1656 // Register all of physical memory.
1657 if ((ret = (long)scif_register(mictc_endp_data,
1658 __va(0), // Physical page 0
1659 max_pfn << PAGE_SHIFT,
1660 0, // suggested_offset,
1661 SCIF_PROT_READ | SCIF_PROT_WRITE,
1662 SCIF_MAP_KERNEL)) < 0) {
1663 if (ret > -300) {
1664 pr_crit("%s:%s:%d scif_register failed failed with %ld\n", __FILE__, __FUNCTION__, __LINE__, ret);
1665 goto done2;
1666 }
1667 }
1668 scif_offset_mem = ret;
1669 pr_crit("%s:%s:%d scif_register scif_offset_mem = %lx\n", __FILE__, __FUNCTION__, __LINE__, scif_offset_mem);
1670
1671 BARRIER(mictc_endp_data, "before barrier");
1672
1673 if ((err = scif_recv(mictc_endp_data, &scif_offset_dst, sizeof(scif_offset_dst), SCIF_RECV_BLOCK)) <= 0) {
1674 pr_crit("%s:%s:%d scif_recv failed with err %ld\n", __FILE__, __FUNCTION__, __LINE__, err);
1675 goto close;
1676 }
1677
1678// g_traceBufferDataOffset = (u32 *)ret;
1679// pr_crit("%s:%s:%d scif_register ret %lx\n", __FILE__, __FUNCTION__, __LINE__, scif_offset);
1680
1681 if ((err = scif_send(mictc_endp_data, &scif_offset_xml, sizeof(scif_offset_xml), SCIF_SEND_BLOCK)) <= 0) {
1682 pr_crit("%s:%s:%d scif_send failed with err %ld\n", __FILE__, __FUNCTION__, __LINE__, err);
1683 goto close;
1684 }
1685
1686 while (*g_traceBufferStatusOffset != TRACE_HOST_READY)
1687 {
1688 msleep(100);
1689 touch_nmi_watchdog();
1690 }
1691
1692 // Get trigger data.
1693 for (i = 0; i < TRACE_TRIGGER_MAX; i++) {
1694 g_traceTriggers[i] = *g_traceBufferTriggerOffset;
1695 printk("Found trace trigger %d\n", g_traceTriggers[i]);
1696 g_traceBufferTriggerOffset++;
1697
1698 if (g_traceTriggers[i] == TRACE_EOL) break;
1699 }
1700
1701 // Is the trigger data empty? If so, accept everything.
1702 if (g_traceTriggers[0] == TRACE_EOL) {
1703 printk("Trace trigger data is empty.\n");
1704 found_it = 1;
1705 } else if (g_traceTriggers[0] == TRACE_IGNORE) {
1706 printk("Ignoring current trace.");
1707 } else {
1708 // See if g_traceCurrentTrigger is in the trigger data.
1709 // If not, abort this trace.
1710 for (i = 0; i < TRACE_TRIGGER_MAX; i++) {
1711 if (g_traceTriggers[i] == TRACE_EOL) break;
1712
1713 if (g_traceTriggers[i] == g_traceCurrentTrigger) {
1714 found_it = 1;
1715 printk("Matched trace trigger %d\n", g_traceTriggers[i]);
1716 break;
1717 }
1718 }
1719 }
1720
1721 if (!found_it) {
1722 // Abort this trace
1723 printk("Trace trigger did not match -- aborting.\n");
1724 *g_traceBufferStatusOffset = TRACE_ABORTED;
1725 goto done3;
1726 }
1727
1728 if (always_false) {
1729 // Mmap memory at 0xfee03000 physical.
1730 spu_addr = ioremap(0xfee03000, 0x1000);
1731 if (! spu_addr) {
1732 pr_crit("%s ioremap failed.\n", __FUNCTION__);
1733 goto done3;
1734 }
1735 printk("CPU ioremap %p\n", spu_addr);
1736 }
1737
1738 cli; // Interrupts off
1739 atomic_set(&cpus_stopped, 0);
1740 atomic_set(&cpus_released, 0);
1741 // Send IPI to capture all other cpus.
1742 apic->send_IPI_allbutself(NMI_VECTOR);
1743 mictc_trace_capture(task_pt_regs(current));
1744 atomic_inc(&cpus_stopped);
1745
1746 pr_debug("start_capture: Entering wait loop until lock count %d >= %d on cpu %d\n", atomic_read(&cpus_stopped), num_online_cpus() - 1, smp_processor_id());
1747
1748 { int ctr = 0;
1749 // Wait for every other CPU to finish its trace capture tasks.
1750 while (atomic_read(&cpus_stopped) < num_online_cpus()) {
1751 cpu_relax();
1752//STH touch_nmi_watchdog();
1753 if (ctr++ > 1000000) {
1754 ctr = 0;
1755 printk("%s:%d *** waiting loop cpus_stopped = %d\n", __FUNCTION__, __LINE__, atomic_read(&cpus_stopped));
1756 }
1757 }
1758 }
1759
1760 printk("%s out of wait loop.\n", __FUNCTION__);
1761
1762 // Get a memory dump here before exiting.
1763 err = mictc_capture_memory();
1764
1765 printk("Completed Memory Dump.\n");
1766// printk("Completed Memory Dump. DMASetuptime = %ld , DMATime = %ld, HostAckTime = %ld\n", dmasetuptime, dmacomptime, hostacktime);
1767
1768 // Now release all cores.
1769 atomic_set(&cpus_stopped, num_online_cpus() + 1);
1770
1771 // Wait for every other CPU to be released
1772 while (atomic_read(&cpus_released) < num_online_cpus() - 1) {
1773 // msleep(2000);
1774 cpu_relax();
1775 touch_nmi_watchdog();
1776 }
1777 sti; // Interrupts on
1778
1779 // FIXME This cleanup probably needs to be checked.
1780 close:
1781 if (always_false) {
1782 iounmap(spu_addr);
1783 }
1784 done3:
1785// scif_unregister(mictc_endp_data, scif_offset, MICTC_XML_BUFFER_SIZE);
1786 done2:
1787 done1:
1788 scif_close(mictc_endp_data);
1789 kfree(trace);
1790 done1a:
1791 kfree(g_traceBufferAllocated);
1792 spin_unlock(&mictc_lock);
1793 done0:
1794 printk("Ending tracecapture on cpu %d. Releasing lock.\n", smp_processor_id());
1795}
1796EXPORT_SYMBOL(mictc_start_capture);
1797
1798
1799/*
1800 * mictc_handle_exception() - main entry point from a kernel exception
1801 *
1802 * Locking hierarchy:
1803 * interface locks, if any (begin_session)
1804 */
1805int
1806mictc_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs)
1807{
1808 // Interrupts are off.
1809
1810 // printk("Entering mictc_handle_exception on cpu %d pid: %d, name: %s\n", smp_processor_id(), current->pid, current->comm);
1811
1812 mictc_trace_capture(regs);
1813 atomic_inc(&cpus_stopped);
1814 pr_debug("handler: Entering wait loop until lock count %d >= %d on cpu %d\n", atomic_read(&cpus_stopped), num_online_cpus() - 1, smp_processor_id());
1815 // Wait for every other CPU to finish its Trace Capture Tasks.
1816 // This test is for num_online_cpus+1 to hold all threads that are
1817 // in interrupt context so that the main thread can dump memory.
1818 while (atomic_read(&cpus_stopped) < num_online_cpus() + 1) {
1819 cpu_relax();
1820//STH touch_nmi_watchdog();
1821 }
1822
1823 atomic_inc(&cpus_released);
1824
1825 printk("Exiting mictc_handle_exception on cpu %d %s\n", smp_processor_id(), current->comm);
1826 return 1;
1827}
1828
1829
1830static int __mictc_notify(struct die_args *args, unsigned long cmd)
1831{
1832 struct pt_regs *regs = args->regs;
1833#if 0
1834 switch (cmd) {
1835 case DIE_NMI:
1836 if (atomic_read(&kgdb_active) != -1) {
1837 /* KGDB CPU roundup */
1838 kgdb_nmicallback(smp_processor_id(), regs);
1839 was_in_debug_nmi[smp_processor_id()] = 1;
1840 touch_nmi_watchdog();
1841 return NOTIFY_STOP;
1842 }
1843 return NOTIFY_DONE;
1844
1845 case DIE_NMIUNKNOWN:
1846 if (was_in_debug_nmi[smp_processor_id()]) {
1847 was_in_debug_nmi[smp_processor_id()] = 0;
1848 return NOTIFY_STOP;
1849 }
1850 return NOTIFY_DONE;
1851
1852 case DIE_DEBUG:
1853 if (atomic_read(&kgdb_cpu_doing_single_step) != -1) {
1854 if (user_mode(regs))
1855 return single_step_cont(regs, args);
1856 break;
1857 } else if (test_thread_flag(TIF_SINGLESTEP))
1858 /* This means a user thread is single stepping
1859 * a system call which should be ignored
1860 */
1861 return NOTIFY_DONE;
1862 /* fall through */
1863 default:
1864 if (user_mode(regs))
1865 return NOTIFY_DONE;
1866 }
1867#endif
1868 if (cmd == DIE_NMI) {
1869 if (mictc_handle_exception(args->trapnr, args->signr, cmd, regs)) {
1870 touch_nmi_watchdog();
1871 return NOTIFY_STOP;
1872 }
1873 } else {
1874 touch_nmi_watchdog();
1875 return NOTIFY_DONE;
1876 }
1877
1878 /* Must touch watchdog before return to normal operation */
1879 touch_nmi_watchdog();
1880 return NOTIFY_STOP;
1881}
1882
1883
1884static int
1885mictc_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
1886{
1887 unsigned long flags;
1888 int ret;
1889
1890 local_irq_save(flags);
1891 ret = __mictc_notify(ptr, cmd);
1892 local_irq_restore(flags);
1893
1894 return ret;
1895}
1896
1897
1898/*
1899 * This function is called whenever a process tries to do an ioctl on our
1900 * device file. We get two extra parameters (additional to the inode and file
1901 * structures, which all device functions get): the number of the ioctl called
1902 * and the parameter given to the ioctl function.
1903 *
1904 * If the ioctl is write or read/write (meaning output is returned to the
1905 * calling process), the ioctl call returns the output of this function.
1906 *
1907 */
1908long device_ioctl(
1909 struct file *file, /* ditto */
1910 unsigned int ioctl_num, /* number and param for ioctl */
1911 unsigned long ioctl_param)
1912{
1913 // Switch according to the ioctl called
1914 switch (ioctl_num) {
1915 case MICTC_START_CAPTURE:
1916
1917 // ioctl_param contains the trace trigger number.
1918 // Save it to check against the g_traceTrigger array.
1919 g_traceCurrentTrigger = (u32)ioctl_param;
1920 printk("IOCTL trace trigger %ld\n", ioctl_param);
1921 mictc_start_capture();
1922 break;
1923 default:
1924 printk("Invalid ioctl.\n");
1925 return -ENXIO;
1926 }
1927 return 0;
1928}
1929
1930
1931/*
1932 * This is called whenever a process attempts to open the device file
1933 */
1934static int device_open(struct inode *inode, struct file *file)
1935{
1936#ifdef DEBUG
1937 printk(KERN_INFO "device_open(%p)\n", file);
1938#endif
1939
1940 /*
1941 * We don't want to talk to two processes at the same time
1942 */
1943 if (Device_Open)
1944 return -EBUSY;
1945
1946 Device_Open++;
1947 try_module_get(THIS_MODULE);
1948 return 0;
1949}
1950
1951static int device_release(struct inode *inode, struct file *file)
1952{
1953#ifdef DEBUG
1954 printk(KERN_INFO "device_release(%p,%p)\n", inode, file);
1955#endif
1956
1957 /*
1958 * We're now ready for our next caller
1959 */
1960 Device_Open--;
1961
1962 module_put(THIS_MODULE);
1963 return 0;
1964}
1965
1966
1967/*
1968 * This structure will hold the functions to be called
1969 * when a process does something to the device we
1970 * created. Since a pointer to this structure is kept in
1971 * the devices table, it can't be local to
1972 * init_module. NULL is for unimplemented functions.
1973 */
1974struct file_operations Fops = {
1975 // .read = device_read,
1976 // .write = device_write,
1977 .unlocked_ioctl = device_ioctl,
1978 .open = device_open,
1979 .release = device_release, /* a.k.a. close */
1980};
1981
1982static struct notifier_block mictc_notifier = {
1983 .notifier_call = mictc_notify,
1984 .priority = 0x7fffffff /* we need to be notified first */
1985};
1986
1987
1988/*
1989 * mictc_init - Register our notifier
1990 *
1991 */
1992static
1993int mictc_init(void)
1994{
1995 int ret_val;
1996 /*
1997 * Register the character device (atleast try)
1998 */
1999 ret_val = register_chrdev(MICTC_MAJOR_NUM, MICTC_DEVICE_NAME, &Fops);
2000
2001 /*
2002 * Negative values signify an error
2003 */
2004 if (ret_val < 0) {
2005 printk(KERN_ALERT "%s failed with %d\n",
2006 "Sorry, registering the character device ", ret_val);
2007 return ret_val;
2008 }
2009
2010 printk(KERN_INFO "%s The major device number is %d.\n",
2011 "Registeration is a success", MICTC_MAJOR_NUM);
2012 printk(KERN_INFO "To use trace capture you'll have to create a device file:\n");
2013 printk(KERN_INFO "mknod %s c %d 0\n", MICTC_FILE_NAME, MICTC_MAJOR_NUM);
2014
2015 return register_die_notifier(&mictc_notifier);
2016
2017}
2018
2019
2020static
2021void mictc_exit(void)
2022{
2023 return;
2024}
2025
2026module_init(mictc_init);
2027module_exit(mictc_exit);
2028
2029MODULE_AUTHOR("Intel Corp. 2011 (sth " __DATE__ ") ver " TC_VER);
2030MODULE_DESCRIPTION("Trace Capture module for K1OM");
2031MODULE_LICENSE("GPL");