qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

sifive_test.c (2761B)


      1 /*
      2  * QEMU SiFive Test Finisher
      3  *
      4  * Copyright (c) 2018 SiFive, Inc.
      5  *
      6  * Test finisher memory mapped device used to exit simulation
      7  *
      8  * This program is free software; you can redistribute it and/or modify it
      9  * under the terms and conditions of the GNU General Public License,
     10  * version 2 or later, as published by the Free Software Foundation.
     11  *
     12  * This program is distributed in the hope it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
     15  * more details.
     16  *
     17  * You should have received a copy of the GNU General Public License along with
     18  * this program.  If not, see <http://www.gnu.org/licenses/>.
     19  */
     20 
     21 #include "qemu/osdep.h"
     22 #include "hw/sysbus.h"
     23 #include "qapi/error.h"
     24 #include "qemu/log.h"
     25 #include "qemu/module.h"
     26 #include "sysemu/runstate.h"
     27 #include "hw/misc/sifive_test.h"
     28 
     29 static uint64_t sifive_test_read(void *opaque, hwaddr addr, unsigned int size)
     30 {
     31     return 0;
     32 }
     33 
     34 static void sifive_test_write(void *opaque, hwaddr addr,
     35            uint64_t val64, unsigned int size)
     36 {
     37     if (addr == 0) {
     38         int status = val64 & 0xffff;
     39         int code = (val64 >> 16) & 0xffff;
     40         switch (status) {
     41         case FINISHER_FAIL:
     42             exit(code);
     43         case FINISHER_PASS:
     44             exit(0);
     45         case FINISHER_RESET:
     46             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
     47             return;
     48         default:
     49             break;
     50         }
     51     }
     52     qemu_log_mask(LOG_GUEST_ERROR, "%s: write: addr=0x%x val=0x%016" PRIx64 "\n",
     53                   __func__, (int)addr, val64);
     54 }
     55 
     56 static const MemoryRegionOps sifive_test_ops = {
     57     .read = sifive_test_read,
     58     .write = sifive_test_write,
     59     .endianness = DEVICE_NATIVE_ENDIAN,
     60     .valid = {
     61         .min_access_size = 2,
     62         .max_access_size = 4
     63     }
     64 };
     65 
     66 static void sifive_test_init(Object *obj)
     67 {
     68     SiFiveTestState *s = SIFIVE_TEST(obj);
     69 
     70     memory_region_init_io(&s->mmio, obj, &sifive_test_ops, s,
     71                           TYPE_SIFIVE_TEST, 0x1000);
     72     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
     73 }
     74 
     75 static const TypeInfo sifive_test_info = {
     76     .name          = TYPE_SIFIVE_TEST,
     77     .parent        = TYPE_SYS_BUS_DEVICE,
     78     .instance_size = sizeof(SiFiveTestState),
     79     .instance_init = sifive_test_init,
     80 };
     81 
     82 static void sifive_test_register_types(void)
     83 {
     84     type_register_static(&sifive_test_info);
     85 }
     86 
     87 type_init(sifive_test_register_types)
     88 
     89 
     90 /*
     91  * Create Test device.
     92  */
     93 DeviceState *sifive_test_create(hwaddr addr)
     94 {
     95     DeviceState *dev = qdev_new(TYPE_SIFIVE_TEST);
     96     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
     97     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
     98     return dev;
     99 }