lkml.org 
[lkml]   [2008]   [Feb]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    SubjectRe: wakeup code translated to .c
    Date
    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 *)?
    2) header->level3_ident_pgt and header->level3_ident_pgt could be (char *) IMO


    --- 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;
    }


    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2008-02-04 00:25    [W:0.030 / U:148.716 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site