1c9c39d3bSAlexander Graf /* 2c9c39d3bSAlexander Graf * S390 CCW boot loader 3c9c39d3bSAlexander Graf * 4c9c39d3bSAlexander Graf * Copyright (c) 2013 Alexander Graf <agraf@suse.de> 5c9c39d3bSAlexander Graf * 6c9c39d3bSAlexander Graf * This work is licensed under the terms of the GNU GPL, version 2 or (at 7c9c39d3bSAlexander Graf * your option) any later version. See the COPYING file in the top-level 8c9c39d3bSAlexander Graf * directory. 9c9c39d3bSAlexander Graf */ 10c9c39d3bSAlexander Graf 11c9c39d3bSAlexander Graf #ifndef S390_CCW_H 12c9c39d3bSAlexander Graf #define S390_CCW_H 13c9c39d3bSAlexander Graf 14c9c39d3bSAlexander Graf /* #define DEBUG */ 15c9c39d3bSAlexander Graf 169f427883SJared Rossi #include <stdbool.h> 179f427883SJared Rossi #include <stddef.h> 189f427883SJared Rossi #include <stdint.h> 199f427883SJared Rossi #include <stdio.h> 209f427883SJared Rossi 21c9c39d3bSAlexander Graf typedef unsigned char u8; 22c9c39d3bSAlexander Graf typedef unsigned short u16; 23c9c39d3bSAlexander Graf typedef unsigned int u32; 24c9c39d3bSAlexander Graf typedef unsigned long long u64; 25c9c39d3bSAlexander Graf 26c9c39d3bSAlexander Graf #define true 1 27c9c39d3bSAlexander Graf #define false 0 28c9c39d3bSAlexander Graf #define PAGE_SIZE 4096 29c9c39d3bSAlexander Graf 30c9c39d3bSAlexander Graf #define EIO 1 31c9c39d3bSAlexander Graf #define EBUSY 2 32f3180b02SThomas Huth #define ENODEV 3 33bef2b8ddSJared Rossi #define EINVAL 4 34f3180b02SThomas Huth 355ffd4a3cSEric Farman #ifndef MIN 365ffd4a3cSEric Farman #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 375ffd4a3cSEric Farman #endif 385ffd4a3cSEric Farman #ifndef MIN_NON_ZERO 395ffd4a3cSEric Farman #define MIN_NON_ZERO(a, b) ((a) == 0 ? (b) : \ 405ffd4a3cSEric Farman ((b) == 0 ? (a) : (MIN(a, b)))) 415ffd4a3cSEric Farman #endif 42c9c39d3bSAlexander Graf 4359efbff1SThomas Huth #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 4459efbff1SThomas Huth 45c9c39d3bSAlexander Graf #include "cio.h" 46d046c51dSAlexander Yarygin #include "iplb.h" 47c9c39d3bSAlexander Graf 487f61cbc1SChristian Borntraeger /* start.s */ 49add923b7SJanosch Frank void disabled_wait(void) __attribute__ ((__noreturn__)); 50bdc7fe36SChristian Borntraeger void consume_sclp_int(void); 513083a1bbSJason J. Herne void consume_io_int(void); 527f61cbc1SChristian Borntraeger 53c9c39d3bSAlexander Graf /* main.c */ 54f2879a5cSChristian Borntraeger void write_subsystem_identification(void); 559bfc04f9SJanosch Frank void write_iplb_location(void); 5695fa1af8SFarhan Ali unsigned int get_loadparm_index(void); 572ba3cc47SThomas Huth void main(void); 58c9c39d3bSAlexander Graf 598e5739ceSJared Rossi /* netmain.c */ 60*f1a2a6e4SJared Rossi int netmain(void); 618e5739ceSJared Rossi 629a22473cSFarhan Ali /* sclp.c */ 63c9c39d3bSAlexander Graf void sclp_print(const char *string); 64dbf2091aSCollin L. Walling void sclp_set_write_mask(uint32_t receive_mask, uint32_t send_mask); 65c9c39d3bSAlexander Graf void sclp_setup(void); 669a22473cSFarhan Ali void sclp_get_loadparm_ascii(char *loadparm); 67ff5dbf1bSCollin L. Walling int sclp_read(char *str, size_t count); 68c9c39d3bSAlexander Graf 69c9c39d3bSAlexander Graf /* virtio.c */ 70f7f2f96fSJuan Quintela unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list2, 71f7f2f96fSJuan Quintela unsigned long subchan_id, void *load_addr); 72a1102cebSEugene (jno) Dvurechenski bool virtio_is_supported(SubChannelId schid); 73605751b5SThomas Huth int virtio_blk_setup_device(SubChannelId schid); 74f7f2f96fSJuan Quintela int virtio_read(unsigned long sector, void *load_addr); 75c9c39d3bSAlexander Graf 76c9c39d3bSAlexander Graf /* bootmap.c */ 7760612d5cSEugene (jno) Dvurechenski void zipl_load(void); 78c9c39d3bSAlexander Graf 799a848adfSThomas Huth /* jump2ipl.c */ 8042ab98e7SJanosch Frank void write_reset_psw(uint64_t psw); 819a848adfSThomas Huth void jump_to_IPL_code(uint64_t address); 829a848adfSThomas Huth void jump_to_low_kernel(void); 839a848adfSThomas Huth 849eaa654aSCollin L. Walling /* menu.c */ 859eaa654aSCollin L. Walling void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout); 86ba831b25SCollin L. Walling int menu_get_zipl_boot_index(const char *menu_data); 87ba831b25SCollin L. Walling bool menu_is_enabled_zipl(void); 88622b3917SCollin Walling int menu_get_enum_boot_index(bool *valid_entries); 89ffb4a1c8SCollin L. Walling bool menu_is_enabled_enum(void); 909eaa654aSCollin L. Walling 916df2a829SCollin Walling #define MAX_BOOT_ENTRIES 31 926df2a829SCollin Walling 93679196a6SThomas Huth __attribute__ ((__noreturn__)) 94add923b7SJanosch Frank static inline void panic(const char *string) 95add923b7SJanosch Frank { 969f427883SJared Rossi printf("ERROR: %s\n ", string); 97add923b7SJanosch Frank disabled_wait(); 98add923b7SJanosch Frank } 99add923b7SJanosch Frank 100c9c39d3bSAlexander Graf static inline void fill_hex(char *out, unsigned char val) 101c9c39d3bSAlexander Graf { 102c9c39d3bSAlexander Graf const char hex[] = "0123456789abcdef"; 103c9c39d3bSAlexander Graf 104c9c39d3bSAlexander Graf out[0] = hex[(val >> 4) & 0xf]; 105c9c39d3bSAlexander Graf out[1] = hex[val & 0xf]; 106c9c39d3bSAlexander Graf } 107c9c39d3bSAlexander Graf 108058cc1f3SEugene (jno) Dvurechenski static inline void fill_hex_val(char *out, void *ptr, unsigned size) 109c9c39d3bSAlexander Graf { 110058cc1f3SEugene (jno) Dvurechenski unsigned char *value = ptr; 111c9c39d3bSAlexander Graf unsigned int i; 112c9c39d3bSAlexander Graf 113058cc1f3SEugene (jno) Dvurechenski for (i = 0; i < size; i++) { 114058cc1f3SEugene (jno) Dvurechenski fill_hex(&out[i*2], value[i]); 115c9c39d3bSAlexander Graf } 116058cc1f3SEugene (jno) Dvurechenski } 117058cc1f3SEugene (jno) Dvurechenski 118c9c39d3bSAlexander Graf static inline void debug_print_int(const char *desc, u64 addr) 119c9c39d3bSAlexander Graf { 120c9c39d3bSAlexander Graf #ifdef DEBUG 1219f427883SJared Rossi printf("%s 0x%X\n", desc, addr); 122c9c39d3bSAlexander Graf #endif 123c9c39d3bSAlexander Graf } 124c9c39d3bSAlexander Graf 125c9c39d3bSAlexander Graf static inline void debug_print_addr(const char *desc, void *p) 126c9c39d3bSAlexander Graf { 127c9c39d3bSAlexander Graf #ifdef DEBUG 128c9c39d3bSAlexander Graf debug_print_int(desc, (unsigned int)(unsigned long)p); 129c9c39d3bSAlexander Graf #endif 130c9c39d3bSAlexander Graf } 131c9c39d3bSAlexander Graf 132c9c39d3bSAlexander Graf /*********************************************** 133c9c39d3bSAlexander Graf * Hypercall functions * 134c9c39d3bSAlexander Graf ***********************************************/ 135c9c39d3bSAlexander Graf 136c9c39d3bSAlexander Graf #define KVM_S390_VIRTIO_NOTIFY 0 137c9c39d3bSAlexander Graf #define KVM_S390_VIRTIO_RESET 1 138c9c39d3bSAlexander Graf #define KVM_S390_VIRTIO_SET_STATUS 2 139c9c39d3bSAlexander Graf #define KVM_S390_VIRTIO_CCW_NOTIFY 3 140c9c39d3bSAlexander Graf 14191a03f9bSEugene (jno) Dvurechenski #define MAX_SECTOR_SIZE 4096 142c9c39d3bSAlexander Graf 143dc25e843SEugene (jno) Dvurechenski static inline void IPL_assert(bool term, const char *message) 144dc25e843SEugene (jno) Dvurechenski { 145dc25e843SEugene (jno) Dvurechenski if (!term) { 1469f427883SJared Rossi panic(message); /* no return */ 147dc25e843SEugene (jno) Dvurechenski } 148dc25e843SEugene (jno) Dvurechenski } 149dc25e843SEugene (jno) Dvurechenski 150dc25e843SEugene (jno) Dvurechenski static inline void IPL_check(bool term, const char *message) 151dc25e843SEugene (jno) Dvurechenski { 152dc25e843SEugene (jno) Dvurechenski if (!term) { 1539f427883SJared Rossi printf("WARNING: %s\n", message); 154dc25e843SEugene (jno) Dvurechenski } 155dc25e843SEugene (jno) Dvurechenski } 156dc25e843SEugene (jno) Dvurechenski 157cfe2124aSEugene (jno) Dvurechenski extern const unsigned char ebc2asc[256]; 158cfe2124aSEugene (jno) Dvurechenski static inline void ebcdic_to_ascii(const char *src, 159cfe2124aSEugene (jno) Dvurechenski char *dst, 160cfe2124aSEugene (jno) Dvurechenski unsigned int size) 161cfe2124aSEugene (jno) Dvurechenski { 162cfe2124aSEugene (jno) Dvurechenski unsigned int i; 163cfe2124aSEugene (jno) Dvurechenski 164cfe2124aSEugene (jno) Dvurechenski for (i = 0; i < size; i++) { 165cfe2124aSEugene (jno) Dvurechenski unsigned c = src[i]; 166cfe2124aSEugene (jno) Dvurechenski dst[i] = ebc2asc[c]; 167cfe2124aSEugene (jno) Dvurechenski } 168cfe2124aSEugene (jno) Dvurechenski } 169cfe2124aSEugene (jno) Dvurechenski 170c9c39d3bSAlexander Graf #endif /* S390_CCW_H */ 171