qemu/linux-user/include/host/riscv/host-signal.h
<<
>>
Prefs
   1/*
   2 * host-signal.h: signal info dependent on the host architecture
   3 *
   4 * Copyright (c) 2003-2005 Fabrice Bellard
   5 * Copyright (c) 2021 Linaro Limited
   6 *
   7 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
   8 * See the COPYING file in the top-level directory.
   9 */
  10
  11#ifndef RISCV_HOST_SIGNAL_H
  12#define RISCV_HOST_SIGNAL_H
  13
  14/* The third argument to a SA_SIGINFO handler is ucontext_t. */
  15typedef ucontext_t host_sigcontext;
  16
  17static inline uintptr_t host_signal_pc(host_sigcontext *uc)
  18{
  19    return uc->uc_mcontext.__gregs[REG_PC];
  20}
  21
  22static inline void host_signal_set_pc(host_sigcontext *uc, uintptr_t pc)
  23{
  24    uc->uc_mcontext.__gregs[REG_PC] = pc;
  25}
  26
  27static inline void *host_signal_mask(host_sigcontext *uc)
  28{
  29    return &uc->uc_sigmask;
  30}
  31
  32static inline bool host_signal_write(siginfo_t *info, host_sigcontext *uc)
  33{
  34    /*
  35     * Detect store by reading the instruction at the program counter.
  36     * Do not read more than 16 bits, because we have not yet determined
  37     * the size of the instruction.
  38     */
  39    const uint16_t *pinsn = (const uint16_t *)host_signal_pc(uc);
  40    uint16_t insn = pinsn[0];
  41
  42    /* 16-bit instructions */
  43    switch (insn & 0xe003) {
  44    case 0xa000: /* c.fsd */
  45    case 0xc000: /* c.sw */
  46    case 0xe000: /* c.sd (rv64) / c.fsw (rv32) */
  47    case 0xa002: /* c.fsdsp */
  48    case 0xc002: /* c.swsp */
  49    case 0xe002: /* c.sdsp (rv64) / c.fswsp (rv32) */
  50        return true;
  51    }
  52
  53    /* 32-bit instructions, major opcodes */
  54    switch (insn & 0x7f) {
  55    case 0x23: /* store */
  56    case 0x27: /* store-fp */
  57        return true;
  58    case 0x2f: /* amo */
  59        /*
  60         * The AMO function code is in bits 25-31, unread as yet.
  61         * The AMO functions are LR (read), SC (write), and the
  62         * rest are all read-modify-write.
  63         */
  64        insn = pinsn[1];
  65        return (insn >> 11) != 2; /* LR */
  66    }
  67
  68    return false;
  69}
  70
  71#endif
  72