blob: 6d1267917a4dc3eb0bf429a2101b677d38e129cb [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;
80};
81
82/** Encapsulates a vCPU whose lock is held. */
83struct vcpu_locked {
84 struct vcpu *vcpu;
85};
86
Olivier Deprez0b6f10a2020-08-05 18:21:33 +020087/** Container for two vcpu_locked structures. */
88struct two_vcpu_locked {
89 struct vcpu_locked vcpu1;
90 struct vcpu_locked vcpu2;
91};
92
Fuad Tabba5c738432019-12-02 11:02:42 +000093struct vcpu_locked vcpu_lock(struct vcpu *vcpu);
Olivier Deprez0b6f10a2020-08-05 18:21:33 +020094struct two_vcpu_locked vcpu_lock_both(struct vcpu *vcpu1, struct vcpu *vcpu2);
Fuad Tabba5c738432019-12-02 11:02:42 +000095void vcpu_unlock(struct vcpu_locked *locked);
96void vcpu_init(struct vcpu *vcpu, struct vm *vm);
97void vcpu_on(struct vcpu_locked vcpu, ipaddr_t entry, uintreg_t arg);
Andrew Walbranb5ab43c2020-04-30 11:32:54 +010098ffa_vcpu_index_t vcpu_index(const struct vcpu *vcpu);
Fuad Tabba5c738432019-12-02 11:02:42 +000099bool vcpu_is_off(struct vcpu_locked vcpu);
100bool vcpu_secondary_reset_and_start(struct vcpu *vcpu, ipaddr_t entry,
101 uintreg_t arg);
102
103bool vcpu_handle_page_fault(const struct vcpu *current,
104 struct vcpu_fault_info *f);