1// Copyright 2018 The Fuchsia Authors
2//
3// Use of this source code is governed by a MIT-style
4// license that can be found in the LICENSE file or at
5// https://opensource.org/licenses/MIT
6
7#include <arch/arm64/hypervisor/gic/el2.h>
8#include <arch/arm64/hypervisor/gic/gicv3.h>
9#include <dev/interrupt/arm_gic_hw_interface.h>
10#include <dev/interrupt/arm_gicv3_regs.h>
11
12static uint32_t gicv3_read_gich_hcr() {
13    return arm64_el2_gicv3_read_gich_hcr();
14}
15
16static void gicv3_write_gich_hcr(uint32_t val) {
17    arm64_el2_gicv3_write_gich_hcr(val);
18}
19
20static uint32_t gicv3_read_gich_vtr() {
21    return arm64_el2_gicv3_read_gich_vtr();
22}
23
24static uint32_t gicv3_default_gich_vmcr() {
25    return ICH_VMCR_VPMR_MASK | ICH_VMCR_VENG1;
26}
27
28static uint32_t gicv3_read_gich_vmcr() {
29    return arm64_el2_gicv3_read_gich_vmcr();
30}
31
32static void gicv3_write_gich_vmcr(uint32_t val) {
33    arm64_el2_gicv3_write_gich_vmcr(val);
34}
35
36static uint32_t gicv3_read_gich_misr() {
37    return arm64_el2_gicv3_read_gich_misr();
38}
39
40static uint64_t gicv3_read_gich_elrsr() {
41    return arm64_el2_gicv3_read_gich_elrsr();
42}
43
44static uint32_t gicv3_read_gich_apr() {
45    return arm64_el2_gicv3_read_gich_apr();
46}
47
48static void gicv3_write_gich_apr(uint32_t val) {
49    arm64_el2_gicv3_write_gich_apr(val);
50}
51
52static uint64_t gicv3_read_gich_lr(uint32_t idx) {
53    return arm64_el2_gicv3_read_gich_lr(idx);
54}
55
56static void gicv3_write_gich_lr(uint32_t idx, uint64_t val) {
57    arm64_el2_gicv3_write_gich_lr(val, idx);
58}
59
60static zx_status_t gicv3_get_gicv(paddr_t* gicv_paddr) {
61    // Check for presence of GICv3 virtualisation extensions.
62    // We return ZX_ERR_NOT_FOUND since this API is used to get
63    // address of GICV base to map it to guest
64    // On GICv3 we do not need to map this region, since we use system registers
65
66    return ZX_ERR_NOT_FOUND;
67}
68
69static uint64_t gicv3_get_lr_from_vector(uint32_t vector) {
70    return (vector & ICH_LR_VIRTUAL_ID_MASK) | ICH_LR_GROUP1 | ICH_LR_PENDING;
71}
72
73static uint32_t gicv3_get_vector_from_lr(uint64_t lr) {
74    return lr & ICH_LR_VIRTUAL_ID_MASK;
75}
76
77static uint32_t gicv3_get_num_lrs() {
78    return (gicv3_read_gich_vtr() & ICH_VTR_LIST_REGS_MASK) + 1;
79}
80
81static const struct arm_gic_hw_interface_ops gic_hw_register_ops = {
82    .read_gich_hcr = gicv3_read_gich_hcr,
83    .write_gich_hcr = gicv3_write_gich_hcr,
84    .read_gich_vtr = gicv3_read_gich_vtr,
85    .default_gich_vmcr = gicv3_default_gich_vmcr,
86    .read_gich_vmcr = gicv3_read_gich_vmcr,
87    .write_gich_vmcr = gicv3_write_gich_vmcr,
88    .read_gich_misr = gicv3_read_gich_misr,
89    .read_gich_elrsr = gicv3_read_gich_elrsr,
90    .read_gich_apr = gicv3_read_gich_apr,
91    .write_gich_apr = gicv3_write_gich_apr,
92    .read_gich_lr = gicv3_read_gich_lr,
93    .write_gich_lr = gicv3_write_gich_lr,
94    .get_gicv = gicv3_get_gicv,
95    .get_lr_from_vector = gicv3_get_lr_from_vector,
96    .get_vector_from_lr = gicv3_get_vector_from_lr,
97    .get_num_lrs = gicv3_get_num_lrs,
98};
99
100void gicv3_hw_interface_register() {
101    arm_gic_hw_interface_register(&gic_hw_register_ops);
102}
103
104bool gicv3_is_gic_registered() {
105    return arm_gic_is_registered();
106}
107