1/* 2 * First stage boot loader for virtio devices. The compiled output goes 3 * into the pc-bios directory of qemu. 4 * 5 * Copyright (c) 2013 Alexander Graf <agraf@suse.de> 6 * Copyright IBM Corp. 2013, 2017 7 * 8 * This work is licensed under the terms of the GNU GPL, version 2 or (at 9 * your option) any later version. See the COPYING file in the top-level 10 * directory. 11 */ 12 13#define STACK_SIZE 0x8000 14#define STACK_FRAME_SIZE 160 15 16 .globl _start 17_start: 18 19 larl %r15,stack + STACK_SIZE - STACK_FRAME_SIZE /* Set up stack */ 20 21 /* clear bss */ 22 larl %r2,bss_start_literal /* __bss_start might be unaligned ... */ 23 lg %r2,0(%r2) /* ... so load it indirectly */ 24 larl %r3,_end 25 slgr %r3,%r2 /* get sizeof bss */ 26 ltgr %r3,%r3 /* bss empty? */ 27 jz done 28 aghi %r3,-1 29 srlg %r4,%r3,8 /* how many 256 byte chunks? */ 30 ltgr %r4,%r4 31 lgr %r1,%r2 32 jz remainder 33loop: 34 xc 0(256,%r1),0(%r1) 35 la %r1,256(%r1) 36 brctg %r4,loop 37remainder: 38 larl %r2,memsetxc 39 ex %r3,0(%r2) 40done: 41 /* set up a pgm exception disabled wait psw */ 42 larl %r2,disabled_wait_psw 43 mvc 0x01d0(16),0(%r2) 44 j main /* And call C */ 45 46memsetxc: 47 xc 0(1,%r1),0(%r1) 48 49/* 50 * void disabled_wait(void) 51 * 52 * stops the current guest cpu. 53 */ 54 .globl disabled_wait 55disabled_wait: 56 larl %r1,disabled_wait_psw 57 lpswe 0(%r1) 581: j 1b 59 60 61/* 62 * void consume_sclp_int(void) 63 * 64 * eats one sclp interrupt 65 */ 66 .globl consume_sclp_int 67consume_sclp_int: 68 /* enable service interrupts in cr0 */ 69 stctg %c0,%c0,0(%r15) 70 oi 6(%r15),0x2 71 lctlg %c0,%c0,0(%r15) 72 /* prepare external call handler */ 73 larl %r1,external_new_code 74 stg %r1,0x1b8 75 larl %r1,external_new_mask 76 mvc 0x1b0(8),0(%r1) 77 /* load enabled wait PSW */ 78 larl %r1,enabled_wait_psw 79 lpswe 0(%r1) 80 81/* 82 * void consume_io_int(void) 83 * 84 * eats one I/O interrupt 85 */ 86 .globl consume_io_int 87consume_io_int: 88 /* enable I/O interrupts in cr6 */ 89 stctg %c6,%c6,0(%r15) 90 oi 4(%r15), 0xff 91 lctlg %c6,%c6,0(%r15) 92 /* prepare i/o call handler */ 93 larl %r1,io_new_code 94 stg %r1,0x1f8 95 larl %r1,io_new_mask 96 mvc 0x1f0(8),0(%r1) 97 /* load enabled wait PSW */ 98 larl %r1,enabled_wait_psw 99 lpswe 0(%r1) 100 101external_new_code: 102 /* disable service interrupts in cr0 */ 103 stctg %c0,%c0,0(%r15) 104 ni 6(%r15),0xfd 105 lctlg %c0,%c0,0(%r15) 106 br %r14 107 108io_new_code: 109 /* disable I/O interrupts in cr6 */ 110 stctg %c6,%c6,0(%r15) 111 ni 4(%r15),0x00 112 lctlg %c6,%c6,0(%r15) 113 br %r14 114 115 .align 8 116bss_start_literal: 117 .quad __bss_start 118disabled_wait_psw: 119 .quad 0x0002000180000000,0x0000000000000000 120enabled_wait_psw: 121 .quad 0x0302000180000000,0x0000000000000000 122external_new_mask: 123 .quad 0x0000000180000000 124io_new_mask: 125 .quad 0x0000000180000000 126 127.bss 128 .align 8 129stack: 130 .space STACK_SIZE 131 .size stack,STACK_SIZE 132