Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/powerpc/kexec/core_32.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* PPC32 code to handle Linux booting another kernel.
4
*
5
* Copyright (C) 2002-2003 Eric Biederman <[email protected]>
6
* GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
7
* Copyright (C) 2005 IBM Corporation.
8
*/
9
10
#include <linux/irq.h>
11
#include <linux/kexec.h>
12
#include <linux/mm.h>
13
#include <linux/string.h>
14
#include <asm/cacheflush.h>
15
#include <asm/hw_irq.h>
16
#include <asm/io.h>
17
18
typedef void (*relocate_new_kernel_t)(
19
unsigned long indirection_page,
20
unsigned long reboot_code_buffer,
21
unsigned long start_address) __noreturn;
22
23
/*
24
* This is a generic machine_kexec function suitable at least for
25
* non-OpenFirmware embedded platforms.
26
* It merely copies the image relocation code to the control page and
27
* jumps to it.
28
* A platform specific function may just call this one.
29
*/
30
void default_machine_kexec(struct kimage *image)
31
{
32
extern const unsigned int relocate_new_kernel_size;
33
unsigned long page_list;
34
unsigned long reboot_code_buffer, reboot_code_buffer_phys;
35
relocate_new_kernel_t rnk;
36
37
/* Interrupts aren't acceptable while we reboot */
38
local_irq_disable();
39
40
/* mask each interrupt so we are in a more sane state for the
41
* kexec kernel */
42
machine_kexec_mask_interrupts();
43
44
page_list = image->head;
45
46
/* we need both effective and real address here */
47
reboot_code_buffer =
48
(unsigned long)page_address(image->control_code_page);
49
reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer);
50
51
/* copy our kernel relocation code to the control code page */
52
memcpy((void *)reboot_code_buffer, relocate_new_kernel,
53
relocate_new_kernel_size);
54
55
flush_icache_range(reboot_code_buffer,
56
reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
57
printk(KERN_INFO "Bye!\n");
58
59
if (!IS_ENABLED(CONFIG_PPC_85xx) && !IS_ENABLED(CONFIG_44x))
60
relocate_new_kernel(page_list, reboot_code_buffer_phys, image->start);
61
62
/* now call it */
63
rnk = (relocate_new_kernel_t) reboot_code_buffer;
64
(*rnk)(page_list, reboot_code_buffer_phys, image->start);
65
}
66
67
int machine_kexec_prepare(struct kimage *image)
68
{
69
return 0;
70
}
71
72