mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-29 15:28:50 +01:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
8
arch/x86/kernel/acpi/Makefile
Normal file
8
arch/x86/kernel/acpi/Makefile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
obj-$(CONFIG_ACPI) += boot.o
|
||||
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o
|
||||
obj-$(CONFIG_ACPI_APEI) += apei.o
|
||||
|
||||
ifneq ($(CONFIG_ACPI_PROCESSOR),)
|
||||
obj-y += cstate.o
|
||||
endif
|
||||
|
||||
62
arch/x86/kernel/acpi/apei.c
Normal file
62
arch/x86/kernel/acpi/apei.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Arch-specific APEI-related functions.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <acpi/apei.h>
|
||||
|
||||
#include <asm/mce.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data)
|
||||
{
|
||||
#ifdef CONFIG_X86_MCE
|
||||
int i;
|
||||
struct acpi_hest_ia_corrected *cmc;
|
||||
struct acpi_hest_ia_error_bank *mc_bank;
|
||||
|
||||
if (hest_hdr->type != ACPI_HEST_TYPE_IA32_CORRECTED_CHECK)
|
||||
return 0;
|
||||
|
||||
cmc = (struct acpi_hest_ia_corrected *)hest_hdr;
|
||||
if (!cmc->enabled)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We expect HEST to provide a list of MC banks that report errors
|
||||
* in firmware first mode. Otherwise, return non-zero value to
|
||||
* indicate that we are done parsing HEST.
|
||||
*/
|
||||
if (!(cmc->flags & ACPI_HEST_FIRMWARE_FIRST) ||
|
||||
!cmc->num_hardware_banks)
|
||||
return 1;
|
||||
|
||||
pr_info("HEST: Enabling Firmware First mode for corrected errors.\n");
|
||||
|
||||
mc_bank = (struct acpi_hest_ia_error_bank *)(cmc + 1);
|
||||
for (i = 0; i < cmc->num_hardware_banks; i++, mc_bank++)
|
||||
mce_disable_bank(mc_bank->bank_number);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
|
||||
{
|
||||
#ifdef CONFIG_X86_MCE
|
||||
apei_mce_report_mem_error(sev, mem_err);
|
||||
#endif
|
||||
}
|
||||
|
||||
void arch_apei_flush_tlb_one(unsigned long addr)
|
||||
{
|
||||
__flush_tlb_one(addr);
|
||||
}
|
||||
1642
arch/x86/kernel/acpi/boot.c
Normal file
1642
arch/x86/kernel/acpi/boot.c
Normal file
File diff suppressed because it is too large
Load diff
183
arch/x86/kernel/acpi/cstate.c
Normal file
183
arch/x86/kernel/acpi/cstate.c
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* Copyright (C) 2005 Intel Corporation
|
||||
* Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
|
||||
* - Added _PDC for SMP C-states on Intel CPUs
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <acpi/processor.h>
|
||||
#include <asm/acpi.h>
|
||||
#include <asm/mwait.h>
|
||||
#include <asm/special_insns.h>
|
||||
|
||||
/*
|
||||
* Initialize bm_flags based on the CPU cache properties
|
||||
* On SMP it depends on cache configuration
|
||||
* - When cache is not shared among all CPUs, we flush cache
|
||||
* before entering C3.
|
||||
* - When cache is shared among all CPUs, we use bm_check
|
||||
* mechanism as in UP case
|
||||
*
|
||||
* This routine is called only after all the CPUs are online
|
||||
*/
|
||||
void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
|
||||
unsigned int cpu)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
|
||||
flags->bm_check = 0;
|
||||
if (num_online_cpus() == 1)
|
||||
flags->bm_check = 1;
|
||||
else if (c->x86_vendor == X86_VENDOR_INTEL) {
|
||||
/*
|
||||
* Today all MP CPUs that support C3 share cache.
|
||||
* And caches should not be flushed by software while
|
||||
* entering C3 type state.
|
||||
*/
|
||||
flags->bm_check = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* On all recent Intel platforms, ARB_DISABLE is a nop.
|
||||
* So, set bm_control to zero to indicate that ARB_DISABLE
|
||||
* is not required while entering C3 type state on
|
||||
* P4, Core and beyond CPUs
|
||||
*/
|
||||
if (c->x86_vendor == X86_VENDOR_INTEL &&
|
||||
(c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 0x0f)))
|
||||
flags->bm_control = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_processor_power_init_bm_check);
|
||||
|
||||
/* The code below handles cstate entry with monitor-mwait pair on Intel*/
|
||||
|
||||
struct cstate_entry {
|
||||
struct {
|
||||
unsigned int eax;
|
||||
unsigned int ecx;
|
||||
} states[ACPI_PROCESSOR_MAX_POWER];
|
||||
};
|
||||
static struct cstate_entry __percpu *cpu_cstate_entry; /* per CPU ptr */
|
||||
|
||||
static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
|
||||
|
||||
#define NATIVE_CSTATE_BEYOND_HALT (2)
|
||||
|
||||
static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
|
||||
{
|
||||
struct acpi_processor_cx *cx = _cx;
|
||||
long retval;
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
unsigned int edx_part;
|
||||
unsigned int cstate_type; /* C-state type and not ACPI C-state type */
|
||||
unsigned int num_cstate_subtype;
|
||||
|
||||
cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
/* Check whether this particular cx_type (in CST) is supported or not */
|
||||
cstate_type = ((cx->address >> MWAIT_SUBSTATE_SIZE) &
|
||||
MWAIT_CSTATE_MASK) + 1;
|
||||
edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE);
|
||||
num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK;
|
||||
|
||||
retval = 0;
|
||||
/* If the HW does not support any sub-states in this C-state */
|
||||
if (num_cstate_subtype == 0) {
|
||||
pr_warn(FW_BUG "ACPI MWAIT C-state 0x%x not supported by HW (0x%x)\n", cx->address, edx_part);
|
||||
retval = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* mwait ecx extensions INTERRUPT_BREAK should be supported for C2/C3 */
|
||||
if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
|
||||
!(ecx & CPUID5_ECX_INTERRUPT_BREAK)) {
|
||||
retval = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!mwait_supported[cstate_type]) {
|
||||
mwait_supported[cstate_type] = 1;
|
||||
printk(KERN_DEBUG
|
||||
"Monitor-Mwait will be used to enter C-%d "
|
||||
"state\n", cx->type);
|
||||
}
|
||||
snprintf(cx->desc,
|
||||
ACPI_CX_DESC_LEN, "ACPI FFH INTEL MWAIT 0x%x",
|
||||
cx->address);
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int acpi_processor_ffh_cstate_probe(unsigned int cpu,
|
||||
struct acpi_processor_cx *cx, struct acpi_power_register *reg)
|
||||
{
|
||||
struct cstate_entry *percpu_entry;
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
long retval;
|
||||
|
||||
if (!cpu_cstate_entry || c->cpuid_level < CPUID_MWAIT_LEAF)
|
||||
return -1;
|
||||
|
||||
if (reg->bit_offset != NATIVE_CSTATE_BEYOND_HALT)
|
||||
return -1;
|
||||
|
||||
percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu);
|
||||
percpu_entry->states[cx->index].eax = 0;
|
||||
percpu_entry->states[cx->index].ecx = 0;
|
||||
|
||||
/* Make sure we are running on right CPU */
|
||||
|
||||
retval = work_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx);
|
||||
if (retval == 0) {
|
||||
/* Use the hint in CST */
|
||||
percpu_entry->states[cx->index].eax = cx->address;
|
||||
percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK;
|
||||
}
|
||||
|
||||
/*
|
||||
* For _CST FFH on Intel, if GAS.access_size bit 1 is cleared,
|
||||
* then we should skip checking BM_STS for this C-state.
|
||||
* ref: "Intel Processor Vendor-Specific ACPI Interface Specification"
|
||||
*/
|
||||
if ((c->x86_vendor == X86_VENDOR_INTEL) && !(reg->access_size & 0x2))
|
||||
cx->bm_sts_skip = 1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
|
||||
|
||||
void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
struct cstate_entry *percpu_entry;
|
||||
|
||||
percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu);
|
||||
mwait_idle_with_hints(percpu_entry->states[cx->index].eax,
|
||||
percpu_entry->states[cx->index].ecx);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_enter);
|
||||
|
||||
static int __init ffh_cstate_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
if (c->x86_vendor != X86_VENDOR_INTEL)
|
||||
return -1;
|
||||
|
||||
cpu_cstate_entry = alloc_percpu(struct cstate_entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit ffh_cstate_exit(void)
|
||||
{
|
||||
free_percpu(cpu_cstate_entry);
|
||||
cpu_cstate_entry = NULL;
|
||||
}
|
||||
|
||||
arch_initcall(ffh_cstate_init);
|
||||
__exitcall(ffh_cstate_exit);
|
||||
140
arch/x86/kernel/acpi/sleep.c
Normal file
140
arch/x86/kernel/acpi/sleep.c
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* sleep.c - x86-specific ACPI sleep support.
|
||||
*
|
||||
* Copyright (C) 2001-2003 Patrick Mochel
|
||||
* Copyright (C) 2001-2003 Pavel Machek <pavel@ucw.cz>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/desc.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/realmode.h>
|
||||
|
||||
#include "../../realmode/rm/wakeup.h"
|
||||
#include "sleep.h"
|
||||
|
||||
unsigned long acpi_realmode_flags;
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(CONFIG_64BIT)
|
||||
static char temp_stack[4096];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* x86_acpi_enter_sleep_state - enter sleep state
|
||||
* @state: Sleep state to enter.
|
||||
*
|
||||
* Wrapper around acpi_enter_sleep_state() to be called by assmebly.
|
||||
*/
|
||||
acpi_status asmlinkage __visible x86_acpi_enter_sleep_state(u8 state)
|
||||
{
|
||||
return acpi_enter_sleep_state(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* x86_acpi_suspend_lowlevel - save kernel state
|
||||
*
|
||||
* Create an identity mapped page table and copy the wakeup routine to
|
||||
* low memory.
|
||||
*/
|
||||
int x86_acpi_suspend_lowlevel(void)
|
||||
{
|
||||
struct wakeup_header *header =
|
||||
(struct wakeup_header *) __va(real_mode_header->wakeup_header);
|
||||
|
||||
if (header->signature != WAKEUP_HEADER_SIGNATURE) {
|
||||
printk(KERN_ERR "wakeup header does not match\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
header->video_mode = saved_video_mode;
|
||||
|
||||
header->pmode_behavior = 0;
|
||||
|
||||
#ifndef CONFIG_64BIT
|
||||
native_store_gdt((struct desc_ptr *)&header->pmode_gdt);
|
||||
|
||||
/*
|
||||
* We have to check that we can write back the value, and not
|
||||
* just read it. At least on 90 nm Pentium M (Family 6, Model
|
||||
* 13), reading an invalid MSR is not guaranteed to trap, see
|
||||
* Erratum X4 in "Intel Pentium M Processor on 90 nm Process
|
||||
* with 2-MB L2 Cache and Intel® Processor A100 and A110 on 90
|
||||
* nm process with 512-KB L2 Cache Specification Update".
|
||||
*/
|
||||
if (!rdmsr_safe(MSR_EFER,
|
||||
&header->pmode_efer_low,
|
||||
&header->pmode_efer_high) &&
|
||||
!wrmsr_safe(MSR_EFER,
|
||||
header->pmode_efer_low,
|
||||
header->pmode_efer_high))
|
||||
header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_EFER);
|
||||
#endif /* !CONFIG_64BIT */
|
||||
|
||||
header->pmode_cr0 = read_cr0();
|
||||
if (__this_cpu_read(cpu_info.cpuid_level) >= 0) {
|
||||
header->pmode_cr4 = read_cr4();
|
||||
header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_CR4);
|
||||
}
|
||||
if (!rdmsr_safe(MSR_IA32_MISC_ENABLE,
|
||||
&header->pmode_misc_en_low,
|
||||
&header->pmode_misc_en_high) &&
|
||||
!wrmsr_safe(MSR_IA32_MISC_ENABLE,
|
||||
header->pmode_misc_en_low,
|
||||
header->pmode_misc_en_high))
|
||||
header->pmode_behavior |=
|
||||
(1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE);
|
||||
header->realmode_flags = acpi_realmode_flags;
|
||||
header->real_magic = 0x12345678;
|
||||
|
||||
#ifndef CONFIG_64BIT
|
||||
header->pmode_entry = (u32)&wakeup_pmode_return;
|
||||
header->pmode_cr3 = (u32)__pa_symbol(initial_page_table);
|
||||
saved_magic = 0x12345678;
|
||||
#else /* CONFIG_64BIT */
|
||||
#ifdef CONFIG_SMP
|
||||
stack_start = (unsigned long)temp_stack + sizeof(temp_stack);
|
||||
early_gdt_descr.address =
|
||||
(unsigned long)get_cpu_gdt_table(smp_processor_id());
|
||||
initial_gs = per_cpu_offset(smp_processor_id());
|
||||
#endif
|
||||
initial_code = (unsigned long)wakeup_long64;
|
||||
saved_magic = 0x123456789abcdef0L;
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
do_suspend_lowlevel();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init acpi_sleep_setup(char *str)
|
||||
{
|
||||
while ((str != NULL) && (*str != '\0')) {
|
||||
if (strncmp(str, "s3_bios", 7) == 0)
|
||||
acpi_realmode_flags |= 1;
|
||||
if (strncmp(str, "s3_mode", 7) == 0)
|
||||
acpi_realmode_flags |= 2;
|
||||
if (strncmp(str, "s3_beep", 7) == 0)
|
||||
acpi_realmode_flags |= 4;
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
if (strncmp(str, "s4_nohwsig", 10) == 0)
|
||||
acpi_no_s4_hw_signature();
|
||||
#endif
|
||||
if (strncmp(str, "nonvs", 5) == 0)
|
||||
acpi_nvs_nosave();
|
||||
if (strncmp(str, "nonvs_s3", 8) == 0)
|
||||
acpi_nvs_nosave_s3();
|
||||
if (strncmp(str, "old_ordering", 12) == 0)
|
||||
acpi_old_suspend_ordering();
|
||||
str = strchr(str, ',');
|
||||
if (str != NULL)
|
||||
str += strspn(str, ", \t");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("acpi_sleep=", acpi_sleep_setup);
|
||||
21
arch/x86/kernel/acpi/sleep.h
Normal file
21
arch/x86/kernel/acpi/sleep.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Variables and functions used by the code in sleep.c
|
||||
*/
|
||||
|
||||
#include <asm/realmode.h>
|
||||
|
||||
extern unsigned long saved_video_mode;
|
||||
extern long saved_magic;
|
||||
|
||||
extern int wakeup_pmode_return;
|
||||
|
||||
extern u8 wake_sleep_flags;
|
||||
|
||||
extern unsigned long acpi_copy_wakeup_routine(unsigned long);
|
||||
extern void wakeup_long64(void);
|
||||
|
||||
extern void do_suspend_lowlevel(void);
|
||||
|
||||
extern int x86_acpi_suspend_lowlevel(void);
|
||||
|
||||
acpi_status asmlinkage x86_acpi_enter_sleep_state(u8 state);
|
||||
97
arch/x86/kernel/acpi/wakeup_32.S
Normal file
97
arch/x86/kernel/acpi/wakeup_32.S
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
.text
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/page_types.h>
|
||||
|
||||
# Copyright 2003, 2008 Pavel Machek <pavel@suse.cz>, distribute under GPLv2
|
||||
|
||||
.code32
|
||||
ALIGN
|
||||
|
||||
ENTRY(wakeup_pmode_return)
|
||||
wakeup_pmode_return:
|
||||
movw $__KERNEL_DS, %ax
|
||||
movw %ax, %ss
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
# reload the gdt, as we need the full 32 bit address
|
||||
lidt saved_idt
|
||||
lldt saved_ldt
|
||||
ljmp $(__KERNEL_CS), $1f
|
||||
1:
|
||||
movl %cr3, %eax
|
||||
movl %eax, %cr3
|
||||
wbinvd
|
||||
|
||||
# and restore the stack ... but you need gdt for this to work
|
||||
movl saved_context_esp, %esp
|
||||
|
||||
movl %cs:saved_magic, %eax
|
||||
cmpl $0x12345678, %eax
|
||||
jne bogus_magic
|
||||
|
||||
# jump to place where we left off
|
||||
movl saved_eip, %eax
|
||||
jmp *%eax
|
||||
|
||||
bogus_magic:
|
||||
jmp bogus_magic
|
||||
|
||||
|
||||
|
||||
save_registers:
|
||||
sidt saved_idt
|
||||
sldt saved_ldt
|
||||
str saved_tss
|
||||
|
||||
leal 4(%esp), %eax
|
||||
movl %eax, saved_context_esp
|
||||
movl %ebx, saved_context_ebx
|
||||
movl %ebp, saved_context_ebp
|
||||
movl %esi, saved_context_esi
|
||||
movl %edi, saved_context_edi
|
||||
pushfl
|
||||
popl saved_context_eflags
|
||||
|
||||
movl $ret_point, saved_eip
|
||||
ret
|
||||
|
||||
|
||||
restore_registers:
|
||||
movl saved_context_ebp, %ebp
|
||||
movl saved_context_ebx, %ebx
|
||||
movl saved_context_esi, %esi
|
||||
movl saved_context_edi, %edi
|
||||
pushl saved_context_eflags
|
||||
popfl
|
||||
ret
|
||||
|
||||
ENTRY(do_suspend_lowlevel)
|
||||
call save_processor_state
|
||||
call save_registers
|
||||
pushl $3
|
||||
call x86_acpi_enter_sleep_state
|
||||
addl $4, %esp
|
||||
|
||||
# In case of S3 failure, we'll emerge here. Jump
|
||||
# to ret_point to recover
|
||||
jmp ret_point
|
||||
.p2align 4,,7
|
||||
ret_point:
|
||||
call restore_registers
|
||||
call restore_processor_state
|
||||
ret
|
||||
|
||||
.data
|
||||
ALIGN
|
||||
ENTRY(saved_magic) .long 0
|
||||
ENTRY(saved_eip) .long 0
|
||||
|
||||
# saved registers
|
||||
saved_idt: .long 0,0
|
||||
saved_ldt: .long 0
|
||||
saved_tss: .long 0
|
||||
|
||||
124
arch/x86/kernel/acpi/wakeup_64.S
Normal file
124
arch/x86/kernel/acpi/wakeup_64.S
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
.text
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/pgtable_types.h>
|
||||
#include <asm/page_types.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
|
||||
# Copyright 2003 Pavel Machek <pavel@suse.cz>, distribute under GPLv2
|
||||
|
||||
.code64
|
||||
/*
|
||||
* Hooray, we are in Long 64-bit mode (but still running in low memory)
|
||||
*/
|
||||
ENTRY(wakeup_long64)
|
||||
movq saved_magic, %rax
|
||||
movq $0x123456789abcdef0, %rdx
|
||||
cmpq %rdx, %rax
|
||||
jne bogus_64_magic
|
||||
|
||||
movw $__KERNEL_DS, %ax
|
||||
movw %ax, %ss
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
movq saved_rsp, %rsp
|
||||
|
||||
movq saved_rbx, %rbx
|
||||
movq saved_rdi, %rdi
|
||||
movq saved_rsi, %rsi
|
||||
movq saved_rbp, %rbp
|
||||
|
||||
movq saved_rip, %rax
|
||||
jmp *%rax
|
||||
ENDPROC(wakeup_long64)
|
||||
|
||||
bogus_64_magic:
|
||||
jmp bogus_64_magic
|
||||
|
||||
ENTRY(do_suspend_lowlevel)
|
||||
subq $8, %rsp
|
||||
xorl %eax, %eax
|
||||
call save_processor_state
|
||||
|
||||
movq $saved_context, %rax
|
||||
movq %rsp, pt_regs_sp(%rax)
|
||||
movq %rbp, pt_regs_bp(%rax)
|
||||
movq %rsi, pt_regs_si(%rax)
|
||||
movq %rdi, pt_regs_di(%rax)
|
||||
movq %rbx, pt_regs_bx(%rax)
|
||||
movq %rcx, pt_regs_cx(%rax)
|
||||
movq %rdx, pt_regs_dx(%rax)
|
||||
movq %r8, pt_regs_r8(%rax)
|
||||
movq %r9, pt_regs_r9(%rax)
|
||||
movq %r10, pt_regs_r10(%rax)
|
||||
movq %r11, pt_regs_r11(%rax)
|
||||
movq %r12, pt_regs_r12(%rax)
|
||||
movq %r13, pt_regs_r13(%rax)
|
||||
movq %r14, pt_regs_r14(%rax)
|
||||
movq %r15, pt_regs_r15(%rax)
|
||||
pushfq
|
||||
popq pt_regs_flags(%rax)
|
||||
|
||||
movq $resume_point, saved_rip(%rip)
|
||||
|
||||
movq %rsp, saved_rsp
|
||||
movq %rbp, saved_rbp
|
||||
movq %rbx, saved_rbx
|
||||
movq %rdi, saved_rdi
|
||||
movq %rsi, saved_rsi
|
||||
|
||||
addq $8, %rsp
|
||||
movl $3, %edi
|
||||
xorl %eax, %eax
|
||||
call x86_acpi_enter_sleep_state
|
||||
/* in case something went wrong, restore the machine status and go on */
|
||||
jmp resume_point
|
||||
|
||||
.align 4
|
||||
resume_point:
|
||||
/* We don't restore %rax, it must be 0 anyway */
|
||||
movq $saved_context, %rax
|
||||
movq saved_context_cr4(%rax), %rbx
|
||||
movq %rbx, %cr4
|
||||
movq saved_context_cr3(%rax), %rbx
|
||||
movq %rbx, %cr3
|
||||
movq saved_context_cr2(%rax), %rbx
|
||||
movq %rbx, %cr2
|
||||
movq saved_context_cr0(%rax), %rbx
|
||||
movq %rbx, %cr0
|
||||
pushq pt_regs_flags(%rax)
|
||||
popfq
|
||||
movq pt_regs_sp(%rax), %rsp
|
||||
movq pt_regs_bp(%rax), %rbp
|
||||
movq pt_regs_si(%rax), %rsi
|
||||
movq pt_regs_di(%rax), %rdi
|
||||
movq pt_regs_bx(%rax), %rbx
|
||||
movq pt_regs_cx(%rax), %rcx
|
||||
movq pt_regs_dx(%rax), %rdx
|
||||
movq pt_regs_r8(%rax), %r8
|
||||
movq pt_regs_r9(%rax), %r9
|
||||
movq pt_regs_r10(%rax), %r10
|
||||
movq pt_regs_r11(%rax), %r11
|
||||
movq pt_regs_r12(%rax), %r12
|
||||
movq pt_regs_r13(%rax), %r13
|
||||
movq pt_regs_r14(%rax), %r14
|
||||
movq pt_regs_r15(%rax), %r15
|
||||
|
||||
xorl %eax, %eax
|
||||
addq $8, %rsp
|
||||
jmp restore_processor_state
|
||||
ENDPROC(do_suspend_lowlevel)
|
||||
|
||||
.data
|
||||
ENTRY(saved_rbp) .quad 0
|
||||
ENTRY(saved_rsi) .quad 0
|
||||
ENTRY(saved_rdi) .quad 0
|
||||
ENTRY(saved_rbx) .quad 0
|
||||
|
||||
ENTRY(saved_rip) .quad 0
|
||||
ENTRY(saved_rsp) .quad 0
|
||||
|
||||
ENTRY(saved_magic) .quad 0
|
||||
Loading…
Add table
Add a link
Reference in a new issue