blob: 2f9ffb6e687c4ef3725be54ce580fef3176fd0b4 [file] [log] [blame]
Fuad Tabba5c738432019-12-02 11:02:42 +00001/*
2 * Copyright 2019 The Hafnium Authors.
3 *
Andrew Walbrane959ec12020-06-17 15:01:09 +01004 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/BSD-3-Clause.
Fuad Tabba5c738432019-12-02 11:02:42 +00007 */
8
9#pragma once
10
11#include "hf/addr.h"
12#include "hf/spinlock.h"
13
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010014#include "vmapi/hf/ffa.h"
Fuad Tabba5c738432019-12-02 11:02:42 +000015
16/** The number of bits in each element of the interrupt bitfields. */
17#define INTERRUPT_REGISTER_BITS 32
18
19enum vcpu_state {
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000020 /** The vCPU is switched off. */
Fuad Tabba5c738432019-12-02 11:02:42 +000021 VCPU_STATE_OFF,
22
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000023 /** The vCPU is ready to be run. */
Fuad Tabba5c738432019-12-02 11:02:42 +000024 VCPU_STATE_READY,
25
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000026 /** The vCPU is currently running. */
Fuad Tabba5c738432019-12-02 11:02:42 +000027 VCPU_STATE_RUNNING,
28
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000029 /** The vCPU is waiting for a message. */
Fuad Tabba5c738432019-12-02 11:02:42 +000030 VCPU_STATE_BLOCKED_MAILBOX,
31
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000032 /** The vCPU is waiting for an interrupt. */
Fuad Tabba5c738432019-12-02 11:02:42 +000033 VCPU_STATE_BLOCKED_INTERRUPT,
34
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000035 /** The vCPU has aborted. */
Fuad Tabba5c738432019-12-02 11:02:42 +000036 VCPU_STATE_ABORTED,
37};
38
39struct interrupts {
40 /** Bitfield keeping track of which interrupts are enabled. */
41 uint32_t interrupt_enabled[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
42 /** Bitfield keeping track of which interrupts are pending. */
43 uint32_t interrupt_pending[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
44 /**
45 * The number of interrupts which are currently both enabled and
46 * pending. i.e. the number of bits set in interrupt_enable &
47 * interrupt_pending.
48 */
49 uint32_t enabled_and_pending_count;
50};
51
52struct vcpu_fault_info {
53 ipaddr_t ipaddr;
54 vaddr_t vaddr;
55 vaddr_t pc;
56 uint32_t mode;
57};
58
59struct vcpu {
60 struct spinlock lock;
61
62 /*
63 * The state is only changed in the context of the vCPU being run. This
64 * ensures the scheduler can easily keep track of the vCPU state as
65 * transitions are indicated by the return code from the run call.
66 */
67 enum vcpu_state state;
68
69 struct cpu *cpu;
70 struct vm *vm;
71 struct arch_regs regs;
72 struct interrupts interrupts;
73
74 /*
75 * Determine whether the 'regs' field is available for use. This is set
76 * to false when a vCPU is about to run on a physical CPU, and is set
77 * back to true when it is descheduled.
78 */
79 bool regs_available;
Olivier Deprezee9d6a92019-11-26 09:14:11 +000080
81 /*
82 * If the current vCPU is executing as a consequence of a
83 * FFA_MSG_SEND_DIRECT_REQ invocation, then this member holds the
84 * originating VM ID from which the call originated.
85 * The value HF_INVALID_VM_ID implies the vCPU is not executing as
86 * a result of a prior FFA_MSG_SEND_DIRECT_REQ invocation.
87 */
88 ffa_vm_id_t direct_request_origin_vm_id;
Fuad Tabba5c738432019-12-02 11:02:42 +000089};
90
91/** Encapsulates a vCPU whose lock is held. */
92struct vcpu_locked {
93 struct vcpu *vcpu;
94};
95
Olivier Deprez0b6f10a2020-08-05 18:21:33 +020096/** Container for two vcpu_locked structures. */
97struct two_vcpu_locked {
98 struct vcpu_locked vcpu1;
99 struct vcpu_locked vcpu2;
100};
101
Fuad Tabba5c738432019-12-02 11:02:42 +0000102struct vcpu_locked vcpu_lock(struct vcpu *vcpu);
Olivier Deprez0b6f10a2020-08-05 18:21:33 +0200103struct two_vcpu_locked vcpu_lock_both(struct vcpu *vcpu1, struct vcpu *vcpu2);
Fuad Tabba5c738432019-12-02 11:02:42 +0000104void vcpu_unlock(struct vcpu_locked *locked);
105void vcpu_init(struct vcpu *vcpu, struct vm *vm);
106void vcpu_on(struct vcpu_locked vcpu, ipaddr_t entry, uintreg_t arg);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +0100107ffa_vcpu_index_t vcpu_index(const struct vcpu *vcpu);
Fuad Tabba5c738432019-12-02 11:02:42 +0000108bool vcpu_is_off(struct vcpu_locked vcpu);
109bool vcpu_secondary_reset_and_start(struct vcpu *vcpu, ipaddr_t entry,
110 uintreg_t arg);
111
112bool vcpu_handle_page_fault(const struct vcpu *current,
113 struct vcpu_fault_info *f);
Olivier Deprez2ebae3a2020-06-11 16:34:30 +0200114
115struct vcpu *vcpu_get_other_world_counterpart(struct vcpu *current);
Olivier Depreze6f7b9d2021-02-01 11:55:48 +0100116void vcpu_reset(struct vcpu *vcpu);