1/* 2 * s390x startup code 3 * 4 * Copyright (c) 2017 Red Hat Inc 5 * 6 * Authors: 7 * Thomas Huth <thuth@redhat.com> 8 * David Hildenbrand <david@redhat.com> 9 * 10 * This code is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU Library General Public License version 2. 12 */ 13#include <asm/asm-offsets.h> 14#include <asm/sigp.h> 15 16.section .init 17 18/* 19 * Short init between 0x10000 and 0x10480 and then jump to 0x11000. 20 * 0x10480 - 0x11000 are written to by bootloader. 21 * 22 * For KVM and TCG kernel boot we are in 64 bit z/Arch mode. 23 * When booting from disk the initial short psw is in 31 bit mode. 24 * When running under LPAR or z/VM, we might start in 31 bit and esam mode. 25 */ 26 .globl start 27start: 28 /* Switch to z/Architecture mode and 64-bit */ 29 slr %r0, %r0 # Set cpuid to zero 30 lhi %r1, 2 # mode 2 = esame 31 sigp %r1, %r0, SIGP_SET_ARCHITECTURE 32 /* XOR all registers with themselves to clear them fully. */ 33 .irp i, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 34 xgr \i,\i 35 .endr 36 sam64 # Set addressing mode to 64 bit 37 /* setup stack */ 38 larl %r15, stackptr 39 /* setup initial PSW mask + control registers*/ 40 larl %r1, initial_psw 41 lpswe 0(%r1) 42clear_bss_start: 43 larl %r2, __bss_start 44 larl %r3, __bss_end 45 slgr %r3, %r2 # Get sizeof bss 46 aghi %r3,-1 47 srlg %r4,%r3,8 # Calc number of 256 byte chunks 48 ltgr %r4,%r4 49 lgr %r1,%r2 50 jz clear_bss_remainder # If none, clear remaining bytes 51clear_bss_loop: 52 xc 0(256,%r1), 0(%r1) # Clear 256 byte chunks via xor 53 la %r1, 256(%r1) 54 brctg %r4, clear_bss_loop 55clear_bss_remainder: 56 larl %r2, memsetxc 57 ex %r3, 0(%r2) 58 /* setup pgm interrupt handler */ 59 larl %r1, pgm_int_psw 60 mvc GEN_LC_PGM_NEW_PSW(16), 0(%r1) 61 /* setup ext interrupt handler */ 62 larl %r1, ext_int_psw 63 mvc GEN_LC_EXT_NEW_PSW(16), 0(%r1) 64 /* setup mcck interrupt handler */ 65 larl %r1, mcck_int_psw 66 mvc GEN_LC_MCCK_NEW_PSW(16), 0(%r1) 67 /* setup io interrupt handler */ 68 larl %r1, io_int_psw 69 mvc GEN_LC_IO_NEW_PSW(16), 0(%r1) 70 /* setup svc interrupt handler */ 71 larl %r1, svc_int_psw 72 mvc GEN_LC_SVC_NEW_PSW(16), 0(%r1) 73 /* setup cr0, enabling e.g. AFP-register control */ 74 larl %r1, initial_cr0 75 lctlg %c0, %c0, 0(%r1) 76 /* call setup() */ 77 brasl %r14, setup 78 /* forward test parameter */ 79 larl %r2, __argc 80 llgf %r2, 0(%r2) 81 larl %r3, __argv 82 /* call to main() */ 83 brasl %r14, main 84 /* forward exit code */ 85 lgr %r3, %r2 86 /* call exit() */ 87 j exit 88 89memsetxc: 90 xc 0(1,%r1),0(%r1) 91 92 .macro SAVE_REGS 93 /* save grs 0-15 */ 94 stmg %r0, %r15, GEN_LC_SW_INT_GRS 95 /* save cr0 */ 96 stctg %c0, %c0, GEN_LC_SW_INT_CR0 97 /* load initial cr0 again */ 98 larl %r1, initial_cr0 99 lctlg %c0, %c0, 0(%r1) 100 /* save fprs 0-15 + fpc */ 101 la %r1, GEN_LC_SW_INT_FPRS 102 std %f0, 0(%r1) 103 std %f1, 8(%r1) 104 std %f2, 16(%r1) 105 std %f3, 24(%r1) 106 std %f4, 32(%r1) 107 std %f5, 40(%r1) 108 std %f6, 48(%r1) 109 std %f7, 56(%r1) 110 std %f8, 64(%r1) 111 std %f9, 72(%r1) 112 std %f10, 80(%r1) 113 std %f11, 88(%r1) 114 std %f12, 96(%r1) 115 std %f13, 104(%r1) 116 std %f14, 112(%r1) 117 std %f15, 120(%r1) 118 stfpc GEN_LC_SW_INT_FPC 119 .endm 120 121 .macro RESTORE_REGS 122 /* restore fprs 0-15 + fpc */ 123 la %r1, GEN_LC_SW_INT_FPRS 124 ld %f0, 0(%r1) 125 ld %f1, 8(%r1) 126 ld %f2, 16(%r1) 127 ld %f3, 24(%r1) 128 ld %f4, 32(%r1) 129 ld %f5, 40(%r1) 130 ld %f6, 48(%r1) 131 ld %f7, 56(%r1) 132 ld %f8, 64(%r1) 133 ld %f9, 72(%r1) 134 ld %f10, 80(%r1) 135 ld %f11, 88(%r1) 136 ld %f12, 96(%r1) 137 ld %f13, 104(%r1) 138 ld %f14, 112(%r1) 139 ld %f15, 120(%r1) 140 lfpc GEN_LC_SW_INT_FPC 141 /* restore cr0 */ 142 lctlg %c0, %c0, GEN_LC_SW_INT_CR0 143 /* restore grs 0-15 */ 144 lmg %r0, %r15, GEN_LC_SW_INT_GRS 145 .endm 146 147.section .text 148/* 149 * load_reset calling convention: 150 * %r2 subcode (0 or 1) 151 */ 152.globl diag308_load_reset 153diag308_load_reset: 154 SAVE_REGS 155 /* Save the first PSW word to the IPL PSW */ 156 epsw %r0, %r1 157 st %r0, 0 158 /* Store the address and the bit for 31 bit addressing */ 159 larl %r0, 0f 160 oilh %r0, 0x8000 161 st %r0, 0x4 162 /* Do the reset */ 163 diag %r0,%r2,0x308 164 /* Failure path */ 165 xgr %r2, %r2 166 br %r14 167 /* Success path */ 168 /* We lost cr0 due to the reset */ 1690: larl %r1, initial_cr0 170 lctlg %c0, %c0, 0(%r1) 171 RESTORE_REGS 172 lhi %r2, 1 173 br %r14 174 175.globl smp_cpu_setup_state 176smp_cpu_setup_state: 177 xgr %r1, %r1 178 lmg %r0, %r15, GEN_LC_SW_INT_GRS 179 lctlg %c0, %c0, GEN_LC_SW_INT_CR0 180 br %r14 181 182pgm_int: 183 SAVE_REGS 184 brasl %r14, handle_pgm_int 185 RESTORE_REGS 186 lpswe GEN_LC_PGM_OLD_PSW 187 188ext_int: 189 SAVE_REGS 190 brasl %r14, handle_ext_int 191 RESTORE_REGS 192 lpswe GEN_LC_EXT_OLD_PSW 193 194mcck_int: 195 SAVE_REGS 196 brasl %r14, handle_mcck_int 197 RESTORE_REGS 198 lpswe GEN_LC_MCCK_OLD_PSW 199 200io_int: 201 SAVE_REGS 202 brasl %r14, handle_io_int 203 RESTORE_REGS 204 lpswe GEN_LC_IO_OLD_PSW 205 206svc_int: 207 SAVE_REGS 208 brasl %r14, handle_svc_int 209 RESTORE_REGS 210 lpswe GEN_LC_SVC_OLD_PSW 211 212 .align 8 213initial_psw: 214 .quad 0x0000000180000000, clear_bss_start 215pgm_int_psw: 216 .quad 0x0000000180000000, pgm_int 217ext_int_psw: 218 .quad 0x0000000180000000, ext_int 219mcck_int_psw: 220 .quad 0x0000000180000000, mcck_int 221io_int_psw: 222 .quad 0x0000000180000000, io_int 223svc_int_psw: 224 .quad 0x0000000180000000, svc_int 225initial_cr0: 226 /* enable AFP-register control, so FP regs (+BFP instr) can be used */ 227 .quad 0x0000000000040000 228