From: Pavel Machek <pavel@ucw.cz>
To: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: kernel list <linux-kernel@vger.kernel.org>,
Linux-pm mailing list <linux-pm@lists.osdl.org>,
"H. Peter Anvin" <hpa@zytor.com>
Subject: Re: wakeup code translated to .c
Date: Mon, 4 Feb 2008 00:33:13 +0100 [thread overview]
Message-ID: <20080203233313.GF2799@elf.ucw.cz> (raw)
In-Reply-To: <200802040020.14836.rjw@sisk.pl>
On Mon 2008-02-04 00:20:14, Rafael J. Wysocki wrote:
> On Sunday, 3 of February 2008, Rafael J. Wysocki wrote:
> > On Sunday, 3 of February 2008, Pavel Machek wrote:
> > > Hi!
> > >
> > > > > This version works on 32-bit, and builds on 64-bit (but I'm pretty
> > > > > sure it does not work. 32-bit code probably needs to go into rm/....)
> > > > >
> > > >
> > > > Do you have an updated version or is this the latest one?
> > >
> > > I'm glad you ask ;-). Here's reasonably-recent version (I have
> > > slightly cleaner one, but it got obscured by 2.6.24-git merge), I
> > > eventually got it to work on 64-bit, by reusing trampoline.S code.
> >
> > I needed to rebase it against the current mainline (Makefile conflict).
> >
> > Some remarks:
> >
> > - It looks like arch/x86/kernel/acpi/wakeup.S is not necessary any more.
> >
> > - These warnings:
> >
> > /home/rafael/src/linux-2.6/arch/x86/kernel/acpi/sleep.c: In function ???acpi_save_state_mem???:
> > /home/rafael/src/linux-2.6/arch/x86/kernel/acpi/sleep.c:41: warning: initialization makes pointer from integer without a cast
> > /home/rafael/src/linux-2.6/arch/x86/kernel/acpi/sleep.c:50: warning: format ???%d??? expects type ???int???, but argument 2 has type ???long unsigned int???
> > /home/rafael/src/linux-2.6/arch/x86/kernel/acpi/sleep.c:50: warning: format ???%d??? expects type ???int???, but argument 3 has type ???long unsigned int???
> > /home/rafael/src/linux-2.6/arch/x86/kernel/acpi/sleep.c:70: warning: ISO C90 forbids mixed declarations and code
> > /home/rafael/src/linux-2.6/arch/x86/kernel/acpi/sleep.c:82: warning: assignment makes integer from pointer without a cast
> > /home/rafael/src/linux-2.6/arch/x86/kernel/acpi/sleep.c:83: warning: assignment makes integer from pointer without a cast
> > /home/rafael/src/linux-2.6/arch/x86/kernel/acpi/sleep.c:84: warning: ISO C90 forbids mixed declarations and code
> > /home/rafael/src/linux-2.6/arch/x86/kernel/acpi/sleep.c:87: warning: ISO C90 forbids mixed declarations and code
> > /home/rafael/src/linux-2.6/arch/x86/kernel/acpi/sleep.c:90: warning: assignment makes integer from pointer without a cast
> > /home/rafael/src/linux-2.6/arch/x86/kernel/acpi/sleep.c:91: warning: ISO C90 forbids mixed declarations and code
> >
> > look pretty scary.
>
> Below is the arch/x86/kernel/acpi/sleep.c part without the warnings (untested).
>
> It still contains some hardcoded magic numbers and extern declarations, so
> I guess the #include list is not complete or another header is necessary.
>
> BTW:
> 1) why exactly is acpi_wakeup_address not (void *)?
Well, it is physical address, not really a pointer.
> 2) header->level3_ident_pgt and header->level3_ident_pgt could be
(char *) IMO
Those are unused, they can be deleted ;-).
Pavel
> --- linux-2.6.orig/arch/x86/kernel/acpi/sleep.c
> +++ linux-2.6/arch/x86/kernel/acpi/sleep.c
> @@ -11,29 +11,92 @@
> #include <linux/cpumask.h>
>
> #include <asm/smp.h>
> +#include "rm/wakeup.h"
>
> /* address in low memory of the wakeup routine. */
> -unsigned long acpi_wakeup_address = 0;
> +static unsigned long acpi_realmode;
> +unsigned long acpi_wakeup_address;
> unsigned long acpi_realmode_flags;
> -extern char wakeup_start, wakeup_end;
>
> +extern char wakeup_code_start, wakeup_code_end;
> extern unsigned long acpi_copy_wakeup_routine(unsigned long);
> +extern unsigned long setup_trampoline(void);
> +extern void wakeup_long64(void);
> +
> +extern unsigned long saved_video_mode;
> +extern long saved_magic;
> +extern char level3_ident_pgt[PAGE_SIZE];
> +extern char level3_kernel_pgt[PAGE_SIZE];
> +extern volatile unsigned long init_rsp;
> +extern void (*initial_code)(void);
> +#ifndef CONFIG_64BIT
> +extern int wakeup_pmode_return;
> +extern char swsusp_pg_dir[PAGE_SIZE];
> +#endif
> +
> +static char temp_stack[10240];
>
> /**
> * acpi_save_state_mem - save kernel state
> *
> * Create an identity mapped page table and copy the wakeup routine to
> * low memory.
> + *
> + * Note that this is too late to change acpi_wakeup_address.
> */
> int acpi_save_state_mem(void)
> {
> - if (!acpi_wakeup_address) {
> - printk(KERN_ERR "Could not allocate memory during boot, S3 disabled\n");
> + struct wakeup_header *header;
> +
> + printk("acpi_save_state_mem\n");
> +
> + if (!acpi_realmode) {
> + printk(KERN_ERR "Could not allocate memory during boot, "
> + "S3 disabled\n");
> return -ENOMEM;
> }
> - memcpy((void *)acpi_wakeup_address, &wakeup_start,
> - &wakeup_end - &wakeup_start);
> - acpi_copy_wakeup_routine(acpi_wakeup_address);
> +
> + memcpy((void *)acpi_realmode, &wakeup_code_start, 4*PAGE_SIZE);
> +
> + header = (struct wakeup_header *)(acpi_realmode + 0x3f00);
> + if (header->signature != 0x51ee1111) {
> + printk(KERN_ERR "wakeup header does not match\n");
> + return -EINVAL;
> + }
> +
> + header->video_mode = saved_video_mode;
> + printk("Video mode = %lu, realmode flags = %lu\n",
> + saved_video_mode, acpi_realmode_flags);
> + mdelay(1000);
> +
> +#ifndef CONFIG_64BIT
> + store_gdt(&header->pmode_gdt);
> +
> + header->pmode_efer_low = nx_enabled;
> + if (header->pmode_efer_low & 1) {
> + /* This is strange, why not save efer, always? */
> + rdmsr(MSR_EFER, header->pmode_efer_low,
> + header->pmode_efer_high);
> + }
> +#endif /* !CONFIG_64BIT */
> +
> + header->pmode_cr0 = read_cr0();
> + header->pmode_cr4 = read_cr4();
> + header->realmode_flags = acpi_realmode_flags;
> + header->real_magic = 0x12345678;
> +
> +#ifndef CONFIG_64BIT
> + header->pmode_entry = &wakeup_pmode_return;
> + header->pmode_cr3 = swsusp_pg_dir - __PAGE_OFFSET;
> + saved_magic = 0x12345678;
> +#else /* CONFIG_64BIT */
> + header->level3_ident_pgt = (u64)level3_ident_pgt;
> + header->level3_kernel_pgt = (u64)level3_kernel_pgt;
> + header->trampoline_segment = setup_trampoline() >> 4;
> + init_rsp = (unsigned long)temp_stack + 4096;
> + initial_code = wakeup_long64;
> + saved_magic = 0x123456789abcdef0;
> +#endif /* CONFIG_64BIT */
>
> return 0;
> }
> @@ -56,15 +119,20 @@ void acpi_restore_state_mem(void)
> */
> void __init acpi_reserve_bootmem(void)
> {
> - if ((&wakeup_end - &wakeup_start) > PAGE_SIZE*2) {
> + if ((&wakeup_code_end - &wakeup_code_start) > PAGE_SIZE*4) {
> printk(KERN_ERR
> "ACPI: Wakeup code way too big, S3 disabled.\n");
> return;
> }
>
> - acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE*2);
> - if (!acpi_wakeup_address)
> + acpi_realmode = (unsigned long)alloc_bootmem_low(PAGE_SIZE*4);
> +
> + if (!acpi_realmode) {
> printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
> + return;
> + }
> +
> + acpi_wakeup_address = acpi_realmode;
> }
>
>
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
next prev parent reply other threads:[~2008-02-03 23:33 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-30 12:01 wakeup code translated to .c Pavel Machek
2008-02-03 17:57 ` Rafael J. Wysocki
2008-02-03 18:16 ` Pavel Machek
2008-02-03 18:24 ` Rafael J. Wysocki
2008-02-03 18:49 ` Sam Ravnborg
2008-02-03 20:02 ` H. Peter Anvin
2008-02-03 22:24 ` Pavel Machek
2008-02-03 22:27 ` Sam Ravnborg
2008-02-04 12:44 ` Pavel Machek
2008-02-03 22:33 ` Rafael J. Wysocki
2008-02-03 23:20 ` Rafael J. Wysocki
2008-02-03 23:30 ` [linux-pm] " Rafael J. Wysocki
2008-02-03 23:33 ` Pavel Machek [this message]
2008-02-03 23:54 ` Rafael J. Wysocki
2008-02-03 23:59 ` Pavel Machek
2008-02-03 23:59 ` Rafael J. Wysocki
2008-02-04 0:05 ` Pavel Machek
2008-02-03 23:56 ` Pavel Machek
2008-02-03 23:57 ` Pavel Machek
2008-02-03 23:57 ` Pavel Machek
2008-02-03 23:57 ` Rafael J. Wysocki
2008-02-04 0:18 ` Pavel Machek
2008-02-03 23:58 ` Pavel Machek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080203233313.GF2799@elf.ucw.cz \
--to=pavel@ucw.cz \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.osdl.org \
--cc=rjw@sisk.pl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.