master
c 96 lines 2.31 KB
Raw
1 /*
2 * S390 guest code used in migration tests
3 *
4 * Copyright 2018 Thomas Huth, Red Hat Inc.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12 /* for sclp.h */
13 #define LOADPARM_LEN 8
14 typedef unsigned int uint32_t;
15 typedef unsigned short uint16_t;
16 typedef unsigned char uint8_t;
17
18 #include <sclp.h>
19
20 #define START_ADDRESS (1024 * 1024)
21 #define END_ADDRESS (100 * 1024 * 1024)
22
23 /* at pc-bios/s390-ccw/start.S */
24
25 void __attribute__((weak)) consume_sclp_int(void)
26 {
27 }
28
29 static char _sccb[4096] __attribute__((__aligned__(4096)));
30 char stack[0x8000] __attribute__((aligned(4096)));
31
32 static void sclp_service_call(unsigned int command)
33 {
34 int cc;
35
36 asm volatile(
37 " .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
38 " ipm %0\n"
39 " srl %0,28"
40 : "=&d" (cc) : "d" (command), "a" (__pa(_sccb))
41 : "cc", "memory");
42 consume_sclp_int();
43 }
44
45 static void sclp_setup(void)
46 {
47 WriteEventMask *sccb = (void *)_sccb;
48
49 sccb->h.length = sizeof(WriteEventMask);
50
51 sccb->mask_length = sizeof(unsigned int);
52 sccb->cp_receive_mask = 0;
53 sccb->cp_send_mask = SCLP_EVENT_MASK_MSG_ASCII;
54
55 sclp_service_call(SCLP_CMD_WRITE_EVENT_MASK);
56 }
57
58 static void putc(const char c)
59 {
60 WriteEventData *sccb = (void *)_sccb;
61 int len = 1;
62
63 sccb->data[0] = c;
64
65 sccb->h.length = sizeof(WriteEventData) + len;
66 sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
67
68 sccb->ebh.length = sizeof(EventBufferHeader) + len;
69 sccb->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
70 sccb->ebh.flags = 0;
71
72 sclp_service_call(SCLP_CMD_WRITE_EVENT_DATA);
73 }
74
75 void main(void)
76 {
77 unsigned long addr;
78
79 sclp_setup();
80 putc('A');
81
82 /*
83 * Make sure all of the pages have consistent contents before incrementing
84 * the first byte below.
85 */
86 for (addr = START_ADDRESS; addr < END_ADDRESS; addr += 4096) {
87 *(volatile char *)addr = 0;
88 }
89
90 while (1) {
91 for (addr = START_ADDRESS; addr < END_ADDRESS; addr += 4096) {
92 *(volatile char *)addr += 1; /* Change pages */
93 }
94 putc('B');
95 }
96 }