Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 1 | /* |
| 2 | * arch/s390/kernel/machine_kexec.c |
| 3 | * |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 4 | * Copyright IBM Corp. 2005,2006 |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 5 | * |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 6 | * Author(s): Rolf Adelsberger, |
| 7 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 8 | */ |
| 9 | |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 10 | #include <linux/device.h> |
| 11 | #include <linux/mm.h> |
| 12 | #include <linux/kexec.h> |
| 13 | #include <linux/delay.h> |
Heiko Carstens | 2b67fc4 | 2007-02-05 21:16:47 +0100 | [diff] [blame^] | 14 | #include <linux/reboot.h> |
Heiko Carstens | a386fba | 2006-02-11 17:56:01 -0800 | [diff] [blame] | 15 | #include <asm/cio.h> |
| 16 | #include <asm/setup.h> |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 17 | #include <asm/pgtable.h> |
| 18 | #include <asm/pgalloc.h> |
| 19 | #include <asm/system.h> |
Heiko Carstens | a386fba | 2006-02-11 17:56:01 -0800 | [diff] [blame] | 20 | #include <asm/smp.h> |
Heiko Carstens | 15e9b58 | 2006-12-04 15:40:26 +0100 | [diff] [blame] | 21 | #include <asm/reset.h> |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 22 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 23 | typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long); |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 24 | |
Tobias Klauser | 2efe55a | 2006-06-26 18:57:34 +0200 | [diff] [blame] | 25 | extern const unsigned char relocate_kernel[]; |
| 26 | extern const unsigned long long relocate_kernel_len; |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 27 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 28 | int machine_kexec_prepare(struct kimage *image) |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 29 | { |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 30 | void *reboot_code_buffer; |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 31 | |
| 32 | /* We don't support anything but the default image type for now. */ |
| 33 | if (image->type != KEXEC_TYPE_DEFAULT) |
| 34 | return -EINVAL; |
| 35 | |
| 36 | /* Get the destination where the assembler code should be copied to.*/ |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 37 | reboot_code_buffer = (void *) page_to_phys(image->control_code_page); |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 38 | |
| 39 | /* Then copy it */ |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 40 | memcpy(reboot_code_buffer, relocate_kernel, relocate_kernel_len); |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 41 | return 0; |
| 42 | } |
| 43 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 44 | void machine_kexec_cleanup(struct kimage *image) |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 45 | { |
| 46 | } |
| 47 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 48 | void machine_shutdown(void) |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 49 | { |
| 50 | printk(KERN_INFO "kexec: machine_shutdown called\n"); |
| 51 | } |
| 52 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 53 | void machine_kexec(struct kimage *image) |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 54 | { |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 55 | relocate_kernel_t data_mover; |
| 56 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 57 | smp_send_stop(); |
Heiko Carstens | 29b08d2 | 2006-12-04 15:40:40 +0100 | [diff] [blame] | 58 | pfault_fini(); |
Heiko Carstens | 15e9b58 | 2006-12-04 15:40:26 +0100 | [diff] [blame] | 59 | s390_reset_system(); |
| 60 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 61 | data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page); |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 62 | |
| 63 | /* Call the moving routine */ |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 64 | (*data_mover)(&image->head, image->start); |
| 65 | for (;;); |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 66 | } |