]>
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 AG |
71 | void sclp_print(const char *string); |
72 | void sclp_setup(void); | |
9a22473c | 73 | void sclp_get_loadparm_ascii(char *loadparm); |
c9c39d3b AG |
74 | |
75 | /* virtio.c */ | |
76 | unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2, | |
abd696e4 | 77 | ulong subchan_id, void *load_addr); |
a1102ceb | 78 | bool virtio_is_supported(SubChannelId schid); |
867e039a | 79 | void virtio_blk_setup_device(SubChannelId schid); |
c9c39d3b | 80 | int virtio_read(ulong sector, void *load_addr); |
c8cda874 | 81 | int enable_mss_facility(void); |
dc25e843 | 82 | ulong get_second(void); |
c9c39d3b AG |
83 | |
84 | /* bootmap.c */ | |
60612d5c | 85 | void zipl_load(void); |
c9c39d3b | 86 | |
c9c39d3b AG |
87 | static inline void fill_hex(char *out, unsigned char val) |
88 | { | |
89 | const char hex[] = "0123456789abcdef"; | |
90 | ||
91 | out[0] = hex[(val >> 4) & 0xf]; | |
92 | out[1] = hex[val & 0xf]; | |
93 | } | |
94 | ||
058cc1f3 | 95 | static inline void fill_hex_val(char *out, void *ptr, unsigned size) |
c9c39d3b | 96 | { |
058cc1f3 | 97 | unsigned char *value = ptr; |
c9c39d3b AG |
98 | unsigned int i; |
99 | ||
058cc1f3 ED |
100 | for (i = 0; i < size; i++) { |
101 | fill_hex(&out[i*2], value[i]); | |
c9c39d3b | 102 | } |
058cc1f3 ED |
103 | } |
104 | ||
105 | static inline void print_int(const char *desc, u64 addr) | |
106 | { | |
107 | char out[] = ": 0xffffffffffffffff\n"; | |
108 | ||
109 | fill_hex_val(&out[4], &addr, sizeof(addr)); | |
c9c39d3b AG |
110 | |
111 | sclp_print(desc); | |
112 | sclp_print(out); | |
113 | } | |
114 | ||
115 | static inline void debug_print_int(const char *desc, u64 addr) | |
116 | { | |
117 | #ifdef DEBUG | |
118 | print_int(desc, addr); | |
119 | #endif | |
120 | } | |
121 | ||
122 | static inline void debug_print_addr(const char *desc, void *p) | |
123 | { | |
124 | #ifdef DEBUG | |
125 | debug_print_int(desc, (unsigned int)(unsigned long)p); | |
126 | #endif | |
127 | } | |
128 | ||
129 | /*********************************************** | |
130 | * Hypercall functions * | |
131 | ***********************************************/ | |
132 | ||
abd696e4 ED |
133 | #define KVM_S390_VIRTIO_NOTIFY 0 |
134 | #define KVM_S390_VIRTIO_RESET 1 | |
135 | #define KVM_S390_VIRTIO_SET_STATUS 2 | |
c9c39d3b AG |
136 | #define KVM_S390_VIRTIO_CCW_NOTIFY 3 |
137 | ||
138 | static inline void yield(void) | |
139 | { | |
abd696e4 ED |
140 | asm volatile ("diag 0,0,0x44" |
141 | : : | |
142 | : "memory", "cc"); | |
c9c39d3b AG |
143 | } |
144 | ||
91a03f9b | 145 | #define MAX_SECTOR_SIZE 4096 |
c9c39d3b | 146 | |
dc25e843 ED |
147 | static inline void sleep(unsigned int seconds) |
148 | { | |
149 | ulong target = get_second() + seconds; | |
150 | ||
151 | while (get_second() < target) { | |
152 | yield(); | |
153 | } | |
154 | } | |
155 | ||
dc25e843 ED |
156 | static inline void IPL_assert(bool term, const char *message) |
157 | { | |
158 | if (!term) { | |
159 | sclp_print("\n! "); | |
160 | sclp_print(message); | |
161 | panic(" !\n"); /* no return */ | |
162 | } | |
163 | } | |
164 | ||
165 | static inline void IPL_check(bool term, const char *message) | |
166 | { | |
167 | if (!term) { | |
168 | sclp_print("\n! WARNING: "); | |
169 | sclp_print(message); | |
170 | sclp_print(" !\n"); | |
171 | } | |
172 | } | |
173 | ||
cfe2124a ED |
174 | extern const unsigned char ebc2asc[256]; |
175 | static inline void ebcdic_to_ascii(const char *src, | |
176 | char *dst, | |
177 | unsigned int size) | |
178 | { | |
179 | unsigned int i; | |
180 | ||
181 | for (i = 0; i < size; i++) { | |
182 | unsigned c = src[i]; | |
183 | dst[i] = ebc2asc[c]; | |
184 | } | |
185 | } | |
186 | ||
c9c39d3b | 187 | #endif /* S390_CCW_H */ |