Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1ee4335 authored by H. Peter Anvin's avatar H. Peter Anvin
Browse files

x86, trampoline: Use the unified trampoline setup for ACPI wakeup



Use the unified trampoline allocation setup to allocate and install
the ACPI wakeup code in low memory.

Signed-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
LKML-Reference: <4D5DFBE4.7090104@intel.com>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Matthieu Castet <castet.matthieu@free.fr>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
parent 4822b7fc
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <asm/processor.h>
#include <asm/mmu.h>
#include <asm/mpspec.h>
#include <asm/trampoline.h>

#define COMPILER_DEPENDENT_INT64   long long
#define COMPILER_DEPENDENT_UINT64  unsigned long long
@@ -116,7 +117,8 @@ static inline void acpi_disable_pci(void)
extern int acpi_save_state_mem(void);
extern void acpi_restore_state_mem(void);

extern unsigned long acpi_wakeup_address;
extern const unsigned char acpi_wakeup_code[];
#define acpi_wakeup_address (__pa(TRAMPOLINE_SYM(acpi_wakeup_code)))

/* early initialization routine */
extern void acpi_reserve_wakeup_memory(void);
+22 −11
Original line number Diff line number Diff line
@@ -3,25 +3,36 @@

#ifndef __ASSEMBLY__

#ifdef CONFIG_X86_TRAMPOLINE
#include <linux/types.h>
#include <asm/io.h>

/*
 * Trampoline 80x86 program as an array.
 * Trampoline 80x86 program as an array.  These are in the init rodata
 * segment, but that's okay, because we only care about the relative
 * addresses of the symbols.
 */
extern const unsigned char trampoline_data [];
extern const unsigned char trampoline_end  [];
extern unsigned char *trampoline_base;
extern const unsigned char x86_trampoline_start [];
extern const unsigned char x86_trampoline_end   [];
extern unsigned char *x86_trampoline_base;

extern unsigned long init_rsp;
extern unsigned long initial_code;
extern unsigned long initial_gs;

#define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
extern void __init setup_trampolines(void);

extern const unsigned char trampoline_data[];
extern const unsigned char trampoline_status[];

#define TRAMPOLINE_SYM(x)						\
	((void *)(x86_trampoline_base +					\
		  ((const unsigned char *)(x) - x86_trampoline_start)))

extern unsigned long setup_trampoline(void);
extern void __init reserve_trampoline_memory(void);
#else
static inline void reserve_trampoline_memory(void) {}
#endif /* CONFIG_X86_TRAMPOLINE */
/* Address of the SMP trampoline */
static inline unsigned long trampoline_address(void)
{
	return virt_to_phys(TRAMPOLINE_SYM(trampoline_data));
}

#endif /* __ASSEMBLY__ */

+14 −7
Original line number Diff line number Diff line
@@ -6,11 +6,17 @@
#include <asm/page_types.h>
#include <asm/pgtable_types.h>
#include <asm/processor-flags.h>
#include "wakeup.h"

	.code16
	.section ".header", "a"
	.section ".jump", "ax"
	.globl	_start
_start:
	cli
	jmp	wakeup_code

/* This should match the structure in wakeup.h */
		.section ".header", "a"
		.globl	wakeup_header
wakeup_header:
video_mode:	.short	0	/* Video mode number */
@@ -30,14 +36,11 @@ wakeup_jmp: .byte 0xea /* ljmpw */
wakeup_jmp_off:	.word	3f
wakeup_jmp_seg:	.word	0
wakeup_gdt:	.quad	0, 0, 0
signature:	.long	0x51ee1111
signature:	.long	WAKEUP_HEADER_SIGNATURE

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

	/* Apparently some dimwit BIOS programmers don't know how to
@@ -77,12 +80,12 @@ _start:

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

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

	/* Call the C code */
@@ -147,3 +150,7 @@ wakeup_heap:
wakeup_stack:
	.space	2048
wakeup_stack_end:

	.section ".signature","a"
end_signature:
	.long	WAKEUP_END_SIGNATURE
+3 −2
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@ struct wakeup_header {
extern struct wakeup_header wakeup_header;
#endif

#define HEADER_OFFSET 0x3f00
#define WAKEUP_SIZE   0x4000
#define WAKEUP_HEADER_OFFSET	8
#define WAKEUP_HEADER_SIGNATURE 0x51ee1111
#define WAKEUP_END_SIGNATURE	0x65a22c82

#endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */
+13 −15
Original line number Diff line number Diff line
@@ -13,9 +13,19 @@ ENTRY(_start)
SECTIONS
{
	. = 0;
	.jump	: {
		*(.jump)
	} = 0x90909090

	. = WAKEUP_HEADER_OFFSET;
	.header : {
		*(.header)
	}

	. = ALIGN(16);
	.text : {
		 *(.text*)
	}
	} = 0x90909090

	. = ALIGN(16);
	.rodata : {
@@ -33,11 +43,6 @@ SECTIONS
		 *(.data*)
	}

	.signature : {
		end_signature = .;
		LONG(0x65a22c82)
	}

	. = ALIGN(16);
	.bss :	{
		__bss_start = .;
@@ -45,20 +50,13 @@ SECTIONS
		__bss_end = .;
	}

	. = HEADER_OFFSET;
	.header : {
		*(.header)
	.signature : {
		*(.signature)
	}

	. = ALIGN(16);
	_end = .;

	/DISCARD/ : {
		*(.note*)
	}

	/*
	 * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
	 */
	. = ASSERT(_end <= WAKEUP_SIZE, "Wakeup too big!");
}
Loading