From: Feng, F. <fle...@in...> - 2003-01-08 15:07:36
|
Hi,=20 I have worked out a very preliminary kernel patch ARM and XScale platform support for LKCD. I developed it on DBPXA250 development board (Lubbock) with Intel's PXA250 processor. Because latest available kernel version that can boot on Linux is still 2.4.18 when I am working on it (I just get 2.4.19 patch from ARM Linux Kernel), I select a fairly old versi= on of LKCD to start from. (The latest version of LKCD is for 2.5 kernel not = for 2.4 kernel, and I am afraid if it is not stable to back port to 2.4 kerne= l). And because it is hard to find a place like swap partition on embedded system, I choose the network dumping method. Also I omit some SMP consideration for dumping since I didn't found any SMP application for ARM/XScale architecture. The following patch will work on LKCD with Moham= ed Abbas's net-console patch. I have successfully dumped to a net-server. An= d I have checked the binary file, I believe it is fine. Really want to have y= our comments! B rgds Fleming The following is the patch for ARM/XScale support: diff -urN linux_lkcd_netconsole/.config linux/.config --- linux_lkcd_netconsole/.config Thu Dec 26 23:24:11 2002 +++ linux/.config Thu Nov 28 19:46:02 2002 @@ -938,6 +938,9 @@ # # Kernel hacking # +CONFIG_DUMP=3Dy +# CONFIG_DUMP_COMPRESS_RLE is not set +# CONFIG_DUMP_COMPRESS_GZIP is not set CONFIG_FRAME_POINTER=3Dy CONFIG_DEBUG_USER=3Dy CONFIG_DEBUG_INFO=3Dy diff -urN linux_lkcd_netconsole/arch/arm/config.in linux/arch/arm/config.= in --- linux_lkcd_netconsole/arch/arm/config.in Thu Dec 26 15:16:21 2002 +++ linux/arch/arm/config.in Thu Nov 28 19:11:47 2002 @@ -707,6 +707,12 @@ mainmenu_option next_comment comment 'Kernel hacking' =20 +tristate 'Linux Kernel Crash Dump(LKCD) Support' CONFIG_DUMP +if [ "$CONFIG_DUMP" !=3D "n" ]; then + dep_tristate ' LKCD RLE compression' CONFIG_DUMP_COMPRESS_RLE $CONFIG_DUMP + dep_tristate ' LKCD GZIP compression' CONFIG_DUMP_COMPRESS_GZIP $CONFIG_DUMP +fi + # RMK wants arm kernels compiled with frame pointers so hardwire this to= y. If # you know what you are doing and are willing to live without stack trac= es, you # can get a slightly smaller kernel by setting this option to n, but the= n RMK diff -urN linux_lkcd_netconsole/arch/arm/kernel/traps.c linux/arch/arm/kernel/traps.c --- linux_lkcd_netconsole/arch/arm/kernel/traps.c Thu Dec 26 15:16:21 2002 +++ linux/arch/arm/kernel/traps.c Fri Dec 27 09:32:44 2002 @@ -25,6 +25,8 @@ #include <linux/interrupt.h> #include <linux/init.h> =20 +#include <linux/dump.h> + #include <asm/pgtable.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -161,6 +163,9 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) { struct task_struct *tsk =3D current; +#if defined(CONFIG_DUMP) || defined(CONFIG_DUMP_MODULE) + _dump_regs_t dump_regs; +#endif =20 console_verbose(); spin_lock_irq(&die_lock); @@ -168,6 +173,11 @@ printk("Internal error: %s: %x\n", str, err); printk("CPU: %d\n", smp_processor_id()); show_regs(regs); +#if defined(CONFIG_DUMP) || defined(CONFIG_DUMP_MODULE) + get_current_regs(&dump_regs); + memcpy(&dump_regs.dha_regs, regs, sizeof(struct pt_regs)); + dump(str, &dump_regs); +#endif printk("Process %s (pid: %d, stackpage=3D%08lx)\n", current->comm, current->pid, 4096+(unsigned long)tsk); =20 diff -urN linux_lkcd_netconsole/drivers/char/sysrq.c linux/drivers/char/sysrq.c --- linux_lkcd_netconsole/drivers/char/sysrq.c Thu Dec 26 15:44:39 2002 +++ linux/drivers/char/sysrq.c Fri Dec 27 09:42:06 2002 @@ -305,8 +305,15 @@ static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs, struct kbd_struct *kbd, struct tty_struct *tty) { #if defined(CONFIG_DUMP) || defined(CONFIG_DUMP_MODULE) +#ifdef CONFIG_ARM + _dump_regs_t regs; + get_current_regs(®s); + memcpy(®s.dha_regs, pt_regs, sizeof(struct pt_regs)); + dump("sysrq", ®s); +#else dump("sysrq", pt_regs); #endif +#endif } static struct sysrq_key_op sysrq_crashdump_op =3D { handler: sysrq_handle_crashdump, diff -urN linux_lkcd_netconsole/drivers/dump/Makefile linux/drivers/dump/Makefile --- linux_lkcd_netconsole/drivers/dump/Makefile Thu Dec 26 15:18:17 2002 +++ linux/drivers/dump/Makefile Thu Nov 28 20:06:35 2002 @@ -30,6 +30,10 @@ dump-objs +=3D dump_ia64.o endif =20 +ifeq ($(ARCH),arm) + dump-objs +=3Ddump_arm.o +endif + include $(TOPDIR)/Rules.make =20 dump.o: $(dump-objs) diff -urN linux_lkcd_netconsole/drivers/dump/dump_arm.c linux/drivers/dump/dump_arm.c --- linux_lkcd_netconsole/drivers/dump/dump_arm.c Thu Jan 1 08:00:00 1970 +++ linux/drivers/dump/dump_arm.c Thu Dec 26 15:00:04 2002 @@ -0,0 +1,161 @@ +/* + * Architecture specific (i386) functions for Linux crash dumps. + * + * Created by: Matt Robinson (ya...@sg...) + * + * Copyright 1999 Silicon Graphics, Inc. All rights reserved. + * + * 2.3 kernel modifications by: Matt D. Robinson (ya...@tu...) + * Copyright 2000 TurboLinux, Inc. All rights reserved. + *=20 + * This code is released under version 2 of the GNU GPL. + */ + +/* + * The hooks for dumping the kernel virtual memory to disk are in this + * file. Any time a modification is made to the virtual memory mechanis= m, + * these routines must be changed to use the new mechanisms. + */ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/smp.h> +#include <linux/fs.h> +#include <linux/vmalloc.h> +#include <linux/dump.h> +#include <linux/mm.h> +#include <asm/processor.h> +#include <asm/hardirq.h> +//#include <linux/irq.h> + +static int alloc_dha_stack(void) +{ + void *ptr; +=09 + if (dump_header_asm.dha_stack) + return 0; + + ptr =3D vmalloc(THREAD_SIZE); + if (!ptr) { + printk("vmalloc for dha_stacks failed\n"); + return -ENOMEM; + } + + dump_header_asm.dha_stack=3Dptr; + + return 0; +} + +static int free_dha_stack(void)=20 +{ + if (dump_header_asm.dha_stack) + vfree(dump_header_asm.dha_stack); + return 0; +} + +/* In case of panic dumps, we collects regs on entry to panic. + * so, we shouldn't 'fix' ssesp here again. But it is hard to + * tell just looking at regs whether ssesp need fixing. We make + * this decision by looking at xss in regs. If we have better + * means to determine that ssesp are valid (by some flag which + * tells that we are here due to panic dump), then we can use + * that instead of this kludge. + */ +#define save_other_cpu_states() + +/* + * Name: __dump_silence_system() + * Func: Do an architecture-specific silencing of the system. + * - Change irq affinities + * - Wait for other cpus to come out of irq handling + * - Send CALL_FUNCTION_VECTOR ipi to other cpus to put them to spin + */ +unsigned int +__dump_silence_system(unsigned int stage) +{ + + /* return */ + return (0); +} + +/* + * Name: __dump_resume_system() + * Func: Resume the system state in an architecture-specific way. + */ +unsigned int +__dump_resume_system(unsigned int stage) +{ + + /* return */ + return (0); +} + +static void=20 +save_this_cpu_state(struct pt_regs *regs, struct task_struct *tsk) +{ + dump_header_asm.dha_current_task =3D tsk; + + if (dump_header_asm.dha_stack) { + memcpy(dump_header_asm.dha_stack, tsk, THREAD_SIZE); + } + return; +} + +/* + * Name: __dump_configure_header() + * Func: Configure the dump header with all proper values. + */ +int +__dump_configure_header(struct pt_regs *regs) +{ + + printk(KERN_EMERG "XScale Dumpping Started!\n"); + + save_this_cpu_state(regs, current); + + save_other_cpu_states(); + + return (1); +} + +/* + * Name: __dump_init() + * Func: Initialize the dumping routine process. This is in case + * it's necessary in the future. + */ +void +__dump_init(uint64_t local_memory_start) +{ + /* return */ + return; +} + +/* + * Name: __dump_open() + * Func: Open the dump device (architecture specific). This is in + * case it's necessary in the future. + */ +void +__dump_open(void) +{ + + alloc_dha_stack(); + + /* return */ + return; +} + +/* + * Name: __dump_cleanup() + * Func: Free any architecture specific data structures. This is called + * when the dump module is being removed. + */ +void +__dump_cleanup(void) +{ + free_dha_stack(); + + /* return */ + return; +} + diff -urN linux_lkcd_netconsole/drivers/dump/dump_base.c linux/drivers/dump/dump_base.c --- linux_lkcd_netconsole/drivers/dump/dump_base.c Thu Dec 26 15:58:47 2002 +++ linux/drivers/dump/dump_base.c Thu Dec 26 22:14:54 2002 @@ -648,7 +648,7 @@ #if DUMP_DEBUG if(dump_add_page_debug) { printk(KERN_ALERT "dump_add_page(page:%lx, *toffset:%lx):\n", =20 - page, *toffset); + p, *toffset); } #endif =20 @@ -928,8 +928,13 @@ =20 /* copy the registers if they are valid */ if (regs) { +#ifdef CONFIG_ARM + memcpy((void *)&(dump_header_asm.dha_regs), + (const void *)regs, sizeof(_dump_regs_t)); +#else memcpy((void *)&(dump_header_asm.dha_regs), (const void *)regs, sizeof(struct pt_regs)); +#endif } =20 /* configure architecture-specific dump header values */ diff -urN linux_lkcd_netconsole/drivers/net/smc9194.c linux/drivers/net/smc9194.c --- linux_lkcd_netconsole/drivers/net/smc9194.c Thu Dec 26 15:16:50 2002 +++ linux/drivers/net/smc9194.c Wed Dec 4 17:08:28 2002 @@ -276,6 +276,7 @@ . relating to a packet is sent. */ static inline void smc_tx(struct net_device * dev); +static void poll_smc(struct net_device* dev); =20 /* ------------------------------------------------------------ @@ -1622,6 +1623,9 @@ dev->get_stats =3D smc_query_statistics; dev->set_multicast_list =3D smc_set_multicast_list; dev->do_ioctl =3D smc_ioctl; +#ifdef HAVE_POLL_CONTROLLER + dev->poll_controller =3D &poll_smc; +#endif =20 return 0; =20 @@ -1960,6 +1964,22 @@ return; } =20 +#ifdef HAVE_POLL_CONTROLLER + +/* Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routing is executing. + */ + +static void poll_smc(struct net_device* dev) +{ + disable_irq(dev->irq); + smc_interrupt(dev->irq, dev, NULL); + enable_irq(dev->irq); +} + +#endif + /*------------------------------------------------------------- . . smc_rcv - receive a packet from the card diff -urN linux_lkcd_netconsole/include/asm-arm/dump.h linux/include/asm-arm/dump.h --- linux_lkcd_netconsole/include/asm-arm/dump.h Thu Jan 1 08:00:00 1970 +++ linux/include/asm-arm/dump.h Mon Dec 16 16:56:30 2002 @@ -0,0 +1,423 @@ +/* + * Kernel header file for Linux crash dumps on arm and XScale. + * + * Created by: Fleming Feng (fle...@in...) + * + * Copyright 2002 Intel Corp. All rights reserved. + * + * This code is released under version 2 of the GNU GPL. + */ + +/* This header file holds the architecture specific crash dump header */ +#ifndef _ASM_DUMP_H +#define _ASM_DUMP_H + +/* necessary header files */ +#include <asm/ptrace.h> /* for pt_regs */ +#include <linux/threads.h> + +/* definitions */ +#define DUMP_ASM_MAGIC_NUMBER 0xdeaddeadULL /* magic number */ +#define DUMP_ASM_VERSION_NUMBER 0x2 /* version number */ + +#define MODE_BIT 0x1f +#define USER_MODE 0x10 +#define SYSTEM_MODE 0x1f + +#ifdef CONFIG_CPU_XSCALE +#define TRACE_BUF_ENABLE 0x1 +#define TRACE_BUF_MODE 0x2 +#define TRACE_BUF_LEN 256 +#endif /* CONFIG_CPU_XSCALE */ +/* Structure: _arm_cp15_regs_t + * Function: This is the structure to hold registers for coprocessor 15 + * of ARM. Some cp15 registers are specific for XSCale Core. + */ +typedef struct _arm_cp15_regs_s { +#ifdef CONFIG_CPU_XSCALE + long uregs[16]; +#else /* CONFIG_CPU_XSCALE */ + long uregs[9]; +#endif /* CONFIG_CPU_XSCALE */ +} _arm_cp15_regs_t; + +#define ARM_cp15_id uregs[0] /* ID */ +#define ARM_cp15_ct uregs[1] /* Cache type */ +#define ARM_cp15_ctr uregs[2] /* Control */ +#define ARM_cp15_ttb uregs[3] /* Translation table base */ +#define ARM_cp15_dac uregs[4] /* Domain access control */ +#define ARM_cp15_fsr uregs[5] /* Fault status register */ +#define ARM_cp15_far uregs[6] /* Fault address register */ +#define ARM_cp15_clm uregs[7] /* Data cache lock mode */ +#define ARM_cp15_pid uregs[8] /* Processor ID */ + +#ifdef CONFIG_CPU_XSCALE +/* The following are registers only exists on XScale Core */ +#define XSCALE_cp15_actr uregs[9] /* Auxillary Control */ +#define XSCALE_cp15_ibcr0 uregs[10] /* Instruction breakpoint + control register 0 */ +#define XSCALE_cp15_ibcr1 uregs[11] /* Instruction breakpoint + control register 1 */ +#define XSCALE_cp15_dbr0 uregs[12] /* Data breakpoint address + register 0 */ +#define XSCALE_cp15_dbr1 uregs[13] /* Data breakpoint address + register 1 */ +#define XSCALE_cp15_dbctr uregs[14] /* Data breakpoint control + register */ +#define XSCALE_cp15_car uregs[15] /* Coprocessor access */ + +/* Structure: _xscale_cp14_regs_t + * Function: This is the structure to hold registers for coprocessor 14 + * of XScale Core. + */ +typedef struct _xscale_cp14_regs_s { + long uregs[11]; +} _xscale_cp14_regs_t; + +#define XSCALE_cp14_pmnc uregs[0] /* Perfmon control */ +#define XSCALE_cp14_ccnt uregs[1] /* Clock counter */ +#define XSCALE_cp14_pmn0 uregs[2] /* Performance monitor + event counter 0 */ +#define XSCALE_cp14_pmn1 uregs[3] /* Performance monitor + event counter 1 */ +#define XSCALE_cp14_cclk uregs[4] /* Core clock config */ +#define XSCALE_cp14_tx uregs[5] /* Transmit regiser */ +#define XSCALE_cp14_rx uregs[6] /* Receive register */ +#define XSCALE_cp14_dcsr uregs[7] /* Debug control and + status register */ +#define XSCALE_cp14_chkpt0 uregs[8] /* Checkpoint register 0 */ +#define XSCALE_cp14_chkpt1 uregs[9] /* Checkpoint register 1 */ +#define XSCALE_cp14_txrxctl uregs[10] /* Tx/Rx control register */ + +/* Structure: _xscale_trace_buf_t + * Function: This is the structure to hold registers and contents for + * trace buffer of XScale Core. + */ +typedef struct _xscale_trace_buf_s { + unsigned char tb_entry[TRACE_BUF_LEN]; +} _xscale_trace_buf_t; +#endif /* CONFIG_CPU_XSCALE */ + +/* Structure: dump_regs_t + * Function: This is the structure that hold all the registers + * to be dumpped. The order each field in this structure + * should be exactly the same order as appeared in=20 + * structure dump_header_asm_t. + */ +typedef struct _dump_regs_s { + /* the dump registers */ + struct pt_regs dha_regs; + + /* the saved psr register */ + uint32_t dha_ARM_spsr; + + /* coprocessor registers for ARM & XScle */ + _arm_cp15_regs_t dha_cp15_regs; + +#ifdef CONFIG_CPU_XSCALE=09 + /* coprocessor registers for XScale */ + _xscale_cp14_regs_t dha_cp14_regs; +=09 + /* trace buffer registers and contents */ + _xscale_trace_buf_t dha_trace_buf; +#endif /*CONFIG_CPU_XSCALE */ +} _dump_regs_t; + +/* + * Structure: dump_header_asm_t + * Function: This is the header for architecture-specific stuff. It + * follows right after the dump header. + */ +typedef struct _dump_header_asm_s { + /* the dump magic number -- unique to verify dump is valid */ + uint64_t dha_magic_number; + + /* the version number of this dump */ + uint32_t dha_version; + + /* the size of this header (in case we can't read it) */ + uint32_t dha_header_size; + + /* the registers to be dumpped */ + _dump_regs_t dha_regs; + + /* current task */ + /* Do we really need this, if we do not support SMP?=20 + * By Fleming Feng, 12/11/2002 + */ + void * dha_current_task; + void * dha_stack; +} dump_header_asm_t; + +#ifdef __KERNEL__ +static inline void get_current_regs(_dump_regs_t *regs) +{ + + unsigned char *temp; + + /* dump critical general registers first */ + __asm__ __volatile__("str fp, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_fp)); + __asm__ __volatile__("str sp, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_sp)); + __asm__ __volatile__("str lr, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_lr)); + + /* dump general registers that will be used later */ + __asm__ __volatile__("str r0, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_r0)); + __asm__ __volatile__("str r1, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_r1)); + +#ifdef CONFIG_CPU_XSCALE + /* put the dumping of Trace buffer as earlier as possible to avoid + * futher corrput of it because of the dumping code. Carefully only + * use register which has already been saved for dumping, because=20 + * the content of these registers are saved.=20 + * by Fleming Feng 12/16/2002. + */ + /* The following code make sure only uses r0-r3 and fp which has already + * saved + */ + /* Test if trace buffer is enabled, if it is, disable it. */ + __asm__ __volatile__("mrc p14, 0, r0, c10, c0, 0 + str r0, %0 + tst r0, %1 + biceq r0, r0, %1 + mcreq p14, 0, r0, c10, c0, 0" + : "=3Dm"(regs->dha_cp14_regs.XSCALE_cp14_dcsr) + : "I"(TRACE_BUF_ENABLE) + /* The following make sure if gcc use a register + * to put the immediate data TRACE_BUF_ENABLE,=20 + * the register will only use r1 + */ + : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r13", "r14"); + /* When code is executed here, the dcsr has been dumpped,=20 + * trace buffer is confirmed to be disabled, and if it is previously + * enabled, the previous states has been saved! And there is no need + * to download trace buffer content immediately. Since the trace buffer + * is disabled, no further info will be written to the trace buffer. + */ +#endif /* CONFIG_CPU_XSCALE */ + + /* dump other general registers */ + __asm__ __volatile__("str r2, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_r2)); + __asm__ __volatile__("str r3, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_r3)); + __asm__ __volatile__("str r4, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_r4)); + __asm__ __volatile__("str r5, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_r5)); + __asm__ __volatile__("str r6, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_r6)); + __asm__ __volatile__("str r7, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_r7)); + __asm__ __volatile__("str r8, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_r8)); + __asm__ __volatile__("str r9, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_r9)); + __asm__ __volatile__("str r10, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_r10)); + __asm__ __volatile__("str ip, %0"=20 + : "=3Dm"(regs->dha_regs.ARM_ip)); + + /* dump program counter */ + regs->dha_regs.ARM_pc =3D (unsigned long)current_text_addr(); + + /* The registers involved with processor states and cp states + * will not be changed in the above operation, so it is safe + * to dump them at last + */ + /* dump cpsr register */ + __asm__ __volatile__("mrs %0, cpsr" + : "=3Dr"(regs->dha_regs.ARM_cpsr)); +=09 + /* dump spsr register */ + if(((regs->dha_regs.ARM_cpsr & MODE_BIT) !=3D USER_MODE) && + ((regs->dha_regs.ARM_cpsr & MODE_BIT) !=3D SYSTEM_MODE)){ + __asm__ __volatile__("mrs %0, spsr" + : "=3Dr"(regs->dha_ARM_spsr)); + } + + /* dump cp15 registers */ + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0"=20 + : "=3Dr"(regs->dha_cp15_regs.ARM_cp15_id)); + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 1"=20 + : "=3Dr"(regs->dha_cp15_regs.ARM_cp15_ct)); + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0"=20 + : "=3Dr"(regs->dha_cp15_regs.ARM_cp15_ctr)); + __asm__ __volatile__("mrc p15, 0, %0, c2, c0, 0"=20 + : "=3Dr"(regs->dha_cp15_regs.ARM_cp15_ttb)); + __asm__ __volatile__("mrc p15, 0, %0, c3, c0, 0"=20 + : "=3Dr"(regs->dha_cp15_regs.ARM_cp15_dac)); + __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0"=20 + : "=3Dr"(regs->dha_cp15_regs.ARM_cp15_fsr)); + __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0"=20 + : "=3Dr"(regs->dha_cp15_regs.ARM_cp15_far)); + __asm__ __volatile__("mrc p15, 0, %0, c9, c2, 0"=20 + : "=3Dr"(regs->dha_cp15_regs.ARM_cp15_clm)); + __asm__ __volatile__("mrc p15, 0, %0, c13, c0, 0"=20 + : "=3Dr"(regs->dha_cp15_regs.ARM_cp15_pid)); + +#ifdef CONFIG_CPU_XSCALE + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1" + : "=3Dr"(regs->dha_cp15_regs.XSCALE_cp15_actr)); + __asm__ __volatile__("mrc p15, 0, %0, c14, c8, 0" + : "=3Dr"(regs->dha_cp15_regs.XSCALE_cp15_ibcr0)); + __asm__ __volatile__("mrc p15, 0, %0, c14, c9, 0" + : "=3Dr"(regs->dha_cp15_regs.XSCALE_cp15_ibcr1)); + __asm__ __volatile__("mrc p15, 0, %0, c14, c0, 0" + : "=3Dr"(regs->dha_cp15_regs.XSCALE_cp15_dbr0)); + __asm__ __volatile__("mrc p15, 0, %0, c14, c3, 0" + : "=3Dr"(regs->dha_cp15_regs.XSCALE_cp15_dbr1)); + __asm__ __volatile__("mrc p15, 0, %0, c14, c4, 0" + : "=3Dr"(regs->dha_cp15_regs.XSCALE_cp15_dbctr)); + __asm__ __volatile__("mrc p15, 0, %0, c15, c1, 0" + : "=3Dr"(regs->dha_cp15_regs.XSCALE_cp15_car)); + + /* dump other cp14 registers */ + __asm__ __volatile__("mrc p14, 0, %0, c0, c0, 0" + : "=3Dr"(regs->dha_cp14_regs.XSCALE_cp14_pmnc)); + __asm__ __volatile__("mrc p14, 0, %0, c1, c0, 0" + : "=3Dr"(regs->dha_cp14_regs.XSCALE_cp14_ccnt)); + __asm__ __volatile__("mrc p14, 0, %0, c2, c0, 0" + : "=3Dr"(regs->dha_cp14_regs.XSCALE_cp14_pmn0)); + __asm__ __volatile__("mrc p14, 0, %0, c3, c0, 0" + : "=3Dr"(regs->dha_cp14_regs.XSCALE_cp14_pmn1)); + __asm__ __volatile__("mrc p14, 0, %0, c6, c0, 0" + : "=3Dr"(regs->dha_cp14_regs.XSCALE_cp14_cclk)); + __asm__ __volatile__("mrc p14, 0, %0, c8, c0, 0" + : "=3Dr"(regs->dha_cp14_regs.XSCALE_cp14_tx)); + __asm__ __volatile__("mrc p14, 0, %0, c9, c0, 0" + : "=3Dr"(regs->dha_cp14_regs.XSCALE_cp14_rx)); + __asm__ __volatile__("mrc p14, 0, %0, c14, c0, 0" : + "=3Dr"(regs->dha_cp14_regs.XSCALE_cp14_txrxctl)); + + /* Check point register */ + __asm__ __volatile__("mrc p14, 0, r0, c12, c0, 0 + str r0, %0 + mrc p14, 0, r0, c13, c0, 0 + str r0, %1" + : "=3Dm"(regs->dha_cp14_regs.XSCALE_cp14_chkpt0), + =09 "=3Dm"(regs->dha_cp14_regs.XSCALE_cp14_chkpt1)); + /* a loop to dump whole trace buf content */ + temp =3D (unsigned char*)&(regs->dha_trace_buf.tb_entry[0]); + __asm__ __volatile__(" ldr r0, %0 + mov r1, %1 + mov r2, #1 + 1: mrc p14, 0, r3, c11, c0, 0 + strb r3, [r0], #1 + sub r1, r1, r2 + beq 1b" + : : "m"(temp), "I"(TRACE_BUF_LEN)); + /* If the trace buffer is previously enabled, enable it! */ + __asm__ __volatile__("mcr p14, 0, %0, c10, c0, 0" + : :"r"(regs->dha_cp14_regs.XSCALE_cp14_dcsr)); +#endif /* CONFIG_CPU_XSCALE */ + +} + +static inline void dump_print_all_regs(_dump_regs_t* regs) +{ +#if DUMP_DEBUG >=3D 6 + + int i, j; + + printk(KERN_EMERG "=3D=3D=3D=3D=3D dumping messages by Fleming =3D=3D=3D= =3D=3D=3D=3D\n"); + printk(KERN_EMERG "=3D=3D ARM registers: =3D=3D\n"); + printk(KERN_EMERG "r0 =3D 0x%08x, r1 =3D 0x%08x, r2 =3D 0x%08x, " + "r3 =3D 0x%08x\n" + "r4 =3D 0x%08x, r5 =3D 0x%08x, r6 =3D 0x%08x, " + "r7 =3D 0x%08x\n" + "r8 =3D 0x%08x, r9 =3D 0x%08x, r10 =3D 0x%08x, " + "fp =3D 0x%08x\n" + "ip =3D 0x%08x, sp =3D 0x%08x, lr =3D 0x%08x, " + "pc =3D 0x%08x\n", + regs->dha_regs.ARM_r0, regs->dha_regs.ARM_r1, + regs->dha_regs.ARM_r2, regs->dha_regs.ARM_r3, + regs->dha_regs.ARM_r4, regs->dha_regs.ARM_r5, + regs->dha_regs.ARM_r6, regs->dha_regs.ARM_r7, + regs->dha_regs.ARM_r8, regs->dha_regs.ARM_r9, + regs->dha_regs.ARM_r10, regs->dha_regs.ARM_fp, + regs->dha_regs.ARM_ip, regs->dha_regs.ARM_sp, + regs->dha_regs.ARM_lr, regs->dha_regs.ARM_pc); + printk(KERN_EMERG "cpsr =3D 0x%08x, spsr =3D 0x%08x\n\n", + regs->dha_regs.ARM_cpsr, regs->dha_ARM_spsr); + + printk(KERN_EMERG "=3D=3D ARM cp15 registers: =3D=3D\n"); + printk(KERN_EMERG "id =3D 0x%08x, ct =3D 0x%08x, ctr =3D 0x%08x= , " + "ttb =3D 0x%08x\n" + "dac =3D 0x%08x, fsr =3D 0x%08x, far =3D 0x%08x, " + "clm =3D 0x%08x, pid =3D 0x%08x\n\n", + regs->dha_cp15_regs.ARM_cp15_id, + regs->dha_cp15_regs.ARM_cp15_ct, + regs->dha_cp15_regs.ARM_cp15_ctr, + regs->dha_cp15_regs.ARM_cp15_ttb, + regs->dha_cp15_regs.ARM_cp15_dac, + regs->dha_cp15_regs.ARM_cp15_fsr, + regs->dha_cp15_regs.ARM_cp15_far, + regs->dha_cp15_regs.ARM_cp15_clm, + regs->dha_cp15_regs.ARM_cp15_pid); + +#ifdef CONFIG_CPU_XSCALE + printk(KERN_EMERG "=3D=3D XSCALE cp15 registers: =3D=3D\n"); + printk(KERN_EMERG "actr =3D 0x%08x, ibcr0 =3D 0x%08x, ibcr1 =3D 0x%08x= , " + "dbr0 =3D 0x%08x\n" + "dbr1 =3D 0x%08x, dbctr =3D 0x%08x, " + "car =3D 0x%08x\n\n", + regs->dha_cp15_regs.XSCALE_cp15_actr, + regs->dha_cp15_regs.XSCALE_cp15_ibcr0, + regs->dha_cp15_regs.XSCALE_cp15_ibcr1, + regs->dha_cp15_regs.XSCALE_cp15_dbr0, + regs->dha_cp15_regs.XSCALE_cp15_dbr1, + regs->dha_cp15_regs.XSCALE_cp15_dbctr, + regs->dha_cp15_regs.XSCALE_cp15_car); + + printk(KERN_EMERG "=3D=3D XSCALE cp14 registers: =3D=3D\n"); + printk(KERN_EMERG "pmnc =3D 0x%08x, ccnt =3D 0x%08x, " + "pmn0 =3D 0x%08x, pmn1 =3D 0x%08x\n" + "cclk =3D 0x%08x, tx =3D 0x%08x, " + "rx =3D 0x%08x, dcsr =3D 0x%08x\n" + "chkpt0 =3D 0x%08x, chkpt1 =3D 0x%08x, " + "txrxctl =3D 0x%08x\n\n", + regs->dha_cp14_regs.XSCALE_cp14_pmnc, + regs->dha_cp14_regs.XSCALE_cp14_ccnt, + regs->dha_cp14_regs.XSCALE_cp14_pmn0, + regs->dha_cp14_regs.XSCALE_cp14_pmn1, + regs->dha_cp14_regs.XSCALE_cp14_cclk, + regs->dha_cp14_regs.XSCALE_cp14_tx, + regs->dha_cp14_regs.XSCALE_cp14_rx, + regs->dha_cp14_regs.XSCALE_cp14_dcsr, + regs->dha_cp14_regs.XSCALE_cp14_chkpt0, + regs->dha_cp14_regs.XSCALE_cp14_chkpt1, + regs->dha_cp14_regs.XSCALE_cp14_txrxctl); + + printk(KERN_EMERG "=3D=3D XSCALE trace buffer: =3D=3D\n"); + for(i =3D 0; i < 16; i ++){ + printk(KERN_EMERG "0x%04x - 0x%04x: ", i*16, i*16+15); + for(j =3D 0; j < 16; j ++){ + printk(KERN_EMERG "%02x ",=20 + (unsigned long) + regs->dha_trace_buf.tb_entry[i*16 + j]); + } + printk(KERN_EMERG "\n"); + } +#endif /* CONFIG_CPU_XSCALE */ +#endif /* DUMP_DEBUG */ +} + +extern volatile int dump_in_progress; +extern unsigned long irq_affinity[]; +extern dump_header_asm_t dump_header_asm; + +#ifdef CONFIG_SMP +extern int (*dump_ipi_function_ptr)(struct pt_regs *); +extern void dump_send_ipi(void); +#else +#define dump_send_ipi() +#endif +#endif /* __KERNEL__ */ + +#endif /* _ASM_DUMP_H */ diff -urN linux_lkcd_netconsole/include/config/dump/compress/gzip.h linux/include/config/dump/compress/gzip.h --- linux_lkcd_netconsole/include/config/dump/compress/gzip.h Thu Jan 1 08:00:00 1970 +++ linux/include/config/dump/compress/gzip.h Thu Nov 28 19:48:39 2002 @@ -0,0 +1 @@ +#undef CONFIG_DUMP_COMPRESS_GZIP diff -urN linux_lkcd_netconsole/include/config/dump/compress/rle.h linux/include/config/dump/compress/rle.h --- linux_lkcd_netconsole/include/config/dump/compress/rle.h Thu Jan 1 08:00:00 1970 +++ linux/include/config/dump/compress/rle.h Thu Nov 28 19:48:39 2002 @@ -0,0 +1 @@ +#undef CONFIG_DUMP_COMPRESS_RLE diff -urN linux_lkcd_netconsole/include/config/dump.h linux/include/config/dump.h --- linux_lkcd_netconsole/include/config/dump.h Thu Jan 1 08:00:00 1970 +++ linux/include/config/dump.h Thu Nov 28 19:48:39 2002 @@ -0,0 +1 @@ +#define CONFIG_DUMP 1 diff -urN linux_lkcd_netconsole/include/linux/autoconf.h linux/include/linux/autoconf.h --- linux_lkcd_netconsole/include/linux/autoconf.h Thu Dec 26 23:24:11 2002 +++ linux/include/linux/autoconf.h Thu Nov 28 19:46:02 2002 @@ -942,6 +942,9 @@ /* * Kernel hacking */ +#define CONFIG_DUMP 1 +#undef CONFIG_DUMP_COMPRESS_RLE +#undef CONFIG_DUMP_COMPRESS_GZIP #define CONFIG_FRAME_POINTER 1 #define CONFIG_DEBUG_USER 1 #define CONFIG_DEBUG_INFO 1 diff -urN linux_lkcd_netconsole/kernel/panic.c linux/kernel/panic.c --- linux_lkcd_netconsole/kernel/panic.c Thu Dec 26 15:58:47 2002 +++ linux/kernel/panic.c Mon Dec 16 15:50:08 2002 @@ -57,8 +57,13 @@ #endif =20 #if defined(CONFIG_DUMP) || defined(CONFIG_DUMP_MODULE) +#ifdef CONFIG_ARM + _dump_regs_t regs; +#else struct pt_regs regs; +#endif get_current_regs(®s); + dump_print_all_regs(®s); #endif =20 bust_spinlocks(1); -----Original Message----- From: Feng, Fleming [mailto:fle...@in...]=20 Sent: 2002=C4=EA12=D4=C24=C8=D5 23:50 To: lkc...@li... Subject: [lkcd-devel] Supporting for XScale Platform Hi, I am planning to add support for XScale platform for LKCD. The following is some preliminary consideration of mine: 1. To add XScale support for LKCD, following questions need to be reviewe= d: When and Where to start dump. What should be dumped. How to dump. 2. For question on When and Where to start dump, I think the is no difference with i386 implementation. 3. For question on "What should be dumped.", I think the main difference will lies in architecture dependent dump header. There will be little chang= e with generic dump header, page header, page data and PAGE_END header. For XScale platform, the architecture dependent dump header will not only include general register, cpsr register, it will also include banked registers, that means all 37 registers in ARM specification should be dumped. Besides, the XScale Core defined coprocessor register (cp15 and cp14) also need to be dumped. T= his can meet basic requirements for the dumping. To fully utilize the XScale power, Trace Buffer registers and Trace Buffer contents should also be dumped. Because it will greatly help the analysis if a crash happens. 4. For question on "How to dump", because for most situation, the XScale = is used in embedded system, there may not be a disk and the flash memory has limi= ted size, I would rather to do a network dump by using netconsole. There may be a lot of points above that need to be improved. Looking forw= ard to your comments. fleming ------------------------------------------------------- This SF.net email is sponsored by: Microsoft Visual Studio.NET=20 comprehensive development tool, built to increase your=20 productivity. Try a free online hosted session at: http://ads.sourceforge.net/cgi-bin/redirect.pl?micr0003en _______________________________________________ lkcd-devel mailing list lkc...@li... https://lists.sourceforge.net/lists/listinfo/lkcd-devel |