1fcbf4a3cSThomas Huth /* 2*b95b5a0aSThomas Huth * Test Open-Firmware-based machines. 3fcbf4a3cSThomas Huth * 4*b95b5a0aSThomas 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" 23fcbf4a3cSThomas Huth #include "libqtest.h" 24fcbf4a3cSThomas Huth 25fcbf4a3cSThomas Huth #define MAGIC 0xcafec0de 26fcbf4a3cSThomas Huth #define ADDRESS 0x4000 27fcbf4a3cSThomas Huth 28fcbf4a3cSThomas Huth static void check_guest_memory(void) 29fcbf4a3cSThomas Huth { 30fcbf4a3cSThomas Huth uint32_t signature; 31fcbf4a3cSThomas Huth int i; 32fcbf4a3cSThomas Huth 33*b95b5a0aSThomas Huth /* Poll until code has run and modified memory. Wait at most 600 seconds */ 34*b95b5a0aSThomas Huth for (i = 0; i < 60000; ++i) { 35fcbf4a3cSThomas Huth signature = readl(ADDRESS); 36fcbf4a3cSThomas Huth if (signature == MAGIC) { 37fcbf4a3cSThomas Huth break; 38fcbf4a3cSThomas Huth } 39fcbf4a3cSThomas Huth g_usleep(10000); 40fcbf4a3cSThomas Huth } 41fcbf4a3cSThomas Huth 42fcbf4a3cSThomas Huth g_assert_cmphex(signature, ==, MAGIC); 43fcbf4a3cSThomas Huth } 44fcbf4a3cSThomas Huth 45fcbf4a3cSThomas Huth static void test_machine(const void *machine) 46fcbf4a3cSThomas Huth { 47fcbf4a3cSThomas Huth char *args; 4861eedf7aSThomas Huth const char *extra_args; 49fcbf4a3cSThomas Huth 5061eedf7aSThomas Huth /* The pseries firmware boots much faster without the default devices */ 5161eedf7aSThomas Huth extra_args = strcmp(machine, "pseries") == 0 ? "-nodefaults" : ""; 5261eedf7aSThomas Huth 5361eedf7aSThomas Huth args = g_strdup_printf("-M %s,accel=tcg %s -prom-env 'use-nvramrc?=true' " 5461eedf7aSThomas Huth "-prom-env 'nvramrc=%x %x l!' ", 5561eedf7aSThomas Huth (const char *)machine, extra_args, MAGIC, ADDRESS); 56fcbf4a3cSThomas Huth 57fcbf4a3cSThomas Huth qtest_start(args); 58fcbf4a3cSThomas Huth check_guest_memory(); 59fcbf4a3cSThomas Huth qtest_quit(global_qtest); 60fcbf4a3cSThomas Huth 61fcbf4a3cSThomas Huth g_free(args); 62fcbf4a3cSThomas Huth } 63fcbf4a3cSThomas Huth 64fcbf4a3cSThomas Huth static void add_tests(const char *machines[]) 65fcbf4a3cSThomas Huth { 66fcbf4a3cSThomas Huth int i; 67fcbf4a3cSThomas Huth char *name; 68fcbf4a3cSThomas Huth 69fcbf4a3cSThomas Huth for (i = 0; machines[i] != NULL; i++) { 70fcbf4a3cSThomas Huth name = g_strdup_printf("prom-env/%s", machines[i]); 71fcbf4a3cSThomas Huth qtest_add_data_func(name, machines[i], test_machine); 72fcbf4a3cSThomas Huth g_free(name); 73fcbf4a3cSThomas Huth } 74fcbf4a3cSThomas Huth } 75fcbf4a3cSThomas Huth 76fcbf4a3cSThomas Huth int main(int argc, char *argv[]) 77fcbf4a3cSThomas Huth { 78fcbf4a3cSThomas Huth const char *sparc_machines[] = { "SPARCbook", "Voyager", "SS-20", NULL }; 796b591ad6SThomas Huth const char *sparc64_machines[] = { "sun4u", NULL }; 8053687348SDavid Gibson const char *ppc_machines[] = { "mac99", "g3beige", NULL }; 81fcbf4a3cSThomas Huth const char *arch = qtest_get_arch(); 82fcbf4a3cSThomas Huth 83fcbf4a3cSThomas Huth g_test_init(&argc, &argv, NULL); 84fcbf4a3cSThomas Huth 8553687348SDavid Gibson if (!strcmp(arch, "ppc")) { 8653687348SDavid Gibson add_tests(ppc_machines); 8753687348SDavid Gibson } else if (!strcmp(arch, "ppc64")) { 88*b95b5a0aSThomas Huth add_tests(ppc_machines); 89*b95b5a0aSThomas Huth if (g_test_slow()) { 90*b95b5a0aSThomas Huth qtest_add_data_func("prom-env/pseries", "pseries", test_machine); 91*b95b5a0aSThomas Huth } 92fcbf4a3cSThomas Huth } else if (!strcmp(arch, "sparc")) { 93fcbf4a3cSThomas Huth add_tests(sparc_machines); 94fcbf4a3cSThomas Huth } else if (!strcmp(arch, "sparc64")) { 95fcbf4a3cSThomas Huth add_tests(sparc64_machines); 96fcbf4a3cSThomas Huth } else { 97fcbf4a3cSThomas Huth g_assert_not_reached(); 98fcbf4a3cSThomas Huth } 99fcbf4a3cSThomas Huth 100fcbf4a3cSThomas Huth return g_test_run(); 101fcbf4a3cSThomas Huth } 102