Re: [rft] s2ram wakeup moves to .c, could fix few machines
On Tue 2008-02-05 17:51:22, H. Peter Anvin wrote: > Rafael J. Wysocki wrote: >>> The asm() for making beeps really need to be moved to a function and >>> cleaned up (redone in C using inb()/outb()) if they are to be retained at >>> all. >> >> Yes, they are. For some people they're the only tool to debug broken resume. > > That's fine, but they should get cleaned up. > > /me is tempted to provide a version which can send messages in Morse Code ;) Actually, it would probably be accepted. Debugging early resume is evil enough that any help is welcome. Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [rft] s2ram wakeup moves to .c, could fix few machines
On Tue 2008-02-05 17:51:22, H. Peter Anvin wrote: Rafael J. Wysocki wrote: The asm() for making beeps really need to be moved to a function and cleaned up (redone in C using inb()/outb()) if they are to be retained at all. Yes, they are. For some people they're the only tool to debug broken resume. That's fine, but they should get cleaned up. /me is tempted to provide a version which can send messages in Morse Code ;) Actually, it would probably be accepted. Debugging early resume is evil enough that any help is welcome. Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [rft] s2ram wakeup moves to .c, could fix few machines
On Tuesday, 5 of February 2008, Pavel Machek wrote: This rewrites wakeup code to .c, and it fixes stack (should use movl ,%esp, not movw). Testers wanted. Makefile infrastructure was done by hpa, cleanups by rjw. Signed-off-by: Pavel Machek [EMAIL PROTECTED] [--snip--] diff --git a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86_64/kernel/acpi/wakeup.S new file mode 100644 index 000..d0f40d9 --- /dev/null +++ b/arch/x86_64/kernel/acpi/wakeup.S Surely this is not intentional? @@ -0,0 +1,425 @@ +.text +#include linux/linkage.h +#include asm/segment.h +#include asm/pgtable.h +#include asm/page.h +#include asm/msr.h + +# Copyright 2003 Pavel Machek [EMAIL PROTECTED], distribute under GPLv2 +# +# wakeup_code runs in real mode, and at unknown address (determined at run-time). +# Therefore it must only use relative jumps/calls. +# +# Do we need to deal with A20? It is okay: ACPI specs says A20 must be enabled +# +# If physical address of wakeup_code is 0x12345, BIOS should call us with +# cs = 0x1234, eip = 0x05 +# + +#define BEEP \ + inb $97, %al; \ + outb%al, $0x80; \ + movb$3, %al;\ + outb%al, $97; \ + outb%al, $0x80; \ + movb$-74, %al; \ + outb%al, $67; \ + outb%al, $0x80; \ + movb$-119, %al; \ + outb%al, $66; \ + outb%al, $0x80; \ + movb$15, %al; \ + outb%al, $66; + + +ALIGN + .align 16 +ENTRY(wakeup_start) +wakeup_code: + wakeup_code_start = . + .code16 + +# Running in *copy* of this code, somewhere in low 1MB. + + cli + cld + # setup data segment + movw%cs, %ax + movw%ax, %ds# Make ds:0 point to wakeup_start + movw%ax, %ss + + # Data segment must be set up before we can see whether to beep. + testl $4, realmode_flags - wakeup_code + jz 1f + BEEP +1: + + # Private stack is needed for ASUS board + mov $(wakeup_stack - wakeup_code), %sp + + pushl $0 # Kill any dangerous flags + popfl + + movlreal_magic - wakeup_code, %eax + cmpl$0x12345678, %eax + jne bogus_real_magic + + testl $1, realmode_flags - wakeup_code + jz 1f + lcall $0xc000,$3 + movw%cs, %ax + movw%ax, %ds# Bios might have played with that + movw%ax, %ss +1: + + testl $2, realmode_flags - wakeup_code + jz 1f + mov video_mode - wakeup_code, %ax + callmode_set +1: + + mov %ds, %ax# Find 32bit wakeup_code addr + movzx %ax, %esi # (Convert %ds:gdt to a liner ptr) + shll$4, %esi + # Fix up the vectors + addl%esi, wakeup_32_vector - wakeup_code + addl%esi, wakeup_long64_vector - wakeup_code + addl%esi, gdt_48a + 2 - wakeup_code # Fixup the gdt pointer + + lidtl %ds:idt_48a - wakeup_code + lgdtl %ds:gdt_48a - wakeup_code # load gdt with whatever is + # appropriate + + movl$1, %eax# protected mode (PE) bit + lmsw%ax # This is it! + jmp 1f +1: + + ljmpl *(wakeup_32_vector - wakeup_code) + + .balign 4 +wakeup_32_vector: + .long wakeup_32 - wakeup_code + .word __KERNEL32_CS, 0 + + .code32 +wakeup_32: +# Running in this code, but at low address; paging is not yet turned on. + + movl$__KERNEL_DS, %eax + movl%eax, %ds + + /* + * Prepare for entering 64bits mode + */ + + /* Enable PAE */ + xorl%eax, %eax + btsl$5, %eax + movl%eax, %cr4 + + /* Setup early boot stage 4 level pagetables */ + leal(wakeup_level4_pgt - wakeup_code)(%esi), %eax + movl%eax, %cr3 + +/* Check if nx is implemented */ +movl$0x8001, %eax +cpuid +movl%edx,%edi + + /* Enable Long Mode */ + xorl%eax, %eax + btsl$_EFER_LME, %eax + + /* No Execute supported? */ + btl $20,%edi + jnc 1f + btsl$_EFER_NX, %eax + + /* Make changes effective */ +1: movl$MSR_EFER, %ecx + xorl%edx, %edx + wrmsr + + xorl%eax, %eax + btsl$31, %eax /* Enable paging and in turn activate Long Mode */ + btsl$0, %eax/* Enable protected mode */ + + /* Make changes effective */ + movl%eax, %cr0 + + /* At this point: + CR4.PAE must be 1 + CS.L must be 0 + CR3 must point to PML4 +
Re: [rft] s2ram wakeup moves to .c, could fix few machines
On Wednesday, 6 of February 2008, H. Peter Anvin wrote: > Rafael J. Wysocki wrote: > >> The asm() for making beeps really need to be moved to a function and > >> cleaned up (redone in C using inb()/outb()) if they are to be retained > >> at all. > > > > Yes, they are. For some people they're the only tool to debug broken > > resume. > > That's fine, but they should get cleaned up. I 100% agree. > /me is tempted to provide a version which can send messages in Morse Code ;) That would be great. It could also play some music or something. ;-) Rafael -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [rft] s2ram wakeup moves to .c, could fix few machines
Rafael J. Wysocki wrote: The asm() for making beeps really need to be moved to a function and cleaned up (redone in C using inb()/outb()) if they are to be retained at all. Yes, they are. For some people they're the only tool to debug broken resume. That's fine, but they should get cleaned up. /me is tempted to provide a version which can send messages in Morse Code ;) -hpa -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [rft] s2ram wakeup moves to .c, could fix few machines
On Wednesday, 6 of February 2008, H. Peter Anvin wrote: > Rafael J. Wysocki wrote: > > On Tuesday, 5 of February 2008, Pavel Machek wrote: > >> This rewrites wakeup code to .c, and it fixes stack (should use movl > >> ,%esp, not movw). Testers wanted. Makefile infrastructure was done by > >> hpa, cleanups by rjw. > > > > I'll test it tomorrow and I still have some more cleanups (I was distracted > > by > > a nasty scheduler issue in the current mainline). > > The asm() for making beeps really need to be moved to a function and > cleaned up (redone in C using inb()/outb()) if they are to be retained > at all. Yes, they are. For some people they're the only tool to debug broken resume. Rafael -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [rft] s2ram wakeup moves to .c, could fix few machines
Rafael J. Wysocki wrote: On Tuesday, 5 of February 2008, Pavel Machek wrote: This rewrites wakeup code to .c, and it fixes stack (should use movl ,%esp, not movw). Testers wanted. Makefile infrastructure was done by hpa, cleanups by rjw. I'll test it tomorrow and I still have some more cleanups (I was distracted by a nasty scheduler issue in the current mainline). The asm() for making beeps really need to be moved to a function and cleaned up (redone in C using inb()/outb()) if they are to be retained at all. -hpa -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [rft] s2ram wakeup moves to .c, could fix few machines
On Tuesday, 5 of February 2008, Pavel Machek wrote: > > This rewrites wakeup code to .c, and it fixes stack (should use movl > ,%esp, not movw). Testers wanted. Makefile infrastructure was done by > hpa, cleanups by rjw. I'll test it tomorrow and I still have some more cleanups (I was distracted by a nasty scheduler issue in the current mainline). Thanks, Rafael -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[rft] s2ram wakeup moves to .c, could fix few machines
This rewrites wakeup code to .c, and it fixes stack (should use movl ,%esp, not movw). Testers wanted. Makefile infrastructure was done by hpa, cleanups by rjw. Signed-off-by: Pavel Machek <[EMAIL PROTECTED]> diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 8978e98..949b8eb 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -192,8 +192,8 @@ drivers-$(CONFIG_PCI)+= arch # must be linked after kernel/ drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/ -ifeq ($(CONFIG_X86_32),y) drivers-$(CONFIG_PM) += arch/x86/power/ +ifeq ($(CONFIG_X86_32),y) drivers-$(CONFIG_FB) += arch/x86/video/ endif diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index 349b81a..0a5bcd3 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -30,7 +30,7 @@ subdir- := compressed setup-y+= a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o setup-y+= header.o main.o mca.o memory.o pm.o pmjump.o -setup-y+= printf.o string.o tty.o video.o version.o +setup-y+= printf.o string.o tty.o video.o video-mode.o version.o setup-$(CONFIG_X86_APM_BOOT) += apm.o setup-$(CONFIG_X86_VOYAGER) += voyager.o diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h index 7822a49..0957807 100644 --- a/arch/x86/boot/boot.h +++ b/arch/x86/boot/boot.h @@ -286,6 +286,11 @@ int getchar_timeout(void); /* video.c */ void set_video(void); +/* video-mode.c */ +int set_mode(u16 mode); +int mode_defined(u16 mode); +void probe_cards(int unsafe); + /* video-vesa.c */ void vesa_store_edid(void); diff --git a/arch/x86/boot/video-bios.c b/arch/x86/boot/video-bios.c index ff664a1..39e247e 100644 --- a/arch/x86/boot/video-bios.c +++ b/arch/x86/boot/video-bios.c @@ -50,6 +50,7 @@ static int set_bios_mode(u8 mode) if (new_mode == mode) return 0; /* Mode change OK */ +#ifndef _WAKEUP if (new_mode != boot_params.screen_info.orig_video_mode) { /* Mode setting failed, but we didn't end up where we started. That's bad. Try to revert to the original @@ -59,13 +60,18 @@ static int set_bios_mode(u8 mode) : "+a" (ax) : : "ebx", "ecx", "edx", "esi", "edi"); } +#endif return -1; } static int bios_probe(void) { u8 mode; +#ifdef _WAKEUP + u8 saved_mode = 0x03; +#else u8 saved_mode = boot_params.screen_info.orig_video_mode; +#endif u16 crtc; struct mode_info *mi; int nmodes = 0; diff --git a/arch/x86/boot/video-mode.c b/arch/x86/boot/video-mode.c new file mode 100644 index 000..18bacb3 --- /dev/null +++ b/arch/x86/boot/video-mode.c @@ -0,0 +1,173 @@ +/* -*- linux-c -*- --- * + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright 2007-2008 rPath, Inc. - All Rights Reserved + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2. + * + * --- */ + +/* + * arch/i386/boot/video-mode.c + * + * Set the video mode. This is separated out into a different + * file in order to be shared with the ACPI wakeup code. + */ + +#include "boot.h" +#include "video.h" +#include "vesa.h" + +/* + * Common variables + */ +int adapter; /* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */ +u16 video_segment; +int force_x, force_y; /* Don't query the BIOS for cols/rows */ + +int do_restore = 0;/* Screen contents changed during mode flip */ +int graphic_mode; /* Graphic mode with linear frame buffer */ + +/* Probe the video drivers and have them generate their mode lists. */ +void probe_cards(int unsafe) +{ + struct card_info *card; + static u8 probed[2]; + + if (probed[unsafe]) + return; + + probed[unsafe] = 1; + + for (card = video_cards; card < video_cards_end; card++) { + if (card->unsafe == unsafe) { + if (card->probe) + card->nmodes = card->probe(); + else + card->nmodes = 0; + } + } +} + +/* Test if a mode is defined */ +int mode_defined(u16 mode) +{ + struct card_info *card; + struct mode_info *mi; + int i; + + for (card = video_cards; card < video_cards_end; card++) { + mi = card->modes; + for (i = 0; i < card->nmodes; i++, mi++) { + if (mi->mode == mode) + return 1; + } + } + + return 0; +} + +/* Set mode (without recalc) */ +static int raw_set_mode(u16 mode, u16 *real_mode) +{ + int nmode, i; + struct card_info *card; + struct mode_info *mi; + + /* Drop the recalc bit if set */ + mode &= ~VIDEO_RECALC; + +
[rft] s2ram wakeup moves to .c, could fix few machines
This rewrites wakeup code to .c, and it fixes stack (should use movl ,%esp, not movw). Testers wanted. Makefile infrastructure was done by hpa, cleanups by rjw. Signed-off-by: Pavel Machek [EMAIL PROTECTED] diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 8978e98..949b8eb 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -192,8 +192,8 @@ drivers-$(CONFIG_PCI)+= arch # must be linked after kernel/ drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/ -ifeq ($(CONFIG_X86_32),y) drivers-$(CONFIG_PM) += arch/x86/power/ +ifeq ($(CONFIG_X86_32),y) drivers-$(CONFIG_FB) += arch/x86/video/ endif diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index 349b81a..0a5bcd3 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -30,7 +30,7 @@ subdir- := compressed setup-y+= a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o setup-y+= header.o main.o mca.o memory.o pm.o pmjump.o -setup-y+= printf.o string.o tty.o video.o version.o +setup-y+= printf.o string.o tty.o video.o video-mode.o version.o setup-$(CONFIG_X86_APM_BOOT) += apm.o setup-$(CONFIG_X86_VOYAGER) += voyager.o diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h index 7822a49..0957807 100644 --- a/arch/x86/boot/boot.h +++ b/arch/x86/boot/boot.h @@ -286,6 +286,11 @@ int getchar_timeout(void); /* video.c */ void set_video(void); +/* video-mode.c */ +int set_mode(u16 mode); +int mode_defined(u16 mode); +void probe_cards(int unsafe); + /* video-vesa.c */ void vesa_store_edid(void); diff --git a/arch/x86/boot/video-bios.c b/arch/x86/boot/video-bios.c index ff664a1..39e247e 100644 --- a/arch/x86/boot/video-bios.c +++ b/arch/x86/boot/video-bios.c @@ -50,6 +50,7 @@ static int set_bios_mode(u8 mode) if (new_mode == mode) return 0; /* Mode change OK */ +#ifndef _WAKEUP if (new_mode != boot_params.screen_info.orig_video_mode) { /* Mode setting failed, but we didn't end up where we started. That's bad. Try to revert to the original @@ -59,13 +60,18 @@ static int set_bios_mode(u8 mode) : +a (ax) : : ebx, ecx, edx, esi, edi); } +#endif return -1; } static int bios_probe(void) { u8 mode; +#ifdef _WAKEUP + u8 saved_mode = 0x03; +#else u8 saved_mode = boot_params.screen_info.orig_video_mode; +#endif u16 crtc; struct mode_info *mi; int nmodes = 0; diff --git a/arch/x86/boot/video-mode.c b/arch/x86/boot/video-mode.c new file mode 100644 index 000..18bacb3 --- /dev/null +++ b/arch/x86/boot/video-mode.c @@ -0,0 +1,173 @@ +/* -*- linux-c -*- --- * + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright 2007-2008 rPath, Inc. - All Rights Reserved + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2. + * + * --- */ + +/* + * arch/i386/boot/video-mode.c + * + * Set the video mode. This is separated out into a different + * file in order to be shared with the ACPI wakeup code. + */ + +#include boot.h +#include video.h +#include vesa.h + +/* + * Common variables + */ +int adapter; /* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */ +u16 video_segment; +int force_x, force_y; /* Don't query the BIOS for cols/rows */ + +int do_restore = 0;/* Screen contents changed during mode flip */ +int graphic_mode; /* Graphic mode with linear frame buffer */ + +/* Probe the video drivers and have them generate their mode lists. */ +void probe_cards(int unsafe) +{ + struct card_info *card; + static u8 probed[2]; + + if (probed[unsafe]) + return; + + probed[unsafe] = 1; + + for (card = video_cards; card video_cards_end; card++) { + if (card-unsafe == unsafe) { + if (card-probe) + card-nmodes = card-probe(); + else + card-nmodes = 0; + } + } +} + +/* Test if a mode is defined */ +int mode_defined(u16 mode) +{ + struct card_info *card; + struct mode_info *mi; + int i; + + for (card = video_cards; card video_cards_end; card++) { + mi = card-modes; + for (i = 0; i card-nmodes; i++, mi++) { + if (mi-mode == mode) + return 1; + } + } + + return 0; +} + +/* Set mode (without recalc) */ +static int raw_set_mode(u16 mode, u16 *real_mode) +{ + int nmode, i; + struct card_info *card; + struct mode_info *mi; + + /* Drop the recalc bit if set */ + mode = ~VIDEO_RECALC; + + /* Scan for mode based on fixed
Re: [rft] s2ram wakeup moves to .c, could fix few machines
On Tuesday, 5 of February 2008, Pavel Machek wrote: This rewrites wakeup code to .c, and it fixes stack (should use movl ,%esp, not movw). Testers wanted. Makefile infrastructure was done by hpa, cleanups by rjw. I'll test it tomorrow and I still have some more cleanups (I was distracted by a nasty scheduler issue in the current mainline). Thanks, Rafael -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [rft] s2ram wakeup moves to .c, could fix few machines
Rafael J. Wysocki wrote: On Tuesday, 5 of February 2008, Pavel Machek wrote: This rewrites wakeup code to .c, and it fixes stack (should use movl ,%esp, not movw). Testers wanted. Makefile infrastructure was done by hpa, cleanups by rjw. I'll test it tomorrow and I still have some more cleanups (I was distracted by a nasty scheduler issue in the current mainline). The asm() for making beeps really need to be moved to a function and cleaned up (redone in C using inb()/outb()) if they are to be retained at all. -hpa -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [rft] s2ram wakeup moves to .c, could fix few machines
On Wednesday, 6 of February 2008, H. Peter Anvin wrote: Rafael J. Wysocki wrote: On Tuesday, 5 of February 2008, Pavel Machek wrote: This rewrites wakeup code to .c, and it fixes stack (should use movl ,%esp, not movw). Testers wanted. Makefile infrastructure was done by hpa, cleanups by rjw. I'll test it tomorrow and I still have some more cleanups (I was distracted by a nasty scheduler issue in the current mainline). The asm() for making beeps really need to be moved to a function and cleaned up (redone in C using inb()/outb()) if they are to be retained at all. Yes, they are. For some people they're the only tool to debug broken resume. Rafael -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [rft] s2ram wakeup moves to .c, could fix few machines
Rafael J. Wysocki wrote: The asm() for making beeps really need to be moved to a function and cleaned up (redone in C using inb()/outb()) if they are to be retained at all. Yes, they are. For some people they're the only tool to debug broken resume. That's fine, but they should get cleaned up. /me is tempted to provide a version which can send messages in Morse Code ;) -hpa -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [rft] s2ram wakeup moves to .c, could fix few machines
On Wednesday, 6 of February 2008, H. Peter Anvin wrote: Rafael J. Wysocki wrote: The asm() for making beeps really need to be moved to a function and cleaned up (redone in C using inb()/outb()) if they are to be retained at all. Yes, they are. For some people they're the only tool to debug broken resume. That's fine, but they should get cleaned up. I 100% agree. /me is tempted to provide a version which can send messages in Morse Code ;) That would be great. It could also play some music or something. ;-) Rafael -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/