]>
Commit | Line | Data |
---|---|---|
c9c39d3b AG |
1 | /* |
2 | * S390 CCW boot loader | |
3 | * | |
4 | * Copyright (c) 2013 Alexander Graf <agraf@suse.de> | |
5 | * | |
6 | * This work is licensed under the terms of the GNU GPL, version 2 or (at | |
7 | * your option) any later version. See the COPYING file in the top-level | |
8 | * directory. | |
9 | */ | |
10 | ||
11 | #ifndef S390_CCW_H | |
12 | #define S390_CCW_H | |
13 | ||
14 | /* #define DEBUG */ | |
15 | ||
16 | typedef unsigned char u8; | |
17 | typedef unsigned short u16; | |
18 | typedef unsigned int u32; | |
19 | typedef unsigned long long u64; | |
20 | typedef unsigned long ulong; | |
c9c39d3b AG |
21 | typedef unsigned char __u8; |
22 | typedef unsigned short __u16; | |
23 | typedef unsigned int __u32; | |
24 | typedef unsigned long long __u64; | |
25 | ||
26 | #define true 1 | |
27 | #define false 0 | |
28 | #define PAGE_SIZE 4096 | |
29 | ||
30 | #ifndef EIO | |
abd696e4 | 31 | #define EIO 1 |
c9c39d3b AG |
32 | #endif |
33 | #ifndef EBUSY | |
abd696e4 | 34 | #define EBUSY 2 |
c9c39d3b AG |
35 | #endif |
36 | #ifndef NULL | |
37 | #define NULL 0 | |
38 | #endif | |
5ffd4a3c EF |
39 | #ifndef MIN |
40 | #define MIN(a, b) (((a) < (b)) ? (a) : (b)) | |
41 | #endif | |
42 | #ifndef MIN_NON_ZERO | |
43 | #define MIN_NON_ZERO(a, b) ((a) == 0 ? (b) : \ | |
44 | ((b) == 0 ? (a) : (MIN(a, b)))) | |
45 | #endif | |
c9c39d3b | 46 | |
59efbff1 TH |
47 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) |
48 | ||
c9c39d3b | 49 | #include "cio.h" |
d046c51d | 50 | #include "iplb.h" |
c9c39d3b | 51 | |
b88d7fa5 ED |
52 | typedef struct irb Irb; |
53 | typedef struct ccw1 Ccw1; | |
54 | typedef struct cmd_orb CmdOrb; | |
55 | typedef struct schib Schib; | |
56 | typedef struct chsc_area_sda ChscAreaSda; | |
57 | typedef struct senseid SenseId; | |
58 | typedef struct subchannel_id SubChannelId; | |
59 | ||
7f61cbc1 CB |
60 | /* start.s */ |
61 | void disabled_wait(void); | |
bdc7fe36 | 62 | void consume_sclp_int(void); |
7f61cbc1 | 63 | |
c9c39d3b | 64 | /* main.c */ |
c9262e8a | 65 | void panic(const char *string); |
f2879a5c | 66 | void write_subsystem_identification(void); |
f17a8430 | 67 | extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); |
95fa1af8 | 68 | unsigned int get_loadparm_index(void); |
c9c39d3b | 69 | |
9a22473c | 70 | /* sclp.c */ |
c9c39d3b | 71 | void sclp_print(const char *string); |
dbf2091a | 72 | void sclp_set_write_mask(uint32_t receive_mask, uint32_t send_mask); |
c9c39d3b | 73 | void sclp_setup(void); |
9a22473c | 74 | void sclp_get_loadparm_ascii(char *loadparm); |
ff5dbf1b | 75 | int sclp_read(char *str, size_t count); |
c9c39d3b AG |
76 | |
77 | /* virtio.c */ | |
78 | unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2, | |
abd696e4 | 79 | ulong subchan_id, void *load_addr); |
a1102ceb | 80 | bool virtio_is_supported(SubChannelId schid); |
867e039a | 81 | void virtio_blk_setup_device(SubChannelId schid); |
c9c39d3b | 82 | int virtio_read(ulong sector, void *load_addr); |
c8cda874 | 83 | int enable_mss_facility(void); |
ff5dbf1b | 84 | u64 get_clock(void); |
dc25e843 | 85 | ulong get_second(void); |
c9c39d3b AG |
86 | |
87 | /* bootmap.c */ | |
60612d5c | 88 | void zipl_load(void); |
c9c39d3b | 89 | |
9a848adf TH |
90 | /* jump2ipl.c */ |
91 | void jump_to_IPL_code(uint64_t address); | |
92 | void jump_to_low_kernel(void); | |
93 | ||
9eaa654a CW |
94 | /* menu.c */ |
95 | void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout); | |
ba831b25 CW |
96 | int menu_get_zipl_boot_index(const char *menu_data); |
97 | bool menu_is_enabled_zipl(void); | |
622b3917 | 98 | int menu_get_enum_boot_index(bool *valid_entries); |
ffb4a1c8 | 99 | bool menu_is_enabled_enum(void); |
9eaa654a | 100 | |
6df2a829 CW |
101 | #define MAX_BOOT_ENTRIES 31 |
102 | ||
c9c39d3b AG |
103 | static inline void fill_hex(char *out, unsigned char val) |
104 | { | |
105 | const char hex[] = "0123456789abcdef"; | |
106 | ||
107 | out[0] = hex[(val >> 4) & 0xf]; | |
108 | out[1] = hex[val & 0xf]; | |
109 | } | |
110 | ||
058cc1f3 | 111 | static inline void fill_hex_val(char *out, void *ptr, unsigned size) |
c9c39d3b | 112 | { |
058cc1f3 | 113 | unsigned char *value = ptr; |
c9c39d3b AG |
114 | unsigned int i; |
115 | ||
058cc1f3 ED |
116 | for (i = 0; i < size; i++) { |
117 | fill_hex(&out[i*2], value[i]); | |
c9c39d3b | 118 | } |
058cc1f3 ED |
119 | } |
120 | ||
121 | static inline void print_int(const char *desc, u64 addr) | |
122 | { | |
123 | char out[] = ": 0xffffffffffffffff\n"; | |
124 | ||
125 | fill_hex_val(&out[4], &addr, sizeof(addr)); | |
c9c39d3b AG |
126 | |
127 | sclp_print(desc); | |
128 | sclp_print(out); | |
129 | } | |
130 | ||
131 | static inline void debug_print_int(const char *desc, u64 addr) | |
132 | { | |
133 | #ifdef DEBUG | |
134 | print_int(desc, addr); | |
135 | #endif | |
136 | } | |
137 | ||
138 | static inline void debug_print_addr(const char *desc, void *p) | |
139 | { | |
140 | #ifdef DEBUG | |
141 | debug_print_int(desc, (unsigned int)(unsigned long)p); | |
142 | #endif | |
143 | } | |
144 | ||
145 | /*********************************************** | |
146 | * Hypercall functions * | |
147 | ***********************************************/ | |
148 | ||
abd696e4 ED |
149 | #define KVM_S390_VIRTIO_NOTIFY 0 |
150 | #define KVM_S390_VIRTIO_RESET 1 | |
151 | #define KVM_S390_VIRTIO_SET_STATUS 2 | |
c9c39d3b AG |
152 | #define KVM_S390_VIRTIO_CCW_NOTIFY 3 |
153 | ||
154 | static inline void yield(void) | |
155 | { | |
abd696e4 ED |
156 | asm volatile ("diag 0,0,0x44" |
157 | : : | |
158 | : "memory", "cc"); | |
c9c39d3b AG |
159 | } |
160 | ||
91a03f9b | 161 | #define MAX_SECTOR_SIZE 4096 |
c9c39d3b | 162 | |
dc25e843 ED |
163 | static inline void sleep(unsigned int seconds) |
164 | { | |
165 | ulong target = get_second() + seconds; | |
166 | ||
167 | while (get_second() < target) { | |
168 | yield(); | |
169 | } | |
170 | } | |
171 | ||
dc25e843 ED |
172 | static inline void IPL_assert(bool term, const char *message) |
173 | { | |
174 | if (!term) { | |
175 | sclp_print("\n! "); | |
176 | sclp_print(message); | |
177 | panic(" !\n"); /* no return */ | |
178 | } | |
179 | } | |
180 | ||
181 | static inline void IPL_check(bool term, const char *message) | |
182 | { | |
183 | if (!term) { | |
184 | sclp_print("\n! WARNING: "); | |
185 | sclp_print(message); | |
186 | sclp_print(" !\n"); | |
187 | } | |
188 | } | |
189 | ||
cfe2124a ED |
190 | extern const unsigned char ebc2asc[256]; |
191 | static inline void ebcdic_to_ascii(const char *src, | |
192 | char *dst, | |
193 | unsigned int size) | |
194 | { | |
195 | unsigned int i; | |
196 | ||
197 | for (i = 0; i < size; i++) { | |
198 | unsigned c = src[i]; | |
199 | dst[i] = ebc2asc[c]; | |
200 | } | |
201 | } | |
202 | ||
c9c39d3b | 203 | #endif /* S390_CCW_H */ |