blob: f227ecebc25efacbd9f00ba46b4dd2369594138a [file] [log] [blame]
Daniel Boulbyf3cf28c2024-08-22 10:46:23 +01001/*
2 * Copyright 2024 The Hafnium Authors.
3 *
4 * 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.
7 */
8
9#include "hf/hf_ipi.h"
10
Daniel Boulby960be202024-08-22 10:53:11 +010011#include "hf/arch/plat/ffa.h"
12
Daniel Boulbyf3cf28c2024-08-22 10:46:23 +010013#include "hf/cpu.h"
14#include "hf/plat/interrupts.h"
15
16/** Interrupt priority for Inter-Processor Interrupt. */
17#define IPI_PRIORITY 0x0U
18
19/**
20 * Initialize the IPI SGI.
21 */
22void hf_ipi_init_interrupt(void)
23{
24 /* Configure as a Secure SGI. */
25 struct interrupt_descriptor ipi_desc = {
26 .interrupt_id = HF_IPI_INTID,
27 .type = INT_DESC_TYPE_SGI,
28 .sec_state = INT_DESC_SEC_STATE_S,
29 .priority = IPI_PRIORITY,
30 .valid = true,
31 };
32
33 plat_interrupts_configure_interrupt(ipi_desc);
34}
35
36/**
37 * Returns the target_vcpu for the pending IPI on the current CPU and
38 * resets the item in the list to NULL to show it has been retrieved.
39 */
40struct vcpu *hf_ipi_get_pending_target_vcpu(struct cpu *current)
41{
42 struct vcpu *ret = current->ipi_target_vcpu;
43
44 current->ipi_target_vcpu = NULL;
45 return ret;
46}
47
48/**
49 * Send and record the IPI for the target vCPU.
50 */
51void hf_ipi_send_interrupt(struct vm *vm, ffa_vcpu_index_t target_vcpu_index)
52{
53 struct vcpu *target_vcpu = vm_get_vcpu(vm, target_vcpu_index);
54 struct cpu *target_cpu = target_vcpu->cpu;
55
56 target_cpu->ipi_target_vcpu = target_vcpu;
57 plat_interrupts_send_sgi(HF_IPI_INTID, target_cpu, true);
58}
59
60/**
61 * IPI IRQ specific handling for the secure interrupt for each vCPU state:
62 * - RUNNING: Continue secure interrupt handling as normal, injecting
63 * a virtual interrupt to the vCPU.
Daniel Boulby960be202024-08-22 10:53:11 +010064 * - WAITING: Mark the IPI as complete from the SPMC perspective and
65 * trigger an SRI so the NWd can schedule to target vCPU to run.
Daniel Boulbyf3cf28c2024-08-22 10:46:23 +010066 * - Other states are not currently supported so exit the handler.
67 * Returns True if the IPI SGI has been handled.
68 * False if further secure interrupt handling is required.
69 */
70bool hf_ipi_handle(struct vcpu_locked target_vcpu_locked)
71{
72 struct vcpu *target_vcpu = target_vcpu_locked.vcpu;
73
74 switch (target_vcpu->state) {
75 case VCPU_STATE_RUNNING:
76 return false;
Daniel Boulby960be202024-08-22 10:53:11 +010077 case VCPU_STATE_WAITING:
Daniel Boulby960be202024-08-22 10:53:11 +010078 plat_ffa_sri_trigger_not_delayed(target_vcpu->cpu);
79 return true;
Daniel Boulbyf3cf28c2024-08-22 10:46:23 +010080 default:
81 dlog_verbose(
82 "IPIs not currently supported for when the target_vcpu "
83 "is in the state %d\n",
84 target_vcpu->state);
Daniel Boulbyf3cf28c2024-08-22 10:46:23 +010085 return true;
86 }
87}