Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
openSUSE:Leap:15.2:Staging:N
s390-tools
s390-tools-sles15sp2-34-zipl-move-s390.h-to-inc...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File s390-tools-sles15sp2-34-zipl-move-s390.h-to-include-boot-s390.h.patch of Package s390-tools
Subject: [PATCH] [FEAT VS1804] zipl: move s390.h to include/boot/s390.h From: Marc Hartmayer <mhartmay@linux.ibm.com> Summary: genprotimg: Introduce new tool for the creation of PV images Description: genprotimg takes a kernel, host-key documents, optionally an initrd, optionally a file with the kernel command line, and it generates a single, loadable image file. The image consists of a concatenation of a plain text boot loader, the encrypted components for kernel, initrd, and cmdline, and the integrity-protected PV header, containing metadata necessary for running the guest in PV mode. It's possible to use this image file as a kernel for zIPL or for a direct kernel boot using QEMU. Upstream-ID: b83c8944f195117609a36f383f32377014e34c31 Problem-ID: VS1804 Upstream-Description: zipl: move s390.h to include/boot/s390.h Now that we made sure that s390.h can be used with our minimal libc implementation and glibc move s390.h to `include/boot/s390.h`. While at it, make sure that s390.h is assembler compatible as it will be used later in the PV boot loader and include s390.h in ipl.h as PAGE_SIZE is used there. Reviewed-by: Philipp Rudo <prudo@linux.ibm.com> Reviewed-by: Stefan Haberland <sth@linux.ibm.com> Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com> Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com> --- include/boot/ipl.h | 1 include/boot/s390.h | 452 +++++++++++++++++++++++++++++++++++++++++++++++++ zipl/boot/cio.c | 2 zipl/boot/cio.h | 2 zipl/boot/eckd2.c | 2 zipl/boot/eckd2dump.c | 2 zipl/boot/fba2.c | 2 zipl/boot/kdump.c | 2 zipl/boot/kdump.h | 2 zipl/boot/s390.h | 449 ------------------------------------------------ zipl/boot/sclp.c | 2 zipl/boot/sclp.h | 2 zipl/boot/stage2.c | 2 zipl/boot/stage2.h | 3 zipl/boot/stage2dump.h | 2 zipl/boot/stage3.c | 2 zipl/boot/stage3.h | 2 17 files changed, 467 insertions(+), 464 deletions(-) --- a/include/boot/ipl.h +++ b/include/boot/ipl.h @@ -11,6 +11,7 @@ #define IPL_H #include "lib/zt_common.h" +#include "s390.h" #define IPL_FLAG_SECURE 0x40 --- /dev/null +++ b/include/boot/s390.h @@ -0,0 +1,452 @@ +/* + * s390 related definitions and functions. + * + * Copyright IBM Corp. 2013, 2020 + * + * s390-tools is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#ifndef S390_H +#define S390_H + +#include "lib/zt_common.h" +#include "boot/sigp.h" + +#define __LC_IPLDEV 0x0c6c +#define __LC_OS_INFO 0x0e18 + +#define PAGE_SIZE _AC(4096, UL) + + +#ifndef __ASSEMBLER__ + +/* + * Helper macro for exception table entries + */ +#define EX_TABLE(_fault, _target) \ + ".section .ex_table,\"a\"\n" \ + ".align 4\n" \ + ".long (" #_fault ")\n" \ + ".long (" #_target ")\n" \ + ".previous\n" + +struct psw_t { + uint64_t mask; + uint64_t addr; +} __aligned(8); + +struct psw32_t { + uint32_t mask; + uint32_t addr; +} __aligned(8); + +void load_wait_psw(uint64_t, struct psw_t *); + +struct _lowcore { + uint8_t pad_0x0000[0x0014-0x0000]; /* 0x0000 */ + uint32_t ipl_parmblock_ptr; /* 0x0014 */ + uint8_t pad_0x0018[0x0080-0x0018]; /* 0x0018 */ + uint32_t ext_params; /* 0x0080 */ + uint16_t ext_cpu_addr; /* 0x0084 */ + uint16_t ext_int_code; /* 0x0086 */ + uint16_t svc_ilc; /* 0x0088 */ + uint16_t svc_code; /* 0x008a */ + uint16_t pgm_ilc; /* 0x008c */ + uint16_t pgm_code; /* 0x008e */ + uint32_t data_exc_code; /* 0x0090 */ + uint16_t mon_class_num; /* 0x0094 */ + uint16_t per_perc_atmid; /* 0x0096 */ + uint64_t per_address; /* 0x0098 */ + uint8_t exc_access_id; /* 0x00a0 */ + uint8_t per_access_id; /* 0x00a1 */ + uint8_t op_access_id; /* 0x00a2 */ + uint8_t ar_access_id; /* 0x00a3 */ + uint8_t pad_0x00a4[0x00a8-0x00a4]; /* 0x00a4 */ + uint64_t trans_exc_code; /* 0x00a8 */ + uint64_t monitor_code; /* 0x00b0 */ + uint16_t subchannel_id; /* 0x00b8 */ + uint16_t subchannel_nr; /* 0x00ba */ + uint32_t io_int_parm; /* 0x00bc */ + uint32_t io_int_word; /* 0x00c0 */ + uint8_t pad_0x00c4[0x00c8-0x00c4]; /* 0x00c4 */ + uint32_t stfl_fac_list; /* 0x00c8 */ + uint8_t pad_0x00cc[0x00e8-0x00cc]; /* 0x00cc */ + uint32_t mcck_interruption_code[2]; /* 0x00e8 */ + uint8_t pad_0x00f0[0x00f4-0x00f0]; /* 0x00f0 */ + uint32_t external_damage_code; /* 0x00f4 */ + uint64_t failing_storage_address; /* 0x00f8 */ + uint8_t pad_0x0100[0x0110-0x0100]; /* 0x0100 */ + uint64_t breaking_event_addr; /* 0x0110 */ + uint8_t pad_0x0118[0x0120-0x0118]; /* 0x0118 */ + struct psw_t restart_old_psw; /* 0x0120 */ + struct psw_t external_old_psw; /* 0x0130 */ + struct psw_t svc_old_psw; /* 0x0140 */ + struct psw_t program_old_psw; /* 0x0150 */ + struct psw_t mcck_old_psw; /* 0x0160 */ + struct psw_t io_old_psw; /* 0x0170 */ + uint8_t pad_0x0180[0x01a0-0x0180]; /* 0x0180 */ + struct psw_t restart_psw; /* 0x01a0 */ + struct psw_t external_new_psw; /* 0x01b0 */ + struct psw_t svc_new_psw; /* 0x01c0 */ + struct psw_t program_new_psw; /* 0x01d0 */ + struct psw_t mcck_new_psw; /* 0x01e0 */ + struct psw_t io_new_psw; /* 0x01f0 */ + + /* Save areas. */ + uint64_t save_area_sync[8]; /* 0x0200 */ + uint64_t save_area_async[8]; /* 0x0240 */ + uint64_t save_area_restart[1]; /* 0x0280 */ + uint8_t pad_0x0288[0x0290-0x0288]; /* 0x0288 */ + + /* Return psws. */ + struct psw_t return_psw; /* 0x0290 */ + struct psw_t return_mcck_psw; /* 0x02a0 */ + + /* CPU accounting and timing values. */ + uint64_t sync_enter_timer; /* 0x02b0 */ + uint64_t async_enter_timer; /* 0x02b8 */ + uint64_t mcck_enter_timer; /* 0x02c0 */ + uint64_t exit_timer; /* 0x02c8 */ + uint64_t user_timer; /* 0x02d0 */ + uint64_t system_timer; /* 0x02d8 */ + uint64_t steal_timer; /* 0x02e0 */ + uint64_t last_update_timer; /* 0x02e8 */ + uint64_t last_update_clock; /* 0x02f0 */ + uint64_t int_clock; /* 0x02f8 */ + uint64_t mcck_clock; /* 0x0300 */ + uint64_t clock_comparator; /* 0x0308 */ + + /* Current process. */ + uint64_t current_task; /* 0x0310 */ + uint64_t thread_info; /* 0x0318 */ + uint64_t kernel_stack; /* 0x0320 */ + + /* Interrupt, panic and restart stack. */ + uint64_t async_stack; /* 0x0328 */ + uint64_t panic_stack; /* 0x0330 */ + uint64_t restart_stack; /* 0x0338 */ + + /* Restart function and parameter. */ + uint64_t restart_fn; /* 0x0340 */ + uint64_t restart_data; /* 0x0348 */ + uint64_t restart_source; /* 0x0350 */ + + /* Address space pointer. */ + uint64_t kernel_asce; /* 0x0358 */ + uint64_t user_asce; /* 0x0360 */ + uint64_t current_pid; /* 0x0368 */ + + /* SMP info area */ + uint32_t cpu_nr; /* 0x0370 */ + uint32_t softirq_pending; /* 0x0374 */ + uint64_t percpu_offset; /* 0x0378 */ + uint64_t vdso_per_cpu_data; /* 0x0380 */ + uint64_t machine_flags; /* 0x0388 */ + uint64_t ftrace_func; /* 0x0390 */ + uint64_t gmap; /* 0x0398 */ + uint8_t pad_0x03a0[0x0400-0x03a0]; /* 0x03a0 */ + + /* Interrupt response block. */ + uint8_t irb[64]; /* 0x0400 */ + + /* Per cpu primary space access list */ + uint32_t paste[16]; /* 0x0440 */ + + uint8_t pad_0x0480[0x0e00-0x0480]; /* 0x0480 */ + + /* + * 0xe00 contains the address of the IPL Parameter Information + * block. Dump tools need IPIB for IPL after dump. + * Note: do not change the position of any fields in 0x0e00-0x0f00 + */ + uint64_t ipib; /* 0x0e00 */ + uint32_t ipib_checksum; /* 0x0e08 */ + uint64_t vmcore_info; /* 0x0e0c */ + uint8_t pad_0x0e14[0x0e18-0x0e14]; /* 0x0e14 */ + uint64_t os_info; /* 0x0e18 */ + uint8_t pad_0x0e20[0x0f00-0x0e20]; /* 0x0e20 */ + + /* Extended facility list */ + uint64_t stfle_fac_list[32]; /* 0x0f00 */ + uint8_t pad_0x1000[0x11b0-0x1000]; /* 0x1000 */ + uint64_t vector_save_area_addr; /* 0x11b0 */ + /* 64 bit extparam used for pfault/diag 250: defined by architecture */ + uint64_t ext_params2; /* 0x11B8 */ + uint8_t pad_0x11c0[0x1200-0x11C0]; /* 0x11C0 */ + + /* CPU register save area: defined by architecture */ + uint64_t floating_pt_save_area[16]; /* 0x1200 */ + uint64_t gpregs_save_area[16]; /* 0x1280 */ + struct psw_t psw_save_area; /* 0x1300 */ + uint8_t pad_0x1310[0x1318-0x1310]; /* 0x1310 */ + uint32_t prefixreg_save_area; /* 0x1318 */ + uint32_t fpt_creg_save_area; /* 0x131c */ + uint8_t pad_0x1320[0x1324-0x1320]; /* 0x1320 */ + uint32_t tod_progreg_save_area; /* 0x1324 */ + uint32_t cpu_timer_save_area[2]; /* 0x1328 */ + uint32_t clock_comp_save_area[2]; /* 0x1330 */ + uint8_t pad_0x1338[0x1340-0x1338]; /* 0x1338 */ + uint32_t access_regs_save_area[16]; /* 0x1340 */ + uint64_t cregs_save_area[16]; /* 0x1380 */ + uint8_t pad_0x1400[0x1800-0x1400]; /* 0x1400 */ + + /* Transaction abort diagnostic block */ + uint8_t pgm_tdb[256]; /* 0x1800 */ + + /* align to the top of the prefix area */ + uint8_t pad_0x1900[0x2000-0x1900]; /* 0x1900 */ +} __packed __aligned(8192); + +#define S390_lowcore (*((struct _lowcore *) 0)) + + +void panic_notify(unsigned long reason); + +#define panic(reason, x...) \ +do { \ + printf(x); \ + panic_notify(reason); \ + libc_stop(reason); \ +} while (0) + +static __always_inline int page_is_valid(unsigned long addr) +{ + unsigned long tmp; + int rc; + + asm volatile( + "0: ic %1,%2\n" + "1: lhi %0,1\n" + "2:\n" + ".pushsection .fixup, \"ax\"\n" + "3: xr %0,%0\n" + " jg 2b\n" + ".popsection\n" + EX_TABLE(0b, 3b) EX_TABLE(1b, 3b) + : "=d" (rc), "=d" (tmp) + : "Q" (*(unsigned long *) addr) + : "cc"); + return rc; +} + +static __always_inline uint32_t csum_partial(const void *buf, int len, uint32_t sum) +{ + register unsigned long reg2 asm("2") = (unsigned long) buf; + register unsigned long reg3 asm("3") = (unsigned long) len; + + asm volatile( + "0: cksm %0,%1\n" /* do checksum on longs */ + " jo 0b\n" + : "+d" (sum), "+d" (reg2), "+d" (reg3) : : "cc", "memory"); + return sum; +} + +#define __ctl_store(array, low, high) ({ \ + typedef struct { char _[sizeof(array)]; } __may_alias addrtype;\ + asm volatile( \ + " stctg %1,%2,%0\n" \ + : "=Q" (*(addrtype *)(&array)) \ + : "i" (low), "i" (high)); \ +}) + +#define __ctl_load(array, low, high) ({ \ + typedef struct { char _[sizeof(array)]; } __may_alias addrtype; \ + asm volatile( \ + " lctlg %1,%2,%0\n" \ + : : "Q" (*(addrtype *)(&array)), \ + "i" (low), "i" (high)); \ +}) + +static __always_inline void __ctl_set_bit(unsigned int cr, unsigned int bit) +{ + unsigned long reg; + + __ctl_store(reg, cr, cr); + reg |= 1UL << bit; + __ctl_load(reg, cr, cr); +} + +/* + * DIAG 308 support + */ +enum diag308_subcode { + DIAG308_REL_HSA = 2, + DIAG308_IPL = 3, + DIAG308_DUMP = 4, + DIAG308_SET = 5, + DIAG308_STORE = 6, +}; + +static __always_inline int diag308(unsigned long subcode, void *addr) +{ + register unsigned long _addr asm("0") = (unsigned long) addr; + register unsigned long _rc asm("1") = 0; + + asm volatile( + " diag %0,%2,0x308\n" + "0:\n" + : "+d" (_addr), "+d" (_rc) + : "d" (subcode) : "cc", "memory"); + return _rc; +} + +/* + * Store CPU address + */ +static __always_inline unsigned short stap(void) +{ + unsigned short cpu_address; + + asm volatile("stap %0" : "=m" (cpu_address)); + return cpu_address; +} + +/* + * Program the clock comparator + */ +static __always_inline void set_clock_comparator(uint64_t time) +{ + asm volatile("sckc %0" : : "Q" (time)); +} + +/* + * Program the CPU timer + */ +static __always_inline void set_cpu_timer(uint64_t timer) +{ + asm volatile("spt %0" : : "Q" (timer)); +} + +/* + * Get current time (store clock) + */ +static __always_inline unsigned long long get_tod_clock(void) +{ + unsigned long long clk; + + asm volatile("stck %0" : "=Q" (clk) : : "cc"); + return clk; +} + +/* + * Get ID of current CPU + */ +struct cpuid { + unsigned int version:8; + unsigned int ident:24; + unsigned int machine:16; + unsigned int unused:16; +} __packed __aligned(8); + +static __always_inline void get_cpu_id(struct cpuid *ptr) +{ + asm volatile("stidp %0" : "=Q" (*ptr)); +} + +/* + * Check if we run under z/VM + */ +static __always_inline int is_zvm(void) +{ + struct cpuid cpuid; + + get_cpu_id(&cpuid); + return cpuid.version == 0xff; +} + +/* + * Vector register definition + */ +typedef struct { + uint32_t u[4]; +} __vector128; + +/* + * Save vector registers + */ +static __always_inline void save_vx_regs(__vector128 *vxrs) +{ + typedef struct { __vector128 _[32]; } addrtype; + + asm volatile( + " la 1,%0\n" + " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */ + " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */ + : "=Q" (*(addrtype *) vxrs) : : "1"); +} + +/* + * Save vector registers safe + */ +static __always_inline void save_vx_regs_safe(__vector128 *vxrs) +{ + unsigned long cr0; + + __ctl_store(cr0, 0, 0); + __ctl_set_bit(0, 17); + __ctl_set_bit(0, 18); /* AFP-register-control */ + save_vx_regs(vxrs); + __ctl_load(cr0, 0, 0); +} + +#define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */ + +static __always_inline int __test_facility(unsigned long nr, void *facilities) +{ + unsigned char *ptr; + + if (nr >= MAX_FACILITY_BIT) + return 0; + ptr = (unsigned char *) facilities + (nr >> 3); + return (*ptr & (0x80 >> (nr & 7))) != 0; +} + +/* + * The test_facility function uses the bit odering where the MSB is bit 0. + * That makes it easier to query facility bits with the bit number as + * documented in the Principles of Operation. + */ +static __always_inline int test_facility(unsigned long nr) +{ + return __test_facility(nr, &S390_lowcore.stfle_fac_list); +} + +static __always_inline unsigned long __stfle_asm(uint64_t *stfle_fac_list, int size) +{ + register unsigned long reg0 asm("0") = size - 1; + + asm volatile( + ".insn s,0xb2b00000,0(%1)" /* stfle */ + : "+d" (reg0) + : "a" (stfle_fac_list) + : "memory", "cc"); + return reg0; +} + +/** + * stfle - Store facility list extended + * @stfle_fac_list: array where facility list can be stored + * @size: size of passed in array in double words + */ +static __always_inline void stfle(uint64_t *stfle_fac_list, int size) +{ + unsigned long nr; + + asm volatile( + " .insn s,0xb2b10000,0(0)\n" /* stfl */ + "0:\n" + EX_TABLE(0b, 0b) + : "+m" (S390_lowcore.stfl_fac_list)); + nr = 4; /* bytes stored by stfl */ + memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); + if (S390_lowcore.stfl_fac_list & 0x01000000) { + /* More facility bits available with stfle */ + nr = __stfle_asm(stfle_fac_list, size); + nr = MIN((nr + 1) * 8, size * 8UL); + } + memset((char *) stfle_fac_list + nr, 0, size * 8 - nr); +} + +#endif /* __ASSEMBLER__ */ +#endif /* S390_H */ --- a/zipl/boot/cio.c +++ b/zipl/boot/cio.c @@ -12,7 +12,7 @@ #include "cio.h" #include "error.h" #include "libc.h" -#include "s390.h" +#include "boot/s390.h" static unsigned long initial_lpm = 0x00; static const char *msg_essch = "Start subchannel failed"; --- a/zipl/boot/cio.h +++ b/zipl/boot/cio.h @@ -12,7 +12,7 @@ #define CIO_H #include "libc.h" -#include "s390.h" +#include "boot/s390.h" /* Condition codes */ #define CC_INITIATED 0 --- a/zipl/boot/eckd2.c +++ b/zipl/boot/eckd2.c @@ -10,7 +10,7 @@ */ #include "eckd.h" -#include "s390.h" +#include "boot/s390.h" #include "stage2.h" int extract_length(void *data) --- a/zipl/boot/eckd2dump.c +++ b/zipl/boot/eckd2dump.c @@ -12,7 +12,7 @@ #include "cio.h" #include "eckd2dump.h" #include "error.h" -#include "s390.h" +#include "boot/s390.h" #include "stage2dump.h" #define ECKD_CCW_LOCATE_RECORD 0x47 --- a/zipl/boot/fba2.c +++ b/zipl/boot/fba2.c @@ -11,7 +11,7 @@ #include "fba.h" #include "libc.h" -#include "s390.h" +#include "boot/s390.h" int extract_length(void *data) { struct linear_blockptr *blockptr = (struct linear_blockptr *)data; --- a/zipl/boot/kdump.c +++ b/zipl/boot/kdump.c @@ -13,7 +13,7 @@ #include "kdump.h" #include "libc.h" #include "menu.h" -#include "s390.h" +#include "boot/s390.h" void kdump_failed(unsigned long reason) { --- a/zipl/boot/kdump.h +++ b/zipl/boot/kdump.h @@ -14,7 +14,7 @@ #define KDUMP_H #include "libc.h" -#include "s390.h" +#include "boot/s390.h" #define OS_INFO_VERSION_MAJOR_SUPPORTED 1 #define OS_INFO_MAGIC 0x4f53494e464f535aULL /* OSINFOSZ */ --- a/zipl/boot/s390.h +++ /dev/null @@ -1,449 +0,0 @@ -/* - * zipl - zSeries Initial Program Loader tool - * - * System z specific functions - * - * Copyright IBM Corp. 2013, 2017 - * - * s390-tools is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ -#ifndef S390_H -#define S390_H - -#include "lib/zt_common.h" -#include "boot/sigp.h" - - -/* - * Helper macro for exception table entries - */ -#define EX_TABLE(_fault, _target) \ - ".section .ex_table,\"a\"\n" \ - ".align 4\n" \ - ".long (" #_fault ")\n" \ - ".long (" #_target ")\n" \ - ".previous\n" - -struct psw_t { - uint64_t mask; - uint64_t addr; -} __aligned(8); - -struct psw32_t { - uint32_t mask; - uint32_t addr; -} __aligned(8); - -void load_wait_psw(uint64_t, struct psw_t *); - -struct _lowcore { - uint8_t pad_0x0000[0x0014-0x0000]; /* 0x0000 */ - uint32_t ipl_parmblock_ptr; /* 0x0014 */ - uint8_t pad_0x0018[0x0080-0x0018]; /* 0x0018 */ - uint32_t ext_params; /* 0x0080 */ - uint16_t ext_cpu_addr; /* 0x0084 */ - uint16_t ext_int_code; /* 0x0086 */ - uint16_t svc_ilc; /* 0x0088 */ - uint16_t svc_code; /* 0x008a */ - uint16_t pgm_ilc; /* 0x008c */ - uint16_t pgm_code; /* 0x008e */ - uint32_t data_exc_code; /* 0x0090 */ - uint16_t mon_class_num; /* 0x0094 */ - uint16_t per_perc_atmid; /* 0x0096 */ - uint64_t per_address; /* 0x0098 */ - uint8_t exc_access_id; /* 0x00a0 */ - uint8_t per_access_id; /* 0x00a1 */ - uint8_t op_access_id; /* 0x00a2 */ - uint8_t ar_access_id; /* 0x00a3 */ - uint8_t pad_0x00a4[0x00a8-0x00a4]; /* 0x00a4 */ - uint64_t trans_exc_code; /* 0x00a8 */ - uint64_t monitor_code; /* 0x00b0 */ - uint16_t subchannel_id; /* 0x00b8 */ - uint16_t subchannel_nr; /* 0x00ba */ - uint32_t io_int_parm; /* 0x00bc */ - uint32_t io_int_word; /* 0x00c0 */ - uint8_t pad_0x00c4[0x00c8-0x00c4]; /* 0x00c4 */ - uint32_t stfl_fac_list; /* 0x00c8 */ - uint8_t pad_0x00cc[0x00e8-0x00cc]; /* 0x00cc */ - uint32_t mcck_interruption_code[2]; /* 0x00e8 */ - uint8_t pad_0x00f0[0x00f4-0x00f0]; /* 0x00f0 */ - uint32_t external_damage_code; /* 0x00f4 */ - uint64_t failing_storage_address; /* 0x00f8 */ - uint8_t pad_0x0100[0x0110-0x0100]; /* 0x0100 */ - uint64_t breaking_event_addr; /* 0x0110 */ - uint8_t pad_0x0118[0x0120-0x0118]; /* 0x0118 */ - struct psw_t restart_old_psw; /* 0x0120 */ - struct psw_t external_old_psw; /* 0x0130 */ - struct psw_t svc_old_psw; /* 0x0140 */ - struct psw_t program_old_psw; /* 0x0150 */ - struct psw_t mcck_old_psw; /* 0x0160 */ - struct psw_t io_old_psw; /* 0x0170 */ - uint8_t pad_0x0180[0x01a0-0x0180]; /* 0x0180 */ - struct psw_t restart_psw; /* 0x01a0 */ - struct psw_t external_new_psw; /* 0x01b0 */ - struct psw_t svc_new_psw; /* 0x01c0 */ - struct psw_t program_new_psw; /* 0x01d0 */ - struct psw_t mcck_new_psw; /* 0x01e0 */ - struct psw_t io_new_psw; /* 0x01f0 */ - - /* Save areas. */ - uint64_t save_area_sync[8]; /* 0x0200 */ - uint64_t save_area_async[8]; /* 0x0240 */ - uint64_t save_area_restart[1]; /* 0x0280 */ - uint8_t pad_0x0288[0x0290-0x0288]; /* 0x0288 */ - - /* Return psws. */ - struct psw_t return_psw; /* 0x0290 */ - struct psw_t return_mcck_psw; /* 0x02a0 */ - - /* CPU accounting and timing values. */ - uint64_t sync_enter_timer; /* 0x02b0 */ - uint64_t async_enter_timer; /* 0x02b8 */ - uint64_t mcck_enter_timer; /* 0x02c0 */ - uint64_t exit_timer; /* 0x02c8 */ - uint64_t user_timer; /* 0x02d0 */ - uint64_t system_timer; /* 0x02d8 */ - uint64_t steal_timer; /* 0x02e0 */ - uint64_t last_update_timer; /* 0x02e8 */ - uint64_t last_update_clock; /* 0x02f0 */ - uint64_t int_clock; /* 0x02f8 */ - uint64_t mcck_clock; /* 0x0300 */ - uint64_t clock_comparator; /* 0x0308 */ - - /* Current process. */ - uint64_t current_task; /* 0x0310 */ - uint64_t thread_info; /* 0x0318 */ - uint64_t kernel_stack; /* 0x0320 */ - - /* Interrupt, panic and restart stack. */ - uint64_t async_stack; /* 0x0328 */ - uint64_t panic_stack; /* 0x0330 */ - uint64_t restart_stack; /* 0x0338 */ - - /* Restart function and parameter. */ - uint64_t restart_fn; /* 0x0340 */ - uint64_t restart_data; /* 0x0348 */ - uint64_t restart_source; /* 0x0350 */ - - /* Address space pointer. */ - uint64_t kernel_asce; /* 0x0358 */ - uint64_t user_asce; /* 0x0360 */ - uint64_t current_pid; /* 0x0368 */ - - /* SMP info area */ - uint32_t cpu_nr; /* 0x0370 */ - uint32_t softirq_pending; /* 0x0374 */ - uint64_t percpu_offset; /* 0x0378 */ - uint64_t vdso_per_cpu_data; /* 0x0380 */ - uint64_t machine_flags; /* 0x0388 */ - uint64_t ftrace_func; /* 0x0390 */ - uint64_t gmap; /* 0x0398 */ - uint8_t pad_0x03a0[0x0400-0x03a0]; /* 0x03a0 */ - - /* Interrupt response block. */ - uint8_t irb[64]; /* 0x0400 */ - - /* Per cpu primary space access list */ - uint32_t paste[16]; /* 0x0440 */ - - uint8_t pad_0x0480[0x0e00-0x0480]; /* 0x0480 */ - - /* - * 0xe00 contains the address of the IPL Parameter Information - * block. Dump tools need IPIB for IPL after dump. - * Note: do not change the position of any fields in 0x0e00-0x0f00 - */ - uint64_t ipib; /* 0x0e00 */ - uint32_t ipib_checksum; /* 0x0e08 */ - uint64_t vmcore_info; /* 0x0e0c */ - uint8_t pad_0x0e14[0x0e18-0x0e14]; /* 0x0e14 */ - uint64_t os_info; /* 0x0e18 */ - uint8_t pad_0x0e20[0x0f00-0x0e20]; /* 0x0e20 */ - - /* Extended facility list */ - uint64_t stfle_fac_list[32]; /* 0x0f00 */ - uint8_t pad_0x1000[0x11b0-0x1000]; /* 0x1000 */ - uint64_t vector_save_area_addr; /* 0x11b0 */ - /* 64 bit extparam used for pfault/diag 250: defined by architecture */ - uint64_t ext_params2; /* 0x11B8 */ - uint8_t pad_0x11c0[0x1200-0x11C0]; /* 0x11C0 */ - - /* CPU register save area: defined by architecture */ - uint64_t floating_pt_save_area[16]; /* 0x1200 */ - uint64_t gpregs_save_area[16]; /* 0x1280 */ - struct psw_t psw_save_area; /* 0x1300 */ - uint8_t pad_0x1310[0x1318-0x1310]; /* 0x1310 */ - uint32_t prefixreg_save_area; /* 0x1318 */ - uint32_t fpt_creg_save_area; /* 0x131c */ - uint8_t pad_0x1320[0x1324-0x1320]; /* 0x1320 */ - uint32_t tod_progreg_save_area; /* 0x1324 */ - uint32_t cpu_timer_save_area[2]; /* 0x1328 */ - uint32_t clock_comp_save_area[2]; /* 0x1330 */ - uint8_t pad_0x1338[0x1340-0x1338]; /* 0x1338 */ - uint32_t access_regs_save_area[16]; /* 0x1340 */ - uint64_t cregs_save_area[16]; /* 0x1380 */ - uint8_t pad_0x1400[0x1800-0x1400]; /* 0x1400 */ - - /* Transaction abort diagnostic block */ - uint8_t pgm_tdb[256]; /* 0x1800 */ - - /* align to the top of the prefix area */ - uint8_t pad_0x1900[0x2000-0x1900]; /* 0x1900 */ -} __packed __aligned(8192); - -#define S390_lowcore (*((struct _lowcore *) 0)) - -#define __LC_IPLDEV 0x0c6c -#define __LC_OS_INFO 0x0e18 - -#define PAGE_SIZE 4096 - -void panic_notify(unsigned long reason); - -#define panic(reason, x...) \ -do { \ - printf(x); \ - panic_notify(reason); \ - libc_stop(reason); \ -} while (0) - -static __always_inline int page_is_valid(unsigned long addr) -{ - unsigned long tmp; - int rc; - - asm volatile( - "0: ic %1,%2\n" - "1: lhi %0,1\n" - "2:\n" - ".pushsection .fixup, \"ax\"\n" - "3: xr %0,%0\n" - " jg 2b\n" - ".popsection\n" - EX_TABLE(0b, 3b) EX_TABLE(1b, 3b) - : "=d" (rc), "=d" (tmp) - : "Q" (*(unsigned long *) addr) - : "cc"); - return rc; -} - -static __always_inline uint32_t csum_partial(const void *buf, int len, uint32_t sum) -{ - register unsigned long reg2 asm("2") = (unsigned long) buf; - register unsigned long reg3 asm("3") = (unsigned long) len; - - asm volatile( - "0: cksm %0,%1\n" /* do checksum on longs */ - " jo 0b\n" - : "+d" (sum), "+d" (reg2), "+d" (reg3) : : "cc", "memory"); - return sum; -} - -#define __ctl_store(array, low, high) ({ \ - typedef struct { char _[sizeof(array)]; } __may_alias addrtype;\ - asm volatile( \ - " stctg %1,%2,%0\n" \ - : "=Q" (*(addrtype *)(&array)) \ - : "i" (low), "i" (high)); \ -}) - -#define __ctl_load(array, low, high) ({ \ - typedef struct { char _[sizeof(array)]; } __may_alias addrtype; \ - asm volatile( \ - " lctlg %1,%2,%0\n" \ - : : "Q" (*(addrtype *)(&array)), \ - "i" (low), "i" (high)); \ -}) - -static __always_inline void __ctl_set_bit(unsigned int cr, unsigned int bit) -{ - unsigned long reg; - - __ctl_store(reg, cr, cr); - reg |= 1UL << bit; - __ctl_load(reg, cr, cr); -} - -/* - * DIAG 308 support - */ -enum diag308_subcode { - DIAG308_REL_HSA = 2, - DIAG308_IPL = 3, - DIAG308_DUMP = 4, - DIAG308_SET = 5, - DIAG308_STORE = 6, -}; - -static __always_inline int diag308(unsigned long subcode, void *addr) -{ - register unsigned long _addr asm("0") = (unsigned long) addr; - register unsigned long _rc asm("1") = 0; - - asm volatile( - " diag %0,%2,0x308\n" - "0:\n" - : "+d" (_addr), "+d" (_rc) - : "d" (subcode) : "cc", "memory"); - return _rc; -} - -/* - * Store CPU address - */ -static __always_inline unsigned short stap(void) -{ - unsigned short cpu_address; - - asm volatile("stap %0" : "=m" (cpu_address)); - return cpu_address; -} - -/* - * Program the clock comparator - */ -static __always_inline void set_clock_comparator(uint64_t time) -{ - asm volatile("sckc %0" : : "Q" (time)); -} - -/* - * Program the CPU timer - */ -static __always_inline void set_cpu_timer(uint64_t timer) -{ - asm volatile("spt %0" : : "Q" (timer)); -} - -/* - * Get current time (store clock) - */ -static __always_inline unsigned long long get_tod_clock(void) -{ - unsigned long long clk; - - asm volatile("stck %0" : "=Q" (clk) : : "cc"); - return clk; -} - -/* - * Get ID of current CPU - */ -struct cpuid { - unsigned int version:8; - unsigned int ident:24; - unsigned int machine:16; - unsigned int unused:16; -} __packed __aligned(8); - -static __always_inline void get_cpu_id(struct cpuid *ptr) -{ - asm volatile("stidp %0" : "=Q" (*ptr)); -} - -/* - * Check if we run under z/VM - */ -static __always_inline int is_zvm(void) -{ - struct cpuid cpuid; - - get_cpu_id(&cpuid); - return cpuid.version == 0xff; -} - -/* - * Vector register definition - */ -typedef struct { - uint32_t u[4]; -} __vector128; - -/* - * Save vector registers - */ -static __always_inline void save_vx_regs(__vector128 *vxrs) -{ - typedef struct { __vector128 _[32]; } addrtype; - - asm volatile( - " la 1,%0\n" - " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */ - " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */ - : "=Q" (*(addrtype *) vxrs) : : "1"); -} - -/* - * Save vector registers safe - */ -static __always_inline void save_vx_regs_safe(__vector128 *vxrs) -{ - unsigned long cr0; - - __ctl_store(cr0, 0, 0); - __ctl_set_bit(0, 17); - __ctl_set_bit(0, 18); /* AFP-register-control */ - save_vx_regs(vxrs); - __ctl_load(cr0, 0, 0); -} - -#define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */ - -static __always_inline int __test_facility(unsigned long nr, void *facilities) -{ - unsigned char *ptr; - - if (nr >= MAX_FACILITY_BIT) - return 0; - ptr = (unsigned char *) facilities + (nr >> 3); - return (*ptr & (0x80 >> (nr & 7))) != 0; -} - -/* - * The test_facility function uses the bit odering where the MSB is bit 0. - * That makes it easier to query facility bits with the bit number as - * documented in the Principles of Operation. - */ -static __always_inline int test_facility(unsigned long nr) -{ - return __test_facility(nr, &S390_lowcore.stfle_fac_list); -} - -static __always_inline unsigned long __stfle_asm(uint64_t *stfle_fac_list, int size) -{ - register unsigned long reg0 asm("0") = size - 1; - - asm volatile( - ".insn s,0xb2b00000,0(%1)" /* stfle */ - : "+d" (reg0) - : "a" (stfle_fac_list) - : "memory", "cc"); - return reg0; -} - -/** - * stfle - Store facility list extended - * @stfle_fac_list: array where facility list can be stored - * @size: size of passed in array in double words - */ -static __always_inline void stfle(uint64_t *stfle_fac_list, int size) -{ - unsigned long nr; - - asm volatile( - " .insn s,0xb2b10000,0(0)\n" /* stfl */ - "0:\n" - EX_TABLE(0b, 0b) - : "+m" (S390_lowcore.stfl_fac_list)); - nr = 4; /* bytes stored by stfl */ - memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); - if (S390_lowcore.stfl_fac_list & 0x01000000) { - /* More facility bits available with stfle */ - nr = __stfle_asm(stfle_fac_list, size); - nr = MIN((nr + 1) * 8, size * 8UL); - } - memset((char *) stfle_fac_list + nr, 0, size * 8 - nr); -} - -#endif /* S390_H */ --- a/zipl/boot/sclp.c +++ b/zipl/boot/sclp.c @@ -11,7 +11,7 @@ #include "libc.h" #include "error.h" -#include "s390.h" +#include "boot/s390.h" #include "sclp.h" /* Perform service call. Return 0 on success, non-zero otherwise. */ --- a/zipl/boot/sclp.h +++ b/zipl/boot/sclp.h @@ -13,7 +13,7 @@ #define SCLP_H #include "libc.h" -#include "s390.h" +#include "boot/s390.h" /* vector keys and ids */ #define GDS_ID_MDSMU 0x1310 --- a/zipl/boot/stage2.c +++ b/zipl/boot/stage2.c @@ -14,7 +14,7 @@ #include "error.h" #include "libc.h" #include "menu.h" -#include "s390.h" +#include "boot/s390.h" #include "stage2.h" static int is_null_descriptor(disk_blockptr_t *address) --- a/zipl/boot/stage2.h +++ b/zipl/boot/stage2.h @@ -15,7 +15,7 @@ #include "cio.h" #include "error.h" #include "libc.h" -#include "s390.h" +#include "boot/s390.h" #define DESCR_PER_BLOCK 16 @@ -76,4 +76,3 @@ void kdump_stage2(unsigned long); #endif /* COMMON_H */ - --- a/zipl/boot/stage2dump.h +++ b/zipl/boot/stage2dump.h @@ -13,7 +13,7 @@ #define STAGE2DUMP_H #include "libc.h" -#include "s390.h" +#include "boot/s390.h" #define IPL_SC *((struct subchannel_id *) &S390_lowcore.subchannel_id) #define ROUND_DOWN(x, a) ((x) & ~((typeof(x))(a) - 1)) --- a/zipl/boot/stage3.c +++ b/zipl/boot/stage3.c @@ -11,7 +11,7 @@ #include "libc.h" #include "boot/sigp.h" -#include "s390.h" +#include "boot/s390.h" #include "stage3.h" #include "error.h" #include "zipl.h" --- a/zipl/boot/stage3.h +++ b/zipl/boot/stage3.h @@ -13,8 +13,8 @@ #define STAGE3_H #include "libc.h" -#include "s390.h" +#include "boot/s390.h" #include "boot/ipl.h" #include "boot/linux_layout.h"
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor