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 */
60f1a2a6e4SJared 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);
81*0181e237SJared Rossi int 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__))
panic(const char * string)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
fill_hex(char * out,unsigned char val)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
fill_hex_val(char * out,void * ptr,unsigned size)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
debug_print_int(const char * desc,u64 addr)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
debug_print_addr(const char * desc,void * p)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
IPL_assert(bool term,const char * message)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
IPL_check(bool term,const char * message)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];
ebcdic_to_ascii(const char * src,char * dst,unsigned int size)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