192f2ca38SAlexander Graf /* 292f2ca38SAlexander Graf * S390 virtio-ccw loading program 392f2ca38SAlexander Graf * 492f2ca38SAlexander Graf * Copyright (c) 2013 Alexander Graf <agraf@suse.de> 592f2ca38SAlexander Graf * 692f2ca38SAlexander Graf * This work is licensed under the terms of the GNU GPL, version 2 or (at 792f2ca38SAlexander Graf * your option) any later version. See the COPYING file in the top-level 892f2ca38SAlexander Graf * directory. 992f2ca38SAlexander Graf */ 1092f2ca38SAlexander Graf 1192f2ca38SAlexander Graf #include "s390-ccw.h" 1292f2ca38SAlexander Graf 1392f2ca38SAlexander Graf struct subchannel_id blk_schid; 1492f2ca38SAlexander Graf char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE))); 15*ff151f4eSDominik Dingel uint64_t boot_value; 1692f2ca38SAlexander Graf 1792f2ca38SAlexander Graf void virtio_panic(const char *string) 1892f2ca38SAlexander Graf { 1992f2ca38SAlexander Graf sclp_print(string); 207f61cbc1SChristian Borntraeger disabled_wait(); 2192f2ca38SAlexander Graf while (1) { } 2292f2ca38SAlexander Graf } 2392f2ca38SAlexander Graf 24*ff151f4eSDominik Dingel static void virtio_setup(uint64_t dev_info) 2592f2ca38SAlexander Graf { 2622d67ab5SCornelia Huck struct schib schib; 2792f2ca38SAlexander Graf int i; 2892f2ca38SAlexander Graf int r; 2992f2ca38SAlexander Graf bool found = false; 30*ff151f4eSDominik Dingel bool check_devno = false; 31*ff151f4eSDominik Dingel uint16_t dev_no = -1; 3292f2ca38SAlexander Graf blk_schid.one = 1; 3392f2ca38SAlexander Graf 34*ff151f4eSDominik Dingel if (dev_info != -1) { 35*ff151f4eSDominik Dingel check_devno = true; 36*ff151f4eSDominik Dingel dev_no = dev_info & 0xffff; 37*ff151f4eSDominik Dingel debug_print_int("device no. ", dev_no); 38*ff151f4eSDominik Dingel } 39*ff151f4eSDominik Dingel 4092f2ca38SAlexander Graf for (i = 0; i < 0x10000; i++) { 4192f2ca38SAlexander Graf blk_schid.sch_no = i; 4222d67ab5SCornelia Huck r = stsch_err(blk_schid, &schib); 4322d67ab5SCornelia Huck if (r == 3) { 4422d67ab5SCornelia Huck break; 4522d67ab5SCornelia Huck } 4622d67ab5SCornelia Huck if (schib.pmcw.dnv) { 47*ff151f4eSDominik Dingel if (!check_devno || (schib.pmcw.dev == dev_no)) { 4892f2ca38SAlexander Graf if (virtio_is_blk(blk_schid)) { 4992f2ca38SAlexander Graf found = true; 5092f2ca38SAlexander Graf break; 5192f2ca38SAlexander Graf } 5292f2ca38SAlexander Graf } 5392f2ca38SAlexander Graf } 54*ff151f4eSDominik Dingel } 5592f2ca38SAlexander Graf 5692f2ca38SAlexander Graf if (!found) { 5792f2ca38SAlexander Graf virtio_panic("No virtio-blk device found!\n"); 5892f2ca38SAlexander Graf } 5992f2ca38SAlexander Graf 6092f2ca38SAlexander Graf virtio_setup_block(blk_schid); 6192f2ca38SAlexander Graf } 6292f2ca38SAlexander Graf 6392f2ca38SAlexander Graf int main(void) 6492f2ca38SAlexander Graf { 6592f2ca38SAlexander Graf sclp_setup(); 66*ff151f4eSDominik Dingel debug_print_int("boot reg[7] ", boot_value); 67*ff151f4eSDominik Dingel virtio_setup(boot_value); 68*ff151f4eSDominik Dingel 6992f2ca38SAlexander Graf if (zipl_load() < 0) 7092f2ca38SAlexander Graf sclp_print("Failed to load OS from hard disk\n"); 717f61cbc1SChristian Borntraeger disabled_wait(); 7292f2ca38SAlexander Graf while (1) { } 7392f2ca38SAlexander Graf } 74