xref: /openbmc/qemu/pc-bios/s390-ccw/s390-ccw.h (revision e31f08dc)
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 
16c9c39d3bSAlexander Graf typedef unsigned char      u8;
17c9c39d3bSAlexander Graf typedef unsigned short     u16;
18c9c39d3bSAlexander Graf typedef unsigned int       u32;
19c9c39d3bSAlexander Graf typedef unsigned long long u64;
20c9c39d3bSAlexander Graf 
21c9c39d3bSAlexander Graf #define true 1
22c9c39d3bSAlexander Graf #define false 0
23c9c39d3bSAlexander Graf #define PAGE_SIZE 4096
24c9c39d3bSAlexander Graf 
25c9c39d3bSAlexander Graf #define EIO     1
26c9c39d3bSAlexander Graf #define EBUSY   2
27f3180b02SThomas Huth #define ENODEV  3
28f3180b02SThomas Huth 
29c9c39d3bSAlexander Graf #ifndef NULL
30c9c39d3bSAlexander Graf #define NULL    0
31c9c39d3bSAlexander Graf #endif
325ffd4a3cSEric Farman #ifndef MIN
335ffd4a3cSEric Farman #define MIN(a, b) (((a) < (b)) ? (a) : (b))
345ffd4a3cSEric Farman #endif
355ffd4a3cSEric Farman #ifndef MIN_NON_ZERO
365ffd4a3cSEric Farman #define MIN_NON_ZERO(a, b) ((a) == 0 ? (b) : \
375ffd4a3cSEric Farman                             ((b) == 0 ? (a) : (MIN(a, b))))
385ffd4a3cSEric Farman #endif
39c9c39d3bSAlexander Graf 
4059efbff1SThomas Huth #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
4159efbff1SThomas Huth 
42c9c39d3bSAlexander Graf #include "cio.h"
43d046c51dSAlexander Yarygin #include "iplb.h"
44c9c39d3bSAlexander Graf 
457f61cbc1SChristian Borntraeger /* start.s */
46add923b7SJanosch Frank void disabled_wait(void) __attribute__ ((__noreturn__));
47bdc7fe36SChristian Borntraeger void consume_sclp_int(void);
483083a1bbSJason J. Herne void consume_io_int(void);
497f61cbc1SChristian Borntraeger 
50c9c39d3bSAlexander Graf /* main.c */
51f2879a5cSChristian Borntraeger void write_subsystem_identification(void);
529bfc04f9SJanosch Frank void write_iplb_location(void);
5395fa1af8SFarhan Ali unsigned int get_loadparm_index(void);
542ba3cc47SThomas Huth void main(void);
55c9c39d3bSAlexander Graf 
569a22473cSFarhan Ali /* sclp.c */
57c9c39d3bSAlexander Graf void sclp_print(const char *string);
58dbf2091aSCollin L. Walling void sclp_set_write_mask(uint32_t receive_mask, uint32_t send_mask);
59c9c39d3bSAlexander Graf void sclp_setup(void);
609a22473cSFarhan Ali void sclp_get_loadparm_ascii(char *loadparm);
61ff5dbf1bSCollin L. Walling int sclp_read(char *str, size_t count);
62c9c39d3bSAlexander Graf 
63c9c39d3bSAlexander Graf /* virtio.c */
64*f7f2f96fSJuan Quintela unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list2,
65*f7f2f96fSJuan Quintela                                  unsigned long subchan_id, void *load_addr);
66a1102cebSEugene (jno) Dvurechenski bool virtio_is_supported(SubChannelId schid);
67605751b5SThomas Huth int virtio_blk_setup_device(SubChannelId schid);
68*f7f2f96fSJuan Quintela int virtio_read(unsigned long sector, void *load_addr);
69c9c39d3bSAlexander Graf 
70c9c39d3bSAlexander Graf /* bootmap.c */
7160612d5cSEugene (jno) Dvurechenski void zipl_load(void);
72c9c39d3bSAlexander Graf 
739a848adfSThomas Huth /* jump2ipl.c */
7442ab98e7SJanosch Frank void write_reset_psw(uint64_t psw);
759a848adfSThomas Huth void jump_to_IPL_code(uint64_t address);
769a848adfSThomas Huth void jump_to_low_kernel(void);
779a848adfSThomas Huth 
789eaa654aSCollin L. Walling /* menu.c */
799eaa654aSCollin L. Walling void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout);
80ba831b25SCollin L. Walling int menu_get_zipl_boot_index(const char *menu_data);
81ba831b25SCollin L. Walling bool menu_is_enabled_zipl(void);
82622b3917SCollin Walling int menu_get_enum_boot_index(bool *valid_entries);
83ffb4a1c8SCollin L. Walling bool menu_is_enabled_enum(void);
849eaa654aSCollin L. Walling 
856df2a829SCollin Walling #define MAX_BOOT_ENTRIES  31
866df2a829SCollin Walling 
87679196a6SThomas Huth __attribute__ ((__noreturn__))
panic(const char * string)88add923b7SJanosch Frank static inline void panic(const char *string)
89add923b7SJanosch Frank {
90add923b7SJanosch Frank     sclp_print(string);
91add923b7SJanosch Frank     disabled_wait();
92add923b7SJanosch Frank }
93add923b7SJanosch Frank 
fill_hex(char * out,unsigned char val)94c9c39d3bSAlexander Graf static inline void fill_hex(char *out, unsigned char val)
95c9c39d3bSAlexander Graf {
96c9c39d3bSAlexander Graf     const char hex[] = "0123456789abcdef";
97c9c39d3bSAlexander Graf 
98c9c39d3bSAlexander Graf     out[0] = hex[(val >> 4) & 0xf];
99c9c39d3bSAlexander Graf     out[1] = hex[val & 0xf];
100c9c39d3bSAlexander Graf }
101c9c39d3bSAlexander Graf 
fill_hex_val(char * out,void * ptr,unsigned size)102058cc1f3SEugene (jno) Dvurechenski static inline void fill_hex_val(char *out, void *ptr, unsigned size)
103c9c39d3bSAlexander Graf {
104058cc1f3SEugene (jno) Dvurechenski     unsigned char *value = ptr;
105c9c39d3bSAlexander Graf     unsigned int i;
106c9c39d3bSAlexander Graf 
107058cc1f3SEugene (jno) Dvurechenski     for (i = 0; i < size; i++) {
108058cc1f3SEugene (jno) Dvurechenski         fill_hex(&out[i*2], value[i]);
109c9c39d3bSAlexander Graf     }
110058cc1f3SEugene (jno) Dvurechenski }
111058cc1f3SEugene (jno) Dvurechenski 
print_int(const char * desc,u64 addr)112058cc1f3SEugene (jno) Dvurechenski static inline void print_int(const char *desc, u64 addr)
113058cc1f3SEugene (jno) Dvurechenski {
114058cc1f3SEugene (jno) Dvurechenski     char out[] = ": 0xffffffffffffffff\n";
115058cc1f3SEugene (jno) Dvurechenski 
116058cc1f3SEugene (jno) Dvurechenski     fill_hex_val(&out[4], &addr, sizeof(addr));
117c9c39d3bSAlexander Graf 
118c9c39d3bSAlexander Graf     sclp_print(desc);
119c9c39d3bSAlexander Graf     sclp_print(out);
120c9c39d3bSAlexander Graf }
121c9c39d3bSAlexander Graf 
debug_print_int(const char * desc,u64 addr)122c9c39d3bSAlexander Graf static inline void debug_print_int(const char *desc, u64 addr)
123c9c39d3bSAlexander Graf {
124c9c39d3bSAlexander Graf #ifdef DEBUG
125c9c39d3bSAlexander Graf     print_int(desc, addr);
126c9c39d3bSAlexander Graf #endif
127c9c39d3bSAlexander Graf }
128c9c39d3bSAlexander Graf 
debug_print_addr(const char * desc,void * p)129c9c39d3bSAlexander Graf static inline void debug_print_addr(const char *desc, void *p)
130c9c39d3bSAlexander Graf {
131c9c39d3bSAlexander Graf #ifdef DEBUG
132c9c39d3bSAlexander Graf     debug_print_int(desc, (unsigned int)(unsigned long)p);
133c9c39d3bSAlexander Graf #endif
134c9c39d3bSAlexander Graf }
135c9c39d3bSAlexander Graf 
136c9c39d3bSAlexander Graf /***********************************************
137c9c39d3bSAlexander Graf  *           Hypercall functions               *
138c9c39d3bSAlexander Graf  ***********************************************/
139c9c39d3bSAlexander Graf 
140c9c39d3bSAlexander Graf #define KVM_S390_VIRTIO_NOTIFY          0
141c9c39d3bSAlexander Graf #define KVM_S390_VIRTIO_RESET           1
142c9c39d3bSAlexander Graf #define KVM_S390_VIRTIO_SET_STATUS      2
143c9c39d3bSAlexander Graf #define KVM_S390_VIRTIO_CCW_NOTIFY      3
144c9c39d3bSAlexander Graf 
14591a03f9bSEugene (jno) Dvurechenski #define MAX_SECTOR_SIZE 4096
146c9c39d3bSAlexander Graf 
IPL_assert(bool term,const char * message)147dc25e843SEugene (jno) Dvurechenski static inline void IPL_assert(bool term, const char *message)
148dc25e843SEugene (jno) Dvurechenski {
149dc25e843SEugene (jno) Dvurechenski     if (!term) {
150dc25e843SEugene (jno) Dvurechenski         sclp_print("\n! ");
151dc25e843SEugene (jno) Dvurechenski         sclp_print(message);
152dc25e843SEugene (jno) Dvurechenski         panic(" !\n"); /* no return */
153dc25e843SEugene (jno) Dvurechenski     }
154dc25e843SEugene (jno) Dvurechenski }
155dc25e843SEugene (jno) Dvurechenski 
IPL_check(bool term,const char * message)156dc25e843SEugene (jno) Dvurechenski static inline void IPL_check(bool term, const char *message)
157dc25e843SEugene (jno) Dvurechenski {
158dc25e843SEugene (jno) Dvurechenski     if (!term) {
159dc25e843SEugene (jno) Dvurechenski         sclp_print("\n! WARNING: ");
160dc25e843SEugene (jno) Dvurechenski         sclp_print(message);
161dc25e843SEugene (jno) Dvurechenski         sclp_print(" !\n");
162dc25e843SEugene (jno) Dvurechenski     }
163dc25e843SEugene (jno) Dvurechenski }
164dc25e843SEugene (jno) Dvurechenski 
165cfe2124aSEugene (jno) Dvurechenski extern const unsigned char ebc2asc[256];
ebcdic_to_ascii(const char * src,char * dst,unsigned int size)166cfe2124aSEugene (jno) Dvurechenski static inline void ebcdic_to_ascii(const char *src,
167cfe2124aSEugene (jno) Dvurechenski                                    char *dst,
168cfe2124aSEugene (jno) Dvurechenski                                    unsigned int size)
169cfe2124aSEugene (jno) Dvurechenski {
170cfe2124aSEugene (jno) Dvurechenski     unsigned int i;
171cfe2124aSEugene (jno) Dvurechenski 
172cfe2124aSEugene (jno) Dvurechenski     for (i = 0; i < size; i++) {
173cfe2124aSEugene (jno) Dvurechenski         unsigned c = src[i];
174cfe2124aSEugene (jno) Dvurechenski         dst[i] = ebc2asc[c];
175cfe2124aSEugene (jno) Dvurechenski     }
176cfe2124aSEugene (jno) Dvurechenski }
177cfe2124aSEugene (jno) Dvurechenski 
178c9c39d3bSAlexander Graf #endif /* S390_CCW_H */
179