From: Andy P. <at...@us...> - 2001-06-26 18:59:04
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv18447/kernel Modified Files: cpu_generic.c cpu_ka410.c cpu_ka42.c cpu_ka43.c cpu_ka46.c cpu_ka55.c cpu_ka630.c cpu_ka640.c cpu_ka650.c cpu_ka660.c entry.S interrupt.c interrupt.h reboot.c setup.c Log Message: machine check fixes. separate pgalloc.h routines into arch/vax/mm/pgalloc.c Index: cpu_generic.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_generic.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- cpu_generic.c 2001/01/17 16:13:57 1.1 +++ cpu_generic.c 2001/06/26 18:59:00 1.2 @@ -11,6 +11,19 @@ * Stuff that is specific to a given CPU can be found in cpu_XXX.c */ +/* + * Generic reboot and halt functions are in reboot.c + * CPUs that need to do special stuff in their halt and reboot functions + * should point to their own functions in their machine vector, + * otherwise they can leave NULL in the machine vector slots for these + * functions + * + * atp. This holds for machine check functions too. Leave a NULL if you + * just want a halt instruction on receipt of a machine check. + * See VARM Chapter 5 for details on machine check frames. + */ + + #include <asm/dz11.h> #include <asm/io.h> /* For ioremap() */ #include <asm/mtpr.h> @@ -71,6 +84,7 @@ : "r2" ); } + int ka46_48_49_prom_getchar(void) { /* Not yet implemented */ @@ -102,6 +116,7 @@ only be used after VM is enabled and the DZ11 registers have been mapped by map_dz11_regs(). */ + /* This gets set to non-NULL once the I/O page has been mapped */ volatile struct dz11_regs *dz11_addr = NULL; @@ -109,6 +124,7 @@ console. Normally it is line 3 */ static unsigned int dz11_line; + /* stuff a char out of a DZ11-compatible serial chip */ void dz11_putchar(int c) { @@ -148,6 +164,7 @@ while ( ((txcs = dz11_addr->csr ) & DZ11_CSR_TRDY) == 0) ; } + int dz11_getchar(void) { /* Not yet implemented */ @@ -164,11 +181,5 @@ dz11_addr = ioremap(dz11_phys_addr, sizeof(*dz11_addr)); } - -/* - * Generic reboot and halt functions. CPUs that need to do special stuff - * here should point to their own functions in their machine vector, - * otherwise they can leave NULL in the machine vector slots for these - * functions - */ + Index: cpu_ka410.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka410.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- cpu_ka410.c 2001/01/17 16:13:57 1.1 +++ cpu_ka410.c 2001/06/26 18:59:00 1.2 @@ -38,6 +38,8 @@ NULL, /* reboot */ NULL, /* halt */ + + NULL, /* mcheck - machine check */ NULL, /* init_devices */ Index: cpu_ka42.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka42.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- cpu_ka42.c 2001/02/22 22:36:42 1.4 +++ cpu_ka42.c 2001/06/26 18:59:00 1.5 @@ -43,6 +43,7 @@ NULL, /* reboot */ NULL, /* halt */ + NULL, /* mcheck - machine check */ ka42_init_devices, /* init_devices */ Index: cpu_ka43.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka43.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- cpu_ka43.c 2001/03/04 23:50:30 1.5 +++ cpu_ka43.c 2001/06/26 18:59:00 1.6 @@ -9,6 +9,7 @@ * 2000/04/01 Mattias Nordlund * Fixed the cache initializing, added the functions * ka43_cache_disbale/enable/clear and moved some stuff around. + * atp jun 2001 - machine check implementation */ #include <linux/types.h> /* For NULL */ @@ -28,6 +29,7 @@ void ka43_cache_disable(volatile unsigned int *creg_addr); void ka43_cache_clear(volatile unsigned int *ctag_addr); void ka43_cache_enable(volatile unsigned int *creg_addr); +void ka43_mcheck(void *stkframe); void ka43_init_devices(void); @@ -35,6 +37,14 @@ /* Internal CPU register space */ static volatile struct ka43_cpu_regs *cpu_regs; +/* We keep the cache page remaps handy incase we want to reset the cache + - see the machine check etc.. + - perhaps we should bung this in the mv too. + atp jun 01 + */ +static volatile unsigned int *ka43_ctag_addr; +static volatile unsigned int *ka43_creg_addr; + struct ka43_machine_vector { struct vax_mv mv; @@ -56,7 +66,8 @@ NULL, /* reboot */ NULL, /* halt */ - + ka43_mcheck, /* mcheck - machine check */ + ka43_init_devices, ka43_cpu_type_str @@ -73,18 +84,16 @@ mv_ka43.sidex = *(unsigned int *)RIGEL_SIDEX_ADDR; } +/* dont call ka43_cache_reset before this function (unlikely) */ void ka43_post_vm_init(void) { - volatile unsigned int *ctag_addr; - volatile unsigned int *creg_addr; - init_dz11_console(0x200A0000, 3); dz_serial_console_init(0, 0); cpu_regs = ioremap(KA43_CPU_BASE, KA43_CPU_SIZE); - creg_addr = ioremap(KA43_CH2_CREG, 1); - ctag_addr = ioremap(KA43_CT2_BASE, KA43_CT2_SIZE); + ka43_creg_addr = ioremap(KA43_CH2_CREG, 1); + ka43_ctag_addr = ioremap(KA43_CT2_BASE, KA43_CT2_SIZE); /* Disable parity on DMA and CPU memory accesses. Don't know what the story is with this, but VMS seems do this too... */ @@ -93,13 +102,10 @@ /* * Resetting the cache involves disabling it, then clear it and enable again. */ - ka43_cache_disable(creg_addr); - ka43_cache_clear(ctag_addr); - ka43_cache_enable(creg_addr); - - /* Don't need these mappings any more */ - iounmap((void *)ctag_addr); - iounmap((void *)creg_addr); + ka43_cache_disable(ka43_creg_addr); + ka43_cache_clear(ka43_ctag_addr); + ka43_cache_enable(ka43_creg_addr); + } void ka43_cache_disable(volatile unsigned int *creg_addr) @@ -148,6 +154,16 @@ } } +void ka43_cache_reset(void) +{ + /* + * Resetting the cache involves disabling it, then clear it and enable again. + */ + ka43_cache_disable(ka43_creg_addr); + ka43_cache_clear(ka43_ctag_addr); + ka43_cache_enable(ka43_creg_addr); +} + void ka43_init_devices(void) { #ifdef CONFIG_VSBUS @@ -161,4 +177,29 @@ return "KA43"; } +/* if this seems very similar to the netbsd implementation, then + * it is. After all how many ways can you check a sequence of flags? + */ +void ka43_mcheck(void *stkframe) +{ + /* map the frame to the stack */ + struct ka43_mcframe *ka43frame = (struct ka43_mcframe *)stkframe; + + /* tell us all about it */ + printk("KA43: machine check %d (0x%x)\n", ka43frame->mc43_code, ka43frame->mc43_code); + printk("KA43: reason: %s\n", ka43_mctype[ka43frame->mc43_code & 0xff]); + + /* fixme check restart and first part done flags */ + + if ((ka43frame->mc43_code & KA43_MC_RESTART) || + (ka43frame->mc43_psl & KA43_PSL_FPDONE)) { + printk("ka43_mchk: recovering from machine-check.\n"); + ka43_cache_reset(); /* reset caches */ + return; /* go on; */ + } + + /* Unknown error state, panic/halt the machine */ + printk("KA43: Machine Check - unknown error state - halting\n"); + machine_halt(); +} Index: cpu_ka46.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka46.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- cpu_ka46.c 2001/02/22 22:36:42 1.5 +++ cpu_ka46.c 2001/06/26 18:59:00 1.6 @@ -48,7 +48,8 @@ NULL, /* reboot */ NULL, /* halt */ - + NULL, /* mcheck - machine check */ + ka46_init_devices, /* init_devices */ ka46_cpu_type_str Index: cpu_ka55.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka55.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- cpu_ka55.c 2001/02/11 23:47:25 1.3 +++ cpu_ka55.c 2001/06/26 18:59:00 1.4 @@ -46,7 +46,8 @@ NULL, /* halt */ NULL, /* init_devices */ - + NULL, /* mcheck - machine check */ + ka55_cpu_type_str }, 0 /* System ID Extension from ROM */ Index: cpu_ka630.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka630.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- cpu_ka630.c 2001/01/17 16:13:57 1.1 +++ cpu_ka630.c 2001/06/26 18:59:00 1.2 @@ -39,7 +39,8 @@ NULL, /* reboot */ NULL, /* halt */ - + NULL, /* mcheck - machine check */ + NULL, /* init_devices */ ka630_cpu_type_str Index: cpu_ka640.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka640.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- cpu_ka640.c 2001/01/17 16:13:57 1.1 +++ cpu_ka640.c 2001/06/26 18:59:00 1.2 @@ -40,7 +40,8 @@ NULL, /* reboot */ NULL, /* halt */ - + NULL, /* mcheck - machine check */ + NULL, /* init_devices */ ka640_cpu_type_str Index: cpu_ka650.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka650.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- cpu_ka650.c 2001/01/17 16:13:57 1.1 +++ cpu_ka650.c 2001/06/26 18:59:00 1.2 @@ -40,7 +40,8 @@ NULL, /* reboot */ NULL, /* halt */ - + NULL, /* mcheck - machine check */ + NULL, /* init_devices */ ka650_cpu_type_str Index: cpu_ka660.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/cpu_ka660.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- cpu_ka660.c 2001/01/17 16:13:57 1.1 +++ cpu_ka660.c 2001/06/26 18:59:00 1.2 @@ -44,7 +44,8 @@ NULL, /* reboot */ NULL, /* halt */ - + NULL, /* mcheck - machine check */ + NULL, /* init_devices */ ka660_cpu_type_str Index: entry.S =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/entry.S,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- entry.S 2001/05/27 12:34:13 1.4 +++ entry.S 2001/06/26 18:59:00 1.5 @@ -5,6 +5,7 @@ Copyright Dec 1998 atp. Copyright 2000, Kenn Humborg <ke...@li...> + 2001 atp. Additions for Machine check handling. */ #include <linux/sys.h> @@ -12,7 +13,7 @@ /* irqvec_handler is the generic handler for all interrupts and exceptions for which a driver (or other code) has registered - a handler. We are responsible for + a handler. Except machine checks. We are responsible for o saving all registers @@ -28,6 +29,7 @@ See Documentation/vax/interrupts.txt for the gory details */ + .globl irqvec_handler irqvec_handler: /* At this point stack looks like: @@ -218,6 +220,34 @@ popr $0x3fff /* restore R0 to FP */ moval 4(sp), sp /* Remove handler_PC */ rei + +/* mcheck_handler is the handler for machine check exceptions. + This is here, because its easier to special case it, and deal with + the machine dependent number of longwords than warp the generic + registration methods to deal with it + atp jun 2001 + */ +/* ensure longword alignment */ +.align 2 +.globl machine_check_handler +machine_check_handler: +/* Note this doesnt use the usual exception registration, as we dont + * know in advance how many longwords of exception info have been pushed. + * + * The interrupt stack at this point looks like this + * SP: longword count of exception info + * exception longwords + * : + * PC + * PSL + */ + pushr $0x3f /* push all registers in case we can restart */ + pushab 24(sp) /* address of stack slot which holds byte count */ + calls $1, machine_check /* in reboot.c */ + popr $0x3f /* spring them off */ + addl2 (sp)+,sp /* get rid of the machine check frame */ + + rei /* dismiss */ .data .globl sys_call_table Index: interrupt.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/interrupt.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- interrupt.c 2001/05/27 13:25:29 1.11 +++ interrupt.c 2001/06/26 18:59:00 1.12 @@ -94,17 +94,27 @@ SCB_VECTOR(i) = &stray_handlers[i].inst_jsb; } + flush_icache(); } void trap_init(void) { - /* Initialize the SCB with the stray interrupt/exception + extern void machine_check_handler(void); + void *mhandler; + + /* Initialize the SCB with the stray interrupt/exception handlers. Some of these will be overridden later as device drivers hook up to their interrupts. */ setup_scb(); + /* Install the specific machine check handler in entry.S + * bits 0-1 must contain 1. machine check handler is longword aligned + */ + mhandler = (void *)(machine_check_handler) + 1; + scb.scb.mcheck = mhandler; + /* And tell the hardware to use this SCB */ __mtpr(__pa(&scb), PR_SCBB); @@ -137,10 +147,11 @@ } /* Perhaps this should be done in CPU-specific code? */ - if (register_excep_handler(0x15, corrected_read_handler, 0, 0)) { + if (register_excep_handler(SCB_MEMCORR, corrected_read_handler, 0, 0)) { printk("Panic: unable to register corrected read handler\n"); machine_halt(); } + } void init_IRQ(void) Index: interrupt.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/interrupt.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- interrupt.h 2001/01/29 00:56:19 1.4 +++ interrupt.h 2001/06/26 18:59:00 1.5 @@ -65,4 +65,3 @@ extern void reserved_instr_handler(struct pt_regs *regs, void *excep_info); extern void corrected_read_handler(struct pt_regs *regs, void *excep_info); extern void syscall_handler(struct pt_regs *regs, void *excep_info); - Index: reboot.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/reboot.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- reboot.c 2001/01/17 16:13:57 1.1 +++ reboot.c 2001/06/26 18:59:00 1.2 @@ -3,7 +3,9 @@ This file contains the standard functions that the arch-independent kernel expects for halting, rebooting and powering off the machine. - + + It also contains the machine check dispatcher + The real work will be done by cpu-specific code via the machine vector. Eventually... @@ -49,6 +51,20 @@ mv->halt(); while (1); +} + +/* This is called directly, from entry.S + * It checks for a cpu specific machine check handler and hands over to it. + * Otherwise it will just halt, as there is no way to recover without a + * sensible cpu specific routine + */ +void machine_check(void *stkframe) +{ + if (mv->mcheck == NULL) { + printk("machine check - CPU specific handler not implemented - halting\n"); + machine_halt(); + } + mv->mcheck(stkframe); } Index: setup.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/setup.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- setup.c 2001/06/08 20:11:10 1.8 +++ setup.c 2001/06/26 18:59:00 1.9 @@ -65,7 +65,7 @@ * atp -- have a temporary one. * Shouldn't we use strcpy here? */ - memcpy(command_line, "root=/dev/nfs nfsroot=/tftpboot/vaxroot\0",54); + memcpy(command_line, "root=/dev/nfs nfsroot=/tftpboot/vaxroot rw debug\0",63); *cmdline_p = command_line; /* Save unparsed command line copy for /proc/cmdline */ memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); |