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 | 9c9c176 | 2007-03-05 23:35:45 +0100 | [diff] [blame] | 22 | #include <asm/ipl.h> |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 23 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 24 | typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long); |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 25 | |
Tobias Klauser | 2efe55a | 2006-06-26 18:57:34 +0200 | [diff] [blame] | 26 | extern const unsigned char relocate_kernel[]; |
| 27 | extern const unsigned long long relocate_kernel_len; |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 28 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 29 | int machine_kexec_prepare(struct kimage *image) |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 30 | { |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 31 | void *reboot_code_buffer; |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 32 | |
Heiko Carstens | 9c9c176 | 2007-03-05 23:35:45 +0100 | [diff] [blame] | 33 | /* Can't replace kernel image since it is read-only. */ |
| 34 | if (ipl_flags & IPL_NSS_VALID) |
| 35 | return -ENOSYS; |
| 36 | |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 37 | /* We don't support anything but the default image type for now. */ |
| 38 | if (image->type != KEXEC_TYPE_DEFAULT) |
| 39 | return -EINVAL; |
| 40 | |
| 41 | /* Get the destination where the assembler code should be copied to.*/ |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 42 | reboot_code_buffer = (void *) page_to_phys(image->control_code_page); |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 43 | |
| 44 | /* Then copy it */ |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 45 | memcpy(reboot_code_buffer, relocate_kernel, relocate_kernel_len); |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 46 | return 0; |
| 47 | } |
| 48 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 49 | void machine_kexec_cleanup(struct kimage *image) |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 50 | { |
| 51 | } |
| 52 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 53 | void machine_shutdown(void) |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 54 | { |
| 55 | printk(KERN_INFO "kexec: machine_shutdown called\n"); |
| 56 | } |
| 57 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 58 | void machine_kexec(struct kimage *image) |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 59 | { |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 60 | relocate_kernel_t data_mover; |
| 61 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 62 | smp_send_stop(); |
Heiko Carstens | 29b08d2 | 2006-12-04 15:40:40 +0100 | [diff] [blame] | 63 | pfault_fini(); |
Heiko Carstens | 15e9b58 | 2006-12-04 15:40:26 +0100 | [diff] [blame] | 64 | s390_reset_system(); |
| 65 | |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 66 | data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page); |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 67 | |
| 68 | /* Call the moving routine */ |
Heiko Carstens | c6b5b84 | 2006-12-04 15:40:33 +0100 | [diff] [blame] | 69 | (*data_mover)(&image->head, image->start); |
| 70 | for (;;); |
Heiko Carstens | cf13f0e | 2005-06-25 14:58:11 -0700 | [diff] [blame] | 71 | } |