On Mon 2008-02-04 00:59:38, Rafael J. Wysocki wrote:
> On Monday, 4 of February 2008, Pavel Machek wrote:
> > Hi!
> > 
> > > BTW, I don't like the way in which the 'struct wakeup_header' fields are
> > > reproduced in rm/wakeup.S very much, because it makes the code fragile.
> > > It might be better to define the offsets in asm-offsets*.c and refer to 
> > > them
> > > relative to wakeup_header (if possible).
> > 
> > If you can do that.. yes, that would be nice. I triple-checked it, but
> > indeed is fragile.
> 
> Do you want me to remove the unused fields from 'struct wakeup_header' too?

I think I did that already. My wakeup.S/wakeup.h is attached. If you
can find more unused fields, kill them for sure.

(I'm not sure about fields needed on 32-bit only. I'm leaving them in
because it does not really matter).


-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
/*
 * Definitions for the wakeup data structure at the head of the
 * wakeup code.
 */

#ifndef ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H
#define ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H

#include <linux/types.h>

/* This must match data at wakeup.S */
struct wakeup_header {
	u16 entry;		/* unused */
	u16 total;		/* unused */
	u16 video_mode;		/* Video mode number */
	u16 _jmp1;
	u32 pmode_entry;	/* Protected mode resume point */
	u16 _jmp2;
	u32 pmode_cr0;		/* Protected mode cr0 */
	u32 pmode_cr3;		/* Protected mode cr3 */
	u32 pmode_cr4;		/* Protected mode cr4 */
	u32 pmode_efer_low;	/* Protected mode EFER */
	u32 pmode_efer_high;
	u64 pmode_gdt;
	u32 realmode_flags;
	u32 real_magic;
	u16 trampoline_segment;
	u32 signature;		/* To check we have correct structure */
} __attribute__((__packed__));

#endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */
/*
 * ACPI wakeup real mode startup stub
 */
#include <asm/segment.h>
#include <asm/msr-index.h>
#include <asm/page_64.h>
#include <asm/pgtable_64.h>

        .code16
        .section ".header", "a"

/* This should match the structure in wakeup.h */
                .globl  wakeup_header
wakeup_header:
entry:          .short  _start  /* unused */
total:          .short  _end    /* unused */
video_mode:     .short  0       /* Video mode number */
pmode_return:   .byte   0x66, 0xea      /* ljmpl */
                .long   0               /* offset goes here */
                .short  __KERNEL_CS
pmode_cr0:      .long   0               /* Saved %cr0 */
pmode_cr3:      .long   0               /* Saved %cr3 */
pmode_cr4:      .long   0               /* Saved %cr4 */
pmode_efer:     .quad   0               /* Saved EFER */
pmode_gdt:      .quad   0
realmode_flags: .long   0
real_magic:     .long   0
trampoline_segment:     .word 0
signature:      .long   0x51ee1111

        .text
        .globl  _start
        .code16
wakeup_code:
_start:
        cli
        cld

        /* Set up segments */
        movw    %cs,%ax
        movw    %ax,%ds
        movw    %ax,%es
        movw    %ax,%ss

        movl    $wakeup_stack_end, %esp

        /* Clear the EFLAGS */
        pushl   $0
        popfl

        /* Check header signature... */
        movl    signature, %eax
        cmpl    $0x51ee1111, %eax
        jne     bogus_real_magic

        /* Check we really have everything... */
        movl    end_signature, %eax
        cmpl    $0x65a22c82, %eax
        jne     bogus_real_magic

        /* Zero the bss */
        xorl    %eax, %eax
        movw    $__bss_start, %di
        movw    $__bss_end+3, %cx
        subw    %di, %cx
        shrw    $2, %cx
        rep; stosl

        /* Call the C code */
        calll   main

        /* Do any other stuff... */
        
#ifndef CONFIG_64BIT
        /* This could also be done in C code... */
        movl    pmode_cr3, %eax
        movl    %eax, %cr3

        movl    pmode_cr4, %ecx
        jecxz   1f
        movl    %ecx, %cr4
1:
        movl    pmode_efer, %eax
        movl    pmode_efer+4, %edx
        movl    %eax, %ecx
        orl     %edx, %ecx
        jz      1f
        movl    $0xc0000080, %ecx
        wrmsr
1:

        lgdtl   pmode_gdt

        /* This really couldn't... */
        movl    pmode_cr0, %eax
        movl    %eax, %cr0
        jmp     pmode_return
#else
        pushw   $0
        pushw   trampoline_segment
        pushw   $0
        lret    
#endif

bogus_real_magic:
1:
        hlt
        jmp     1b
        
        .data
        .balign 4
        .globl  HEAP, heap_end
HEAP:
        .long   wakeup_heap
heap_end:
        .long   wakeup_stack

        .bss
wakeup_heap:
        .space  2048
wakeup_stack:
        .space  2048
wakeup_stack_end:

Reply via email to