2 * Copyright (c) 2007-2011 Josef 'Jeff' Sipek
6 #include <binfmt_elf.h>
10 static unsigned char seek_data
[6];
11 static unsigned char search_data
[5];
13 extern struct orb ORB
;
15 static u8
*buf
= (u8
*) (16 * 1024);
16 static u32
*ptrbuf
= (u32
*) (20 * 1024);
18 static u64 pgm_new_psw_diswait
[2] = {
19 0x0002000180000000ULL
, 0,
22 static u64 io_new_psw
[2] = {
23 0x0000000180000000ULL
, (u64
) &IOHANDLER
,
26 static u64 pgm_new_psw
[2] = {
27 0x0000000180000000ULL
, (u64
) &PGMHANDLER
,
34 void __readwrite_blk(void *ptr
, u32 lba
, int rwccw
)
43 memset(ccw
, 0, sizeof(ccw
));
46 cc
= lba
/ RECORDS_PER_CYL
;
47 hh
= (lba
% RECORDS_PER_CYL
) / RECORDS_PER_TRACK
;
48 r
= (lba
% RECORDS_PER_CYL
) % RECORDS_PER_TRACK
;
51 ORB
.addr
= ADDR31(ccw
);
55 ccw
[0].flags
= CCW_FLAG_CC
| CCW_FLAG_SLI
;
57 ccw
[0].addr
= ADDR31(seek_data
);
59 seek_data
[0] = 0; /* zero */
60 seek_data
[1] = 0; /* zero */
61 seek_data
[2] = cc
>> 8; /* Cc */
62 seek_data
[3] = cc
& 0xff; /* cC */
63 seek_data
[4] = hh
>> 8; /* Hh */
64 seek_data
[5] = hh
& 0xff; /* hH */
68 ccw
[1].flags
= CCW_FLAG_CC
| CCW_FLAG_SLI
;
70 ccw
[1].addr
= ADDR31(search_data
);
72 search_data
[0] = cc
>> 8;
73 search_data
[1] = cc
& 0xff;
74 search_data
[2] = hh
>> 8;
75 search_data
[3] = hh
& 0xff;
82 ccw
[2].addr
= ADDR31(&ccw
[1]);
88 ccw
[3].addr
= ADDR31(ptr
);
93 if (__do_io(dasd_sch
))
97 struct senseid_struct
{
103 } __attribute__((packed
));
106 static int dev_dasd(void)
110 struct senseid_struct id
;
113 ccw
.flags
= CCW_FLAG_SLI
;
114 ccw
.count
= sizeof(struct senseid_struct
);
115 ccw
.addr
= ADDR31(&id
);
117 ORB
.param
= 0x12345678,
120 ORB
.addr
= ADDR31(&ccw
);
122 ret
= __do_io(dasd_sch
);
126 if ((id
.dev_type
== 0x3390) &&
127 (id
.dev_model
== 0x0A) &&
128 (id
.cu_type
== 0x3990) &&
129 (id
.cu_model
== 0xC2))
130 return 0; // ECKD 3390-3 that we know how to use
132 return -1; // not a DASD
135 static u64
atoi(char *s
, int len
)
140 if ((*s
>= '0') && (*s
<= '9'))
141 i
= (i
* 16) + (*s
- '0');
142 else if ((*s
>= 'A') && (*s
<= 'F'))
143 i
= (i
* 16) + (*s
- 'A' + 10);
144 else if ((*s
>= 'a') && (*s
<= 'f'))
145 i
= (i
* 16) + (*s
- 'a' + 10);
155 static u64
find_devnum(u64 devnum
)
163 memset(&schib
, 0, sizeof(struct schib
));
166 * For each possible subchannel id...
168 for(sch
= 0x10000; sch
<= 0x1ffff; sch
++) {
170 * ...call store subchannel, to find out whether or not
173 if (store_sch(sch
, &schib
))
179 if (schib
.pmcw
.dev_num
!= devnum
)
184 if (modify_sch(sch
, &schib
))
199 strncpy(buf
, str
, 160);
202 ascii2ebcdic((u8
*)buf
, 160);
206 ccw
.count
= strlen(str
);
207 ccw
.addr
= ADDR31(buf
);
209 ORB
.param
= 0x12345678,
212 ORB
.addr
= ADDR31(&ccw
);
214 ret
= __do_io(con_sch
);
219 void wtor(char *str
, char *inp
, int buflen
)
226 /* wait for user input */
229 /* read user input */
231 ccw
.flags
= CCW_FLAG_SLI
;
233 ccw
.addr
= ADDR31(inp
);
235 ORB
.param
= 0x12345678,
238 ORB
.addr
= ADDR31(&ccw
);
240 ret
= __do_io(con_sch
);
244 ebcdic2ascii((u8
*)inp
, buflen
);
247 static void init_io(void)
251 /* enable all I/O interrupt classes */
253 "stctg 6,6,%0\n" /* get cr6 */
254 "oi %1,0xff\n" /* enable all */
255 "lctlg 6,6,%0\n" /* reload cr6 */
259 "m" (*(u64
*) (((u8
*)&cr6
) + 4))
263 void load_nucleus(void)
267 /* Save the IPL device subchannel id */
268 ipl_sch
= *((u32
*) 0xb8);
270 memcpy((void*) 0x1d0, pgm_new_psw_diswait
, 16);
271 memcpy((void*) 0x1f0, io_new_psw
, 16);
276 * try to find the console on 0009
278 con_sch
= find_devnum(CON_DEVNUM
);
279 if (con_sch
> 0x1ffff)
283 * greet the user on the console
285 wto("HVF installer\n\n");
289 * ask the user for target dasd
291 wtor("Specify target device (1-4 hex digits):\n", inp
, 160);
293 dasd_sch
= find_devnum(atoi(inp
, 160));
294 if ((dasd_sch
< 0x10000) || (dasd_sch
> 0x1ffff)) {
295 wto("Invalid device number.\n\n");
299 wto("Device found.\n\n");
301 wto("Need a DASD.\n\n");
309 wtor("Format volume? [y/n]\n", inp
, 160);
311 if ((inp
[0] == 'y') || (inp
[0] == 'Y')) {
312 wto("Formating volume...\n");
316 * 1) format the volume
320 wto("done. (Not yet implemented)\n");
323 wto("Formatting skipped.\n");
326 * initialize the memory allocator
328 init_malloc(TEMP_BASE
);
331 * mount the EDF volume
336 * read through the archive and decide what to do with each file
341 * currently, we haven't written anything to disk; flush everything
346 * FIXME: inform the user that we're done, and load a psw with the
350 wto("\nInstallation complete.\n");
351 wto("You can now IPL from the DASD.\n");
357 "m" (pgm_new_psw_diswait
[0])