1fcbf4a3cSThomas Huth /* 2b95b5a0aSThomas Huth * Test Open-Firmware-based machines. 3fcbf4a3cSThomas Huth * 4b95b5a0aSThomas Huth * Copyright (c) 2016, 2017 Red Hat Inc. 5fcbf4a3cSThomas Huth * 6fcbf4a3cSThomas Huth * Author: 7fcbf4a3cSThomas Huth * Thomas Huth <thuth@redhat.com> 8fcbf4a3cSThomas Huth * 9fcbf4a3cSThomas Huth * This work is licensed under the terms of the GNU GPL, version 2 10fcbf4a3cSThomas Huth * or later. See the COPYING file in the top-level directory. 11fcbf4a3cSThomas Huth * 1253687348SDavid Gibson * This test is used to check that some Open Firmware based machines (i.e. 1353687348SDavid Gibson * OpenBIOS or SLOF) can be started successfully in TCG mode. To do this, we 1453687348SDavid Gibson * first put some Forth code into the "boot-command" Open Firmware environment 1553687348SDavid Gibson * variable. This Forth code writes a well-known magic value to a known location 1653687348SDavid Gibson * in memory. Then we start the guest so that the firmware can boot and finally 1753687348SDavid Gibson * run the Forth code. 18fcbf4a3cSThomas Huth * The testing code here then can finally check whether the value has been 19fcbf4a3cSThomas Huth * successfully written into the guest memory. 20fcbf4a3cSThomas Huth */ 21fcbf4a3cSThomas Huth 22fcbf4a3cSThomas Huth #include "qemu/osdep.h" 23907b5105SMarc-André Lureau #include "libqtest.h" 2463d57c8fSGreg Kurz #include "libqos/libqos-spapr.h" 25fcbf4a3cSThomas Huth 26fcbf4a3cSThomas Huth #define MAGIC 0xcafec0de 27fcbf4a3cSThomas Huth #define ADDRESS 0x4000 28fcbf4a3cSThomas Huth 29dc4c1587SThomas Huth static void check_guest_memory(QTestState *qts) 30fcbf4a3cSThomas Huth { 31fcbf4a3cSThomas Huth uint32_t signature; 32fcbf4a3cSThomas Huth int i; 33fcbf4a3cSThomas Huth 34b95b5a0aSThomas Huth /* Poll until code has run and modified memory. Wait at most 600 seconds */ 35b95b5a0aSThomas Huth for (i = 0; i < 60000; ++i) { 36dc4c1587SThomas Huth signature = qtest_readl(qts, ADDRESS); 37fcbf4a3cSThomas Huth if (signature == MAGIC) { 38fcbf4a3cSThomas Huth break; 39fcbf4a3cSThomas Huth } 40fcbf4a3cSThomas Huth g_usleep(10000); 41fcbf4a3cSThomas Huth } 42fcbf4a3cSThomas Huth 43fcbf4a3cSThomas Huth g_assert_cmphex(signature, ==, MAGIC); 44fcbf4a3cSThomas Huth } 45fcbf4a3cSThomas Huth 46fcbf4a3cSThomas Huth static void test_machine(const void *machine) 47fcbf4a3cSThomas Huth { 48ba3b40deSDavid Gibson const char *extra_args = ""; 49dc4c1587SThomas Huth QTestState *qts; 50fcbf4a3cSThomas Huth 51ba3b40deSDavid Gibson /* 52ba3b40deSDavid Gibson * The pseries firmware boots much faster without the default 53ba3b40deSDavid Gibson * devices, it also needs Spectre/Meltdown workarounds disabled to 54ba3b40deSDavid Gibson * avoid warnings with TCG 55ba3b40deSDavid Gibson */ 56ba3b40deSDavid Gibson if (strcmp(machine, "pseries") == 0) { 57ba3b40deSDavid Gibson extra_args = "-nodefaults" 5863d57c8fSGreg Kurz " -machine " PSERIES_DEFAULT_CAPABILITIES; 59ba3b40deSDavid Gibson } 6061eedf7aSThomas Huth 61*94add6eeSBin Meng qts = qtest_initf("-M %s -accel tcg %s -prom-env \"use-nvramrc?=true\" " 62*94add6eeSBin Meng "-prom-env \"nvramrc=%x %x l!\" ", (const char *)machine, 63dc4c1587SThomas Huth extra_args, MAGIC, ADDRESS); 64dc4c1587SThomas Huth check_guest_memory(qts); 65dc4c1587SThomas Huth qtest_quit(qts); 66fcbf4a3cSThomas Huth } 67fcbf4a3cSThomas Huth 68fcbf4a3cSThomas Huth static void add_tests(const char *machines[]) 69fcbf4a3cSThomas Huth { 70fcbf4a3cSThomas Huth int i; 71fcbf4a3cSThomas Huth char *name; 72fcbf4a3cSThomas Huth 73fcbf4a3cSThomas Huth for (i = 0; machines[i] != NULL; i++) { 74719051caSThomas Huth if (qtest_has_machine(machines[i])) { 75fcbf4a3cSThomas Huth name = g_strdup_printf("prom-env/%s", machines[i]); 76fcbf4a3cSThomas Huth qtest_add_data_func(name, machines[i], test_machine); 77fcbf4a3cSThomas Huth g_free(name); 78fcbf4a3cSThomas Huth } 79fcbf4a3cSThomas Huth } 80719051caSThomas Huth } 81fcbf4a3cSThomas Huth 82fcbf4a3cSThomas Huth int main(int argc, char *argv[]) 83fcbf4a3cSThomas Huth { 84fcbf4a3cSThomas Huth const char *sparc_machines[] = { "SPARCbook", "Voyager", "SS-20", NULL }; 856b591ad6SThomas Huth const char *sparc64_machines[] = { "sun4u", NULL }; 8653687348SDavid Gibson const char *ppc_machines[] = { "mac99", "g3beige", NULL }; 87fcbf4a3cSThomas Huth const char *arch = qtest_get_arch(); 88fcbf4a3cSThomas Huth 89fcbf4a3cSThomas Huth g_test_init(&argc, &argv, NULL); 90fcbf4a3cSThomas Huth 9153687348SDavid Gibson if (!strcmp(arch, "ppc")) { 9253687348SDavid Gibson add_tests(ppc_machines); 9353687348SDavid Gibson } else if (!strcmp(arch, "ppc64")) { 94b95b5a0aSThomas Huth add_tests(ppc_machines); 95b95b5a0aSThomas Huth if (g_test_slow()) { 96b95b5a0aSThomas Huth qtest_add_data_func("prom-env/pseries", "pseries", test_machine); 97b95b5a0aSThomas Huth } 98fcbf4a3cSThomas Huth } else if (!strcmp(arch, "sparc")) { 99fcbf4a3cSThomas Huth add_tests(sparc_machines); 100fcbf4a3cSThomas Huth } else if (!strcmp(arch, "sparc64")) { 101fcbf4a3cSThomas Huth add_tests(sparc64_machines); 102fcbf4a3cSThomas Huth } else { 103fcbf4a3cSThomas Huth g_assert_not_reached(); 104fcbf4a3cSThomas Huth } 105fcbf4a3cSThomas Huth 106fcbf4a3cSThomas Huth return g_test_run(); 107fcbf4a3cSThomas Huth } 108