Add and enable kexec hardboot support.
Consists of squashed commits from: https://github.com/mkasick/android_kernel_samsung_jfltespr.git commit 750bb80f2854d6af5273e55ea179a4c60b2d9efc Author: Mike Kasick <mike@kasick.org> Date: Sun Jun 2 23:11:24 2013 -0400 Clear download mode flag on kexec hardboot. commit 138ba851ee949af291eae914f410aea2d85ed9f5 Author: Mike Kasick <mike@kasick.org> Date: Sun May 12 22:39:26 2013 -0400 Support hard booting to a kexec kernel. See KEXEC_HARDBOOT config option help for details. commit 3ab41019a7af08395c233bebb605c2f1ea49c8e0 Author: Mike Kasick <mike@kasick.org> Date: Sat Jul 7 23:10:24 2012 -0400 Support copying of kernel tagged list (atags) in the decompressor. This is needed to hardboot kexec a kernel with a new tags list (including a new kernel command line), since the new atags would otherwise be lost with the limited kernel memory mapping. Without this patch, a hardboot-kexec'd kernel uses the atags provided by the bootloader. commit 446c3d7a6631877f7dc9142359cf0eae300e9a08 Author: Mike Kasick <mike@kasick.org> Date: Sat Jul 7 23:09:39 2012 -0400 Enable caching and buffering for all of physical RAM in the decompressor. Old method is to enable caching and buffering only for the 256 MB at the start of the decompressor image. This makes a hardboot-kexec'd kernel very slow to decompress since the decompressor is located far above the kernel destination. This patch reduces boot time from 35 to 8 seconds on epicmtd. commit d3646be88f5b1f9a8ae714c922ec50c681b7157f Author: Mike Kasick <mike@kasick.org> Date: Sat Jul 7 19:00:47 2012 -0400 Enable and fix kexec syscall support. Use mem_text_write_kernel_word when assigning reboot_code_buffer parameters to avoid protection faults (writes to read-only kernel memory) when CONFIG_STRICT_MEMORY_RWX is enabled. Change-Id: I0400ad00fcf02b8ad017f8aa371724a659b930b4
This commit is contained in:
parent
7134c840d8
commit
1173eb767f
|
@ -2224,6 +2224,36 @@ config ATAGS_PROC
|
|||
Should the atags used to boot the kernel be exported in an "atags"
|
||||
file in procfs. Useful with kexec.
|
||||
|
||||
config KEXEC_HARDBOOT
|
||||
bool "Support hard booting to a kexec kernel"
|
||||
depends on KEXEC
|
||||
help
|
||||
Allows hard booting (i.e., with a full hardware reboot) to a kernel
|
||||
previously loaded in memory by kexec. This works around the problem of
|
||||
soft-booted kernel hangs due to improper device shutdown and/or
|
||||
reinitialization. Support is comprised of two components:
|
||||
|
||||
First, a "hardboot" flag is added to the kexec syscall to force a hard
|
||||
reboot in relocate_new_kernel() (which requires machine-specific assembly
|
||||
code). This also requires the kexec userspace tool to load the kexec'd
|
||||
kernel in memory region left untouched by the bootloader (i.e., not
|
||||
explicitly cleared and not overwritten by the boot kernel). Just prior
|
||||
to reboot, the kexec kernel arguments are stashed in a machine-specific
|
||||
memory page that must also be preserved. Note that this hardboot page
|
||||
need not be reserved during regular kernel execution.
|
||||
|
||||
Second, the zImage decompresor of the boot (bootloader-loaded) kernel is
|
||||
modified to check the hardboot page for fresh kexec arguments, and if
|
||||
present, attempts to jump to the kexec'd kernel preserved in memory.
|
||||
|
||||
Note that hardboot support is only required in the boot kernel and any
|
||||
kernel capable of performing a hardboot kexec. It is _not_ required by a
|
||||
kexec'd kernel.
|
||||
|
||||
config KEXEC_HB_PAGE_ADDR
|
||||
hex "Kexec hardboot page address"
|
||||
depends on KEXEC_HARDBOOT
|
||||
|
||||
config CRASH_DUMP
|
||||
bool "Build kdump crash kernel (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
|
|
|
@ -139,6 +139,9 @@ endif
|
|||
ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
|
||||
LDFLAGS_vmlinux += --be8
|
||||
endif
|
||||
ifneq ($(PARAMS_PHYS),)
|
||||
LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS)
|
||||
endif
|
||||
# ?
|
||||
LDFLAGS_vmlinux += -p
|
||||
# Report unresolved symbol references
|
||||
|
|
|
@ -9,6 +9,11 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/memory.h>
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Debugging stuff
|
||||
|
@ -133,7 +138,31 @@ start:
|
|||
.word _edata @ zImage end address
|
||||
THUMB( .thumb )
|
||||
1: mov r7, r1 @ save architecture ID
|
||||
mov r8, r2 @ save atags pointer
|
||||
teq r0, #0 @ Check for kexec_boot_atags.
|
||||
movne r8, r0 @ Save kexec_boot_tags.
|
||||
moveq r8, r2 @ save atags pointer
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
/* Check hardboot page for a kexec kernel. */
|
||||
ldr r3, =KEXEC_HB_PAGE_ADDR
|
||||
ldr r0, [r3]
|
||||
ldr r1, =KEXEC_HB_PAGE_MAGIC
|
||||
teq r0, r1
|
||||
bne not_booting_other
|
||||
|
||||
/* Clear hardboot page magic to avoid boot loop. */
|
||||
mov r0, #0
|
||||
str r0, [r3]
|
||||
|
||||
/* Load boot arguments and jump to kexec kernel. */
|
||||
ldr r0, [r3, #12] @ kexec_boot_atags (r2: boot_atags)
|
||||
ldr r1, [r3, #8] @ kexec_mach_type
|
||||
ldr pc, [r3, #4] @ kexec_start_address
|
||||
|
||||
.ltorg
|
||||
|
||||
not_booting_other:
|
||||
#endif
|
||||
|
||||
#ifndef __ARM_ARCH_2__
|
||||
/*
|
||||
|
@ -456,6 +485,41 @@ not_relocated: mov r0, #0
|
|||
add r2, sp, #0x10000 @ 64k max
|
||||
mov r3, r7
|
||||
bl decompress_kernel
|
||||
|
||||
/* Copy the kernel tagged list (atags):
|
||||
*
|
||||
* The kernel requires atags to be located in a direct-mapped region,
|
||||
* usually below the kernel in the first 16 kB of RAM. If they're above
|
||||
* (the start of) the kernel, they need to be copied to a suitable
|
||||
* location, e.g., the machine-defined params_phys.
|
||||
*
|
||||
* Still need to make sure that the copied tags don't overwrite either the
|
||||
* kernel or decompressor code (or rather, the remainder of it since
|
||||
* everything up to here has already been executed).
|
||||
*
|
||||
* r4: zreladdr (kernel start)
|
||||
* r8: atags */
|
||||
|
||||
/* Don't need to copy atags if they're already below the kernel. */
|
||||
cmp r8, r4
|
||||
blo call_kernel
|
||||
|
||||
/* r1: min(zreladdr, pc) */
|
||||
mov r1, pc
|
||||
cmp r4, r1
|
||||
movlo r1, r4
|
||||
|
||||
/* Compute max space for atags, if max <= 0 don't copy. */
|
||||
ldr r0, =params_phys @ dest
|
||||
subs r2, r1, r0 @ max = min(zreladdr, pc) - dest
|
||||
bls call_kernel
|
||||
|
||||
/* Copy atags to params_phys. */
|
||||
mov r1, r8 @ src
|
||||
bl copy_atags
|
||||
mov r8, r0
|
||||
|
||||
call_kernel:
|
||||
bl cache_clean_flush
|
||||
bl cache_off
|
||||
mov r0, #0 @ must be zero
|
||||
|
@ -464,6 +528,8 @@ not_relocated: mov r0, #0
|
|||
ARM( mov pc, r4 ) @ call kernel
|
||||
THUMB( bx r4 ) @ entry point is always ARM
|
||||
|
||||
.ltorg
|
||||
|
||||
.align 2
|
||||
.type LC0, #object
|
||||
LC0: .word LC0 @ r1
|
||||
|
@ -581,9 +647,14 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size
|
|||
* bits for the RAM area only.
|
||||
*/
|
||||
mov r0, r3
|
||||
#if defined(PLAT_PHYS_OFFSET) && defined(END_MEM)
|
||||
ldr r9, =PLAT_PHYS_OFFSET @ start of RAM
|
||||
ldr r10, =END_MEM @ end of RAM
|
||||
#else
|
||||
mov r9, r0, lsr #18
|
||||
mov r9, r9, lsl #18 @ start of RAM
|
||||
add r10, r9, #0x10000000 @ a reasonable RAM size
|
||||
#endif
|
||||
mov r1, #0x12 @ XN|U + section mapping
|
||||
orr r1, r1, #3 << 10 @ AP=11
|
||||
add r2, r3, #16384
|
||||
|
|
|
@ -21,6 +21,8 @@ unsigned int __machine_arch_type;
|
|||
#include <linux/compiler.h> /* for inline */
|
||||
#include <linux/types.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/string.h>
|
||||
|
||||
static void putstr(const char *ptr);
|
||||
extern void error(char *x);
|
||||
|
@ -152,3 +154,25 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
|
|||
else
|
||||
putstr(" done, booting the kernel.\n");
|
||||
}
|
||||
|
||||
const struct tag *copy_atags(struct tag *dest, const struct tag *src,
|
||||
size_t max)
|
||||
{
|
||||
struct tag *tag;
|
||||
size_t size;
|
||||
|
||||
/* Find the last tag (ATAG_NONE). */
|
||||
for_each_tag(tag, (struct tag *)src)
|
||||
continue;
|
||||
|
||||
/* Include the last tag in copy. */
|
||||
size = (char *)tag - (char *)src + sizeof(struct tag_header);
|
||||
|
||||
/* If there's not enough room, just use original and hope it works. */
|
||||
if (size > max)
|
||||
return src;
|
||||
|
||||
memcpy(dest, src, size);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
|
|
@ -722,3 +722,12 @@ CONFIG_MSM_AVS_HW=y
|
|||
CONFIG_SCHED_MC=y
|
||||
CONFIG_RCU_FAST_NO_HZ=y
|
||||
CONFIG_ZCACHE=y
|
||||
|
||||
# Enable kexec hardboot support.
|
||||
CONFIG_HAVE_END_MEM=y
|
||||
CONFIG_END_MEM=0xffffffff
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_ATAGS_PROC=y
|
||||
CONFIG_KEXEC_HARDBOOT=y
|
||||
CONFIG_KEXEC_HB_PAGE_ADDR=0x8fdff000
|
||||
CONFIG_ANDROID_PERSISTENT_RAM=y
|
||||
|
|
|
@ -17,6 +17,11 @@
|
|||
#define KEXEC_ARM_ATAGS_OFFSET 0x1000
|
||||
#define KEXEC_ARM_ZIMAGE_OFFSET 0x8000
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#define KEXEC_HB_PAGE_ADDR UL(CONFIG_KEXEC_HB_PAGE_ADDR)
|
||||
#define KEXEC_HB_PAGE_MAGIC 0x4a5db007
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/**
|
||||
|
@ -53,6 +58,10 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
|
|||
/* Function pointer to optional machine-specific reinitialization */
|
||||
extern void (*kexec_reinit)(void);
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
extern void (*kexec_hardboot_hook)(void);
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* CONFIG_KEXEC */
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/system_misc.h>
|
||||
#include <asm/mmu_writeable.h>
|
||||
|
||||
extern const unsigned char relocate_new_kernel[];
|
||||
extern const unsigned int relocate_new_kernel_size;
|
||||
|
@ -23,6 +24,11 @@ extern unsigned long kexec_indirection_page;
|
|||
extern unsigned long kexec_mach_type;
|
||||
extern unsigned long kexec_boot_atags;
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
extern unsigned long kexec_hardboot;
|
||||
void (*kexec_hardboot_hook)(void);
|
||||
#endif
|
||||
|
||||
static atomic_t waiting_for_crash_ipi;
|
||||
|
||||
/*
|
||||
|
@ -119,10 +125,13 @@ void machine_kexec(struct kimage *image)
|
|||
reboot_code_buffer = page_address(image->control_code_page);
|
||||
|
||||
/* Prepare parameters for reboot_code_buffer*/
|
||||
kexec_start_address = image->start;
|
||||
kexec_indirection_page = page_list;
|
||||
kexec_mach_type = machine_arch_type;
|
||||
kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
|
||||
mem_text_write_kernel_word(&kexec_start_address, image->start);
|
||||
mem_text_write_kernel_word(&kexec_indirection_page, page_list);
|
||||
mem_text_write_kernel_word(&kexec_mach_type, machine_arch_type);
|
||||
mem_text_write_kernel_word(&kexec_boot_atags, image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET);
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
mem_text_write_kernel_word(&kexec_hardboot, image->hardboot);
|
||||
#endif
|
||||
|
||||
/* copy our kernel relocation code to the control code page */
|
||||
memcpy(reboot_code_buffer,
|
||||
|
@ -136,5 +145,11 @@ void machine_kexec(struct kimage *image)
|
|||
if (kexec_reinit)
|
||||
kexec_reinit();
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
if (image->hardboot && kexec_hardboot_hook)
|
||||
/* Run any final machine-specific shutdown code. */
|
||||
kexec_hardboot_hook();
|
||||
#endif
|
||||
|
||||
soft_restart(reboot_code_buffer_phys);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,13 @@
|
|||
|
||||
#include <asm/kexec.h>
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/memory.h>
|
||||
#if defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064)
|
||||
#include <mach/msm_iomap.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
.globl relocate_new_kernel
|
||||
relocate_new_kernel:
|
||||
|
||||
|
@ -52,6 +59,12 @@ relocate_new_kernel:
|
|||
b 0b
|
||||
|
||||
2:
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
ldr r0, kexec_hardboot
|
||||
teq r0, #0
|
||||
bne hardboot
|
||||
#endif
|
||||
|
||||
/* Jump to relocated kernel */
|
||||
mov lr,r1
|
||||
mov r0,#0
|
||||
|
@ -60,6 +73,40 @@ relocate_new_kernel:
|
|||
ARM( mov pc, lr )
|
||||
THUMB( bx lr )
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
hardboot:
|
||||
/* Stash boot arguments in hardboot page:
|
||||
* 0: KEXEC_HB_PAGE_MAGIC
|
||||
* 4: kexec_start_address
|
||||
* 8: kexec_mach_type
|
||||
* 12: kexec_boot_atags */
|
||||
ldr r0, =KEXEC_HB_PAGE_ADDR
|
||||
str r1, [r0, #4]
|
||||
ldr r1, kexec_mach_type
|
||||
str r1, [r0, #8]
|
||||
ldr r1, kexec_boot_atags
|
||||
str r1, [r0, #12]
|
||||
ldr r1, =KEXEC_HB_PAGE_MAGIC
|
||||
str r1, [r0]
|
||||
|
||||
#if defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064)
|
||||
#if defined(CONFIG_ARCH_APQ8064)
|
||||
#define MSM_TLMM_PHYS APQ8064_TLMM_PHYS
|
||||
#elif defined(CONFIG_ARCH_MSM8960)
|
||||
#define MSM_TLMM_PHYS MSM8960_TLMM_PHYS
|
||||
#endif
|
||||
/* Hard reset via PMIC, decompressor jumps to kernel. */
|
||||
ldr r0, =MSM_TLMM_PHYS
|
||||
mov r1, #0
|
||||
str r1, [r0, #0x820] @ PSHOLD_CTL_SU
|
||||
loop: b loop
|
||||
#else
|
||||
#error "No reboot method defined for hardboot."
|
||||
#endif
|
||||
|
||||
.ltorg
|
||||
#endif
|
||||
|
||||
.align
|
||||
|
||||
.globl kexec_start_address
|
||||
|
@ -79,6 +126,12 @@ kexec_mach_type:
|
|||
kexec_boot_atags:
|
||||
.long 0x0
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.globl kexec_hardboot
|
||||
kexec_hardboot:
|
||||
.long 0x0
|
||||
#endif
|
||||
|
||||
relocate_new_kernel_end:
|
||||
|
||||
.globl relocate_new_kernel_size
|
||||
|
|
|
@ -1089,6 +1089,13 @@ config PHYS_OFFSET
|
|||
default "0x40200000" if ARCH_MSM8X60
|
||||
default "0x10000000"
|
||||
|
||||
config HAVE_END_MEM
|
||||
bool "Specify highest physical RAM address at compile time"
|
||||
|
||||
config END_MEM
|
||||
hex "Highest physical address where system RAM resides"
|
||||
depends on HAVE_END_MEM
|
||||
|
||||
config KERNEL_MSM_CONTIG_MEM_REGION
|
||||
bool "Enable in-kernel contiguous memory region"
|
||||
default y if ARCH_MSM8X60
|
||||
|
|
|
@ -38,12 +38,14 @@ endif
|
|||
|
||||
# MSM8960
|
||||
zreladdr-$(CONFIG_ARCH_MSM8960) := 0x80208000
|
||||
params_phys-$(CONFIG_ARCH_MSM8960) := 0x80200100
|
||||
|
||||
# MSM8930
|
||||
zreladdr-$(CONFIG_ARCH_MSM8930) := 0x80208000
|
||||
|
||||
# APQ8064
|
||||
zreladdr-$(CONFIG_ARCH_APQ8064) := 0x80208000
|
||||
params_phys-$(CONFIG_ARCH_APQ8064) := 0x80200100
|
||||
|
||||
# MSM8974
|
||||
zreladdr-$(CONFIG_ARCH_MSM8974) := 0x00008000
|
||||
|
|
|
@ -150,6 +150,10 @@
|
|||
#include <mach/fusion3-thermistor.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSORS_SSP)
|
||||
enum {
|
||||
SNS_PWR_OFF,
|
||||
|
@ -1015,7 +1019,15 @@ static struct platform_device ram_console_device = {
|
|||
static struct persistent_ram_descriptor per_ram_descs[] __initdata = {
|
||||
{
|
||||
.name = "ram_console",
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.size = KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR,
|
||||
},
|
||||
{
|
||||
.name = "kexec_hb_page",
|
||||
.size = SZ_1M - (KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR),
|
||||
#else
|
||||
.size = SZ_1M,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -144,6 +144,10 @@
|
|||
#include <mach/fusion3-thermistor.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSORS_SSP)
|
||||
enum {
|
||||
SNS_PWR_OFF,
|
||||
|
@ -962,7 +966,15 @@ static struct platform_device ram_console_device = {
|
|||
static struct persistent_ram_descriptor per_ram_descs[] __initdata = {
|
||||
{
|
||||
.name = "ram_console",
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.size = KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR,
|
||||
},
|
||||
{
|
||||
.name = "kexec_hb_page",
|
||||
.size = SZ_1M - (KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR),
|
||||
#else
|
||||
.size = SZ_1M,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -158,6 +158,10 @@
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSORS_SSP)
|
||||
enum {
|
||||
SNS_PWR_OFF,
|
||||
|
@ -970,7 +974,15 @@ static struct platform_device ram_console_device = {
|
|||
static struct persistent_ram_descriptor per_ram_descs[] __initdata = {
|
||||
{
|
||||
.name = "ram_console",
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.size = KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR,
|
||||
},
|
||||
{
|
||||
.name = "kexec_hb_page",
|
||||
.size = SZ_1M - (KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR),
|
||||
#else
|
||||
.size = SZ_1M,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -146,6 +146,10 @@
|
|||
#include <mach/fusion3-thermistor.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSORS_SSP)
|
||||
enum {
|
||||
SNS_PWR_OFF,
|
||||
|
@ -961,7 +965,15 @@ static struct platform_device ram_console_device = {
|
|||
static struct persistent_ram_descriptor per_ram_descs[] __initdata = {
|
||||
{
|
||||
.name = "ram_console",
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.size = KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR,
|
||||
},
|
||||
{
|
||||
.name = "kexec_hb_page",
|
||||
.size = SZ_1M - (KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR),
|
||||
#else
|
||||
.size = SZ_1M,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -150,6 +150,10 @@
|
|||
#include <mach/tdmb_pdata.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSORS_SSP)
|
||||
enum {
|
||||
SNS_PWR_OFF,
|
||||
|
@ -987,7 +991,15 @@ static struct platform_device ram_console_device = {
|
|||
static struct persistent_ram_descriptor per_ram_descs[] __initdata = {
|
||||
{
|
||||
.name = "ram_console",
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.size = KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR,
|
||||
},
|
||||
{
|
||||
.name = "kexec_hb_page",
|
||||
.size = SZ_1M - (KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR),
|
||||
#else
|
||||
.size = SZ_1M,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -148,6 +148,10 @@
|
|||
#include <mach/tdmb_pdata.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSORS_SSP)
|
||||
enum {
|
||||
SNS_PWR_OFF,
|
||||
|
@ -985,7 +989,15 @@ static struct platform_device ram_console_device = {
|
|||
static struct persistent_ram_descriptor per_ram_descs[] __initdata = {
|
||||
{
|
||||
.name = "ram_console",
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.size = KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR,
|
||||
},
|
||||
{
|
||||
.name = "kexec_hb_page",
|
||||
.size = SZ_1M - (KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR),
|
||||
#else
|
||||
.size = SZ_1M,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -150,6 +150,10 @@
|
|||
#include <mach/tdmb_pdata.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSORS_SSP)
|
||||
enum {
|
||||
SNS_PWR_OFF,
|
||||
|
@ -987,7 +991,15 @@ static struct platform_device ram_console_device = {
|
|||
static struct persistent_ram_descriptor per_ram_descs[] __initdata = {
|
||||
{
|
||||
.name = "ram_console",
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.size = KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR,
|
||||
},
|
||||
{
|
||||
.name = "kexec_hb_page",
|
||||
.size = SZ_1M - (KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR),
|
||||
#else
|
||||
.size = SZ_1M,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -144,6 +144,10 @@
|
|||
#include <mach/fusion3-thermistor.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSORS_SSP)
|
||||
enum {
|
||||
SNS_PWR_OFF,
|
||||
|
@ -962,7 +966,15 @@ static struct platform_device ram_console_device = {
|
|||
static struct persistent_ram_descriptor per_ram_descs[] __initdata = {
|
||||
{
|
||||
.name = "ram_console",
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.size = KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR,
|
||||
},
|
||||
{
|
||||
.name = "kexec_hb_page",
|
||||
.size = SZ_1M - (KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR),
|
||||
#else
|
||||
.size = SZ_1M,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -144,6 +144,10 @@
|
|||
#include <mach/fusion3-thermistor.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSORS_SSP)
|
||||
enum {
|
||||
SNS_PWR_OFF,
|
||||
|
@ -961,7 +965,15 @@ static struct platform_device ram_console_device = {
|
|||
static struct persistent_ram_descriptor per_ram_descs[] __initdata = {
|
||||
{
|
||||
.name = "ram_console",
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.size = KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR,
|
||||
},
|
||||
{
|
||||
.name = "kexec_hb_page",
|
||||
.size = SZ_1M - (KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR),
|
||||
#else
|
||||
.size = SZ_1M,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -144,6 +144,10 @@
|
|||
#include <mach/fusion3-thermistor.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSORS_SSP)
|
||||
enum {
|
||||
SNS_PWR_OFF,
|
||||
|
@ -962,7 +966,15 @@ static struct platform_device ram_console_device = {
|
|||
static struct persistent_ram_descriptor per_ram_descs[] __initdata = {
|
||||
{
|
||||
.name = "ram_console",
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.size = KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR,
|
||||
},
|
||||
{
|
||||
.name = "kexec_hb_page",
|
||||
.size = SZ_1M - (KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR),
|
||||
#else
|
||||
.size = SZ_1M,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -144,6 +144,10 @@
|
|||
#include <mach/fusion3-thermistor.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SENSORS_SSP)
|
||||
enum {
|
||||
SNS_PWR_OFF,
|
||||
|
@ -960,7 +964,15 @@ static struct platform_device ram_console_device = {
|
|||
static struct persistent_ram_descriptor per_ram_descs[] __initdata = {
|
||||
{
|
||||
.name = "ram_console",
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
.size = KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR,
|
||||
},
|
||||
{
|
||||
.name = "kexec_hb_page",
|
||||
.size = SZ_1M - (KEXEC_HB_PAGE_ADDR - RAMCONSOLE_PHYS_ADDR),
|
||||
#else
|
||||
.size = SZ_1M,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
/* physical offset of RAM */
|
||||
#define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET)
|
||||
#ifdef CONFIG_HAVE_END_MEM
|
||||
#define END_MEM UL(CONFIG_END_MEM)
|
||||
#endif
|
||||
|
||||
#define MAX_PHYSMEM_BITS 32
|
||||
#define SECTION_SIZE_BITS 28
|
||||
|
|
|
@ -40,6 +40,10 @@
|
|||
#include "msm_watchdog.h"
|
||||
#include "timer.h"
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#include <asm/kexec.h>
|
||||
#endif
|
||||
|
||||
#define WDT0_RST 0x38
|
||||
#define WDT0_EN 0x40
|
||||
#define WDT0_BARK_TIME 0x4C
|
||||
|
@ -373,6 +377,23 @@ static struct notifier_block dload_reboot_block = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
void msm_kexec_hardboot(void)
|
||||
{
|
||||
#if defined(CONFIG_MSM_DLOAD_MODE) && !defined(CONFIG_SEC_DEBUG)
|
||||
/* Do not enter download mode on reboot. */
|
||||
set_dload_mode(0);
|
||||
#endif
|
||||
|
||||
/* Set PM8XXX PMIC to reset on power off. */
|
||||
pm8xxx_reset_pwr_off(1);
|
||||
|
||||
/* Reboot with the recovery kernel since the boot kernel decompressor may
|
||||
* not support the hardboot jump. */
|
||||
__raw_writel(0x77665502, restart_reason);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init msm_pmic_restart_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
@ -427,6 +448,9 @@ static int __init msm_restart_init(void)
|
|||
restart_reason = MSM_IMEM_BASE + RESTART_REASON_ADDR;
|
||||
#endif
|
||||
pm_power_off = msm_power_off;
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
kexec_hardboot_hook = msm_kexec_hardboot;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -110,6 +110,9 @@ struct kimage {
|
|||
#define KEXEC_TYPE_DEFAULT 0
|
||||
#define KEXEC_TYPE_CRASH 1
|
||||
unsigned int preserve_context : 1;
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
unsigned int hardboot : 1;
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_HAS_KIMAGE_ARCH
|
||||
struct kimage_arch arch;
|
||||
|
@ -178,6 +181,9 @@ extern struct kimage *kexec_crash_image;
|
|||
|
||||
#define KEXEC_ON_CRASH 0x00000001
|
||||
#define KEXEC_PRESERVE_CONTEXT 0x00000002
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
#define KEXEC_HARDBOOT 0x00000004
|
||||
#endif
|
||||
#define KEXEC_ARCH_MASK 0xffff0000
|
||||
|
||||
/* These values match the ELF architecture values.
|
||||
|
@ -196,10 +202,14 @@ extern struct kimage *kexec_crash_image;
|
|||
#define KEXEC_ARCH_MIPS ( 8 << 16)
|
||||
|
||||
/* List of defined/legal kexec flags */
|
||||
#ifndef CONFIG_KEXEC_JUMP
|
||||
#define KEXEC_FLAGS KEXEC_ON_CRASH
|
||||
#else
|
||||
#if defined(CONFIG_KEXEC_JUMP) && defined(CONFIG_KEXEC_HARDBOOT)
|
||||
#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT | KEXEC_HARDBOOT)
|
||||
#elif defined(CONFIG_KEXEC_JUMP)
|
||||
#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT)
|
||||
#elif defined(CONFIG_KEXEC_HARDBOOT)
|
||||
#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_HARDBOOT)
|
||||
#else
|
||||
#define KEXEC_FLAGS (KEXEC_ON_CRASH)
|
||||
#endif
|
||||
|
||||
#define VMCOREINFO_BYTES (4096)
|
||||
|
|
|
@ -1004,6 +1004,10 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
|
|||
|
||||
if (flags & KEXEC_PRESERVE_CONTEXT)
|
||||
image->preserve_context = 1;
|
||||
#ifdef CONFIG_KEXEC_HARDBOOT
|
||||
if (flags & KEXEC_HARDBOOT)
|
||||
image->hardboot = 1;
|
||||
#endif
|
||||
result = machine_kexec_prepare(image);
|
||||
if (result)
|
||||
goto out;
|
||||
|
|
Loading…
Reference in New Issue