* [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a
@ 2005-03-28 14:15 jayalk
2005-03-28 14:36 ` H. Peter Anvin
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: jayalk @ 2005-03-28 14:15 UTC (permalink / raw)
To: hpa; +Cc: linux-kernel, davej
Hi Riley, Dave, Peter, i386 boot/workaround maintainers,
I ran into a problem getting reboot working with 2.6.11 on an embedded
board. The board has a Geode GX1 with a CS5530A companion. What I observe on
reboot is the "Restarting system" printk, and then a cpu stall/hang. I think
the problem arises because the keyboard controller is disabled by the BIOS,
so the traditional mach_reboot()'s output to port 0x64 is ignored. Then the
386 triple fault issued after mach_reboot() results in a shutdown (because
the hardware doesn't have to detect the triple fault and issue a reset).
That then gives the end result of a stalled cpu/hang.
I found that the CS5530A in question has a "issue system wide reset" bit.
The reboot works cleanly if I write that bit rather than do mach_reboot().
So the following patch is my attempt to incorporate that change into 2.6.11
by adding a X86_REBOOTFIXUPS option. In order to keep reboot.c free of hw
specific fixups, I put it in another file, reboot_fixups.c. I tried to make
it a bit generic so that if there are other reboot related fixups for other
chipsets/boards, there'd be a clean place to put it. Please let me know what
you think.
Thanks,
Jaya Kumar
---
Signed-off-by: Jaya Kumar <jayalk@intworks.biz>
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/Kconfig linux-2.6.11.2/arch/i386/Kconfig
--- linux-2.6.11.2-vanilla/arch/i386/Kconfig 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/Kconfig 2005-03-28 21:30:15.000000000 +0800
@@ -645,6 +645,23 @@ config I8K
Say Y if you intend to run this kernel on a Dell Inspiron 8000.
Say N otherwise.
+config X86_REBOOTFIXUPS
+ bool "Enable X86 Board Specific Fixups for Reboot"
+ depends on X86
+ default n
+ ---help---
+ This enables chipset and/or board specific fixups to be done
+ in order to get reboot to work correctly. This is only needed on
+ some combinations of hardware and BIOS. The symptom, for which
+ this config is intended, is when reboot ends with a stalled/hung
+ system.
+
+ Currently, the only fixup is for the Geode GX1/CS5530A/TROM2.1.
+ combination.
+
+ Say Y if you want to enable the fixup.
+ Say N otherwise.
+
config MICROCODE
tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"
---help---
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/kernel/Makefile linux-2.6.11.2/arch/i386/kernel/Makefile
--- linux-2.6.11.2-vanilla/arch/i386/kernel/Makefile 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/kernel/Makefile 2005-03-28 15:56:31.000000000 +0800
@@ -23,6 +23,7 @@ obj-$(CONFIG_X86_TRAMPOLINE) += trampoli
obj-$(CONFIG_X86_MPPARSE) += mpparse.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o
+obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o
obj-$(CONFIG_X86_NUMAQ) += numaq.o
obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o
obj-$(CONFIG_KPROBES) += kprobes.o
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/kernel/reboot.c linux-2.6.11.2/arch/i386/kernel/reboot.c
--- linux-2.6.11.2-vanilla/arch/i386/kernel/reboot.c 2005-03-10 16:31:25.000000000 +0800
+++ linux-2.6.11.2/arch/i386/kernel/reboot.c 2005-03-28 21:36:39.562079136 +0800
@@ -14,6 +14,10 @@
#include <asm/apic.h>
#include "mach_reboot.h"
+#ifdef CONFIG_X86_REBOOTFIXUPS
+extern void mach_reboot_fixups(void);
+#endif
+
/*
* Power off function, if any
*/
@@ -348,6 +352,9 @@ void machine_restart(char * __unused)
/* rebooting needs to touch the page at absolute addr 0 */
*((unsigned short *)__va(0x472)) = reboot_mode;
for (;;) {
+#ifdef CONFIG_X86_REBOOTFIXUPS
+ mach_reboot_fixups();
+#endif
mach_reboot();
/* That didn't work - force a triple fault.. */
__asm__ __volatile__("lidt %0": :"m" (no_idt));
diff -uprN -X dontdiff linux-2.6.11.2-vanilla/arch/i386/kernel/reboot_fixups.c linux-2.6.11.2/arch/i386/kernel/reboot_fixups.c
--- linux-2.6.11.2-vanilla/arch/i386/kernel/reboot_fixups.c 1970-01-01 07:30:00.000000000 +0730
+++ linux-2.6.11.2/arch/i386/kernel/reboot_fixups.c 2005-03-28 21:38:30.893154240 +0800
@@ -0,0 +1,40 @@
+#include <asm/delay.h>
+#include <linux/pci.h>
+
+void cs5530a_warm_reset(struct pci_dev *dev)
+{
+ /* writing 1 to the reset control register, 0x44 causes the
+ cs5530a to perform a system warm reset */
+ pci_write_config_byte(dev, 0x44, 0x1);
+ udelay(50); /* shouldn't get here but be safe and spin-a-while */
+ return;
+}
+
+struct device_fixup {
+ unsigned int vendor;
+ unsigned int device;
+ void (*reboot_fixup)(struct pci_dev *);
+};
+
+struct device_fixup fixups_table[] = {
+ { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset },
+};
+
+void mach_reboot_fixups(void)
+{
+ struct device_fixup *cur;
+ struct pci_dev *dev;
+ int i;
+
+ for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
+ cur = fixups_table + i;
+ dev = pci_find_device(cur->vendor, cur->device, 0);
+ if (!dev)
+ continue;
+
+ cur->reboot_fixup(dev);
+ }
+
+ printk(KERN_WARNING "No reboot fixup found for your hardware\n");
+}
+
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a
2005-03-28 14:15 [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a jayalk
@ 2005-03-28 14:36 ` H. Peter Anvin
2005-03-28 14:38 ` H. Peter Anvin
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: H. Peter Anvin @ 2005-03-28 14:36 UTC (permalink / raw)
To: jayalk; +Cc: linux-kernel, davej
jayalk@intworks.biz wrote:
> Hi Riley, Dave, Peter, i386 boot/workaround maintainers,
>
> I ran into a problem getting reboot working with 2.6.11 on an embedded
> board. The board has a Geode GX1 with a CS5530A companion. What I observe on
> reboot is the "Restarting system" printk, and then a cpu stall/hang. I think
> the problem arises because the keyboard controller is disabled by the BIOS,
> so the traditional mach_reboot()'s output to port 0x64 is ignored. Then the
> 386 triple fault issued after mach_reboot() results in a shutdown (because
> the hardware doesn't have to detect the triple fault and issue a reset).
> That then gives the end result of a stalled cpu/hang.
>
> I found that the CS5530A in question has a "issue system wide reset" bit.
> The reboot works cleanly if I write that bit rather than do mach_reboot().
> So the following patch is my attempt to incorporate that change into 2.6.11
> by adding a X86_REBOOTFIXUPS option. In order to keep reboot.c free of hw
> specific fixups, I put it in another file, reboot_fixups.c. I tried to make
> it a bit generic so that if there are other reboot related fixups for other
> chipsets/boards, there'd be a clean place to put it. Please let me know what
> you think.
>
This makes a lot of sense to me. I appreciate the fact that you took
the time to properly add detection/abstraction code.
-hpa
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a
2005-03-28 14:15 [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a jayalk
2005-03-28 14:36 ` H. Peter Anvin
@ 2005-03-28 14:38 ` H. Peter Anvin
2005-03-28 17:27 ` Jesper Juhl
2005-03-28 21:17 ` Sam Ravnborg
3 siblings, 0 replies; 7+ messages in thread
From: H. Peter Anvin @ 2005-03-28 14:38 UTC (permalink / raw)
To: jayalk; +Cc: linux-kernel, davej
jayalk@intworks.biz wrote:
>
> +#ifdef CONFIG_X86_REBOOTFIXUPS
> +extern void mach_reboot_fixups(void);
> +#endif
> +
However, it would be nice if this could go in a header file instead of
being a "naked extern".
-hpa
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a
2005-03-28 14:15 [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a jayalk
2005-03-28 14:36 ` H. Peter Anvin
2005-03-28 14:38 ` H. Peter Anvin
@ 2005-03-28 17:27 ` Jesper Juhl
2005-03-28 21:17 ` Sam Ravnborg
3 siblings, 0 replies; 7+ messages in thread
From: Jesper Juhl @ 2005-03-28 17:27 UTC (permalink / raw)
To: jayalk; +Cc: hpa, linux-kernel, davej
On Mon, 28 Mar 2005 jayalk@intworks.biz wrote:
> Hi Riley, Dave, Peter, i386 boot/workaround maintainers,
>
> +config X86_REBOOTFIXUPS
> + bool "Enable X86 Board Specific Fixups for Reboot"
> + depends on X86
> + default n
> + ---help---
> + This enables chipset and/or board specific fixups to be done
> + in order to get reboot to work correctly. This is only needed on
> + some combinations of hardware and BIOS. The symptom, for which
> + this config is intended, is when reboot ends with a stalled/hung
> + system.
> +
> + Currently, the only fixup is for the Geode GX1/CS5530A/TROM2.1.
> + combination.
> +
> + Say Y if you want to enable the fixup.
> + Say N otherwise.
> +
I'd think it would be nice if the help text had a note telling the user if
it's safe to always enable this or not, even if it's not needed. Something
along the lines of "It's safe to always enable this config option even if
you don't need it." or "This option should only be enabled if needed as it
may cause problems otherwise." - whatever applies...
--
Jesper
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a
2005-03-28 14:15 [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a jayalk
` (2 preceding siblings ...)
2005-03-28 17:27 ` Jesper Juhl
@ 2005-03-28 21:17 ` Sam Ravnborg
2005-03-28 21:17 ` H. Peter Anvin
3 siblings, 1 reply; 7+ messages in thread
From: Sam Ravnborg @ 2005-03-28 21:17 UTC (permalink / raw)
To: jayalk; +Cc: hpa, linux-kernel, davej
Small comments below.
>
> +#ifdef CONFIG_X86_REBOOTFIXUPS
> +extern void mach_reboot_fixups(void);
> +#endif
Move this to header file.
> +#ifdef CONFIG_X86_REBOOTFIXUPS
> + mach_reboot_fixups();
> +#endif
And hide this ifdef in same hederfile.
#ifndef CONFIG_X86_REBOOTFIXUPS
#define mach_reboot_fixups do {} while (0);
#endif
Sam
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a
2005-03-28 21:17 ` Sam Ravnborg
@ 2005-03-28 21:17 ` H. Peter Anvin
2005-03-28 21:43 ` H. Peter Anvin
0 siblings, 1 reply; 7+ messages in thread
From: H. Peter Anvin @ 2005-03-28 21:17 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: jayalk, linux-kernel, davej
Sam Ravnborg wrote:
>
> And hide this ifdef in same hederfile.
>
> #ifndef CONFIG_X86_REBOOTFIXUPS
> #define mach_reboot_fixups do {} while (0);
> #endif
>
No semicolon; besides:
#define mach_reboot_fixups(x) ((void)0)
... is better all around.
-hpa
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a
2005-03-28 21:17 ` H. Peter Anvin
@ 2005-03-28 21:43 ` H. Peter Anvin
0 siblings, 0 replies; 7+ messages in thread
From: H. Peter Anvin @ 2005-03-28 21:43 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Sam Ravnborg, jayalk, linux-kernel, davej
H. Peter Anvin wrote:
> Sam Ravnborg wrote:
>
>>
>> And hide this ifdef in same hederfile.
>>
>> #ifndef CONFIG_X86_REBOOTFIXUPS
>> #define mach_reboot_fixups do {} while (0);
>> #endif
>>
>
> No semicolon; besides:
>
> #define mach_reboot_fixups(x) ((void)0)
>
> ... is better all around.
>
Correction, that should have been:
#define mach_reboot_fixups(x) ((void)(x))
... in order to preserve side effects.
-hpa
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2005-03-28 21:44 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-28 14:15 [RFC 2.6.11.2 1/1] Add reboot fixup for gx1/cs5530a jayalk
2005-03-28 14:36 ` H. Peter Anvin
2005-03-28 14:38 ` H. Peter Anvin
2005-03-28 17:27 ` Jesper Juhl
2005-03-28 21:17 ` Sam Ravnborg
2005-03-28 21:17 ` H. Peter Anvin
2005-03-28 21:43 ` H. Peter Anvin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox