xref: /kvm-unit-tests/lib/s390x/hardware.c (revision d1e2a8e2d0d5856f1a6ce23ea3f044a1532eab40)
1f489dfa5SClaudio Imbrenda /* SPDX-License-Identifier: GPL-2.0-or-later */
2f489dfa5SClaudio Imbrenda /*
3f489dfa5SClaudio Imbrenda  * Functions to retrieve information about the host system.
4f489dfa5SClaudio Imbrenda  *
5f489dfa5SClaudio Imbrenda  * Copyright (c) 2020 Red Hat Inc
6f489dfa5SClaudio Imbrenda  * Copyright 2022 IBM Corp.
7f489dfa5SClaudio Imbrenda  *
8f489dfa5SClaudio Imbrenda  * Authors:
9f489dfa5SClaudio Imbrenda  *  Thomas Huth <thuth@redhat.com>
10f489dfa5SClaudio Imbrenda  *  Claudio Imbrenda <imbrenda@linux.ibm.com>
11f489dfa5SClaudio Imbrenda  */
12f489dfa5SClaudio Imbrenda 
13f489dfa5SClaudio Imbrenda #include <libcflat.h>
14f489dfa5SClaudio Imbrenda #include <alloc_page.h>
15f489dfa5SClaudio Imbrenda #include <asm/arch_def.h>
16*1330e388SJanosch Frank #include <asm/page.h>
17f489dfa5SClaudio Imbrenda #include "hardware.h"
18f489dfa5SClaudio Imbrenda #include "stsi.h"
19f489dfa5SClaudio Imbrenda 
20f489dfa5SClaudio Imbrenda /* The string "QEMU" in EBCDIC */
21f489dfa5SClaudio Imbrenda static const uint8_t qemu_ebcdic[] = { 0xd8, 0xc5, 0xd4, 0xe4 };
22f489dfa5SClaudio Imbrenda /* The string "KVM/" in EBCDIC */
23f489dfa5SClaudio Imbrenda static const uint8_t kvm_ebcdic[] = { 0xd2, 0xe5, 0xd4, 0x61 };
24f489dfa5SClaudio Imbrenda 
do_detect_host(void)25*1330e388SJanosch Frank static enum s390_host do_detect_host(void)
26f489dfa5SClaudio Imbrenda {
27*1330e388SJanosch Frank 	uint8_t buf[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
28*1330e388SJanosch Frank 	struct sysinfo_3_2_2 *stsi_322 = (struct sysinfo_3_2_2 *)buf;
29f489dfa5SClaudio Imbrenda 
30f489dfa5SClaudio Imbrenda 	if (stsi_get_fc() == 2)
31f489dfa5SClaudio Imbrenda 		return HOST_IS_LPAR;
32f489dfa5SClaudio Imbrenda 
33f489dfa5SClaudio Imbrenda 	if (stsi_get_fc() != 3)
34f489dfa5SClaudio Imbrenda 		return HOST_IS_UNKNOWN;
35f489dfa5SClaudio Imbrenda 
36f489dfa5SClaudio Imbrenda 	if (!stsi(buf, 1, 1, 1)) {
37f489dfa5SClaudio Imbrenda 		/*
38f489dfa5SClaudio Imbrenda 		 * If the manufacturer string is "QEMU" in EBCDIC, then we
39f489dfa5SClaudio Imbrenda 		 * are on TCG (otherwise the string is "IBM" in EBCDIC)
40f489dfa5SClaudio Imbrenda 		 */
41f489dfa5SClaudio Imbrenda 		if (!memcmp((char *)buf + 32, qemu_ebcdic, sizeof(qemu_ebcdic)))
42f489dfa5SClaudio Imbrenda 			return HOST_IS_TCG;
43f489dfa5SClaudio Imbrenda 	}
44f489dfa5SClaudio Imbrenda 
45f489dfa5SClaudio Imbrenda 	if (!stsi(buf, 3, 2, 2)) {
46f489dfa5SClaudio Imbrenda 		/*
47f489dfa5SClaudio Imbrenda 		 * If the manufacturer string is "KVM/" in EBCDIC, then we
48f489dfa5SClaudio Imbrenda 		 * are on KVM.
49f489dfa5SClaudio Imbrenda 		 */
50f489dfa5SClaudio Imbrenda 		if (!memcmp(&stsi_322->vm[0].cpi, kvm_ebcdic, sizeof(kvm_ebcdic)))
51f489dfa5SClaudio Imbrenda 			return HOST_IS_KVM;
52f489dfa5SClaudio Imbrenda 	}
53f489dfa5SClaudio Imbrenda 
54f489dfa5SClaudio Imbrenda 	return HOST_IS_UNKNOWN;
55f489dfa5SClaudio Imbrenda }
56f489dfa5SClaudio Imbrenda 
detect_host(void)57f489dfa5SClaudio Imbrenda enum s390_host detect_host(void)
58f489dfa5SClaudio Imbrenda {
59f489dfa5SClaudio Imbrenda 	static enum s390_host host = HOST_IS_UNKNOWN;
60f489dfa5SClaudio Imbrenda 	static bool initialized = false;
61f489dfa5SClaudio Imbrenda 
62f489dfa5SClaudio Imbrenda 	if (initialized)
63f489dfa5SClaudio Imbrenda 		return host;
64f489dfa5SClaudio Imbrenda 
65*1330e388SJanosch Frank 	host = do_detect_host();
66f489dfa5SClaudio Imbrenda 	initialized = true;
67f489dfa5SClaudio Imbrenda 	return host;
68f489dfa5SClaudio Imbrenda }
69