1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#include <autoconf.h>
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <assert.h>
18
19#include <sel4/sel4.h>
20
21#include <simple-default/simple-default.h>
22#include <utils/util.h>
23#include <vspace/page.h>
24
25seL4_Error
26simple_default_get_ioapic(void *data, seL4_CNode root, seL4_Word index, uint8_t depth,
27                          seL4_Word ioapic, seL4_Word pin, seL4_Word level, seL4_Word polarity,
28                          seL4_Word vector)
29{
30    return seL4_IRQControl_GetIOAPIC(seL4_CapIRQControl, root, index, depth, ioapic, pin, level,
31                                     polarity, vector);
32}
33
34seL4_Error
35simple_default_get_irq(void *data, int irq, seL4_CNode root, seL4_Word index, uint8_t depth) {
36
37    if (config_set(CONFIG_IRQ_IOAPIC)) {
38        /* we need to try and guess how to map a requested IRQ to an IOAPIC
39         * pin, as well as what the edge and polarity detection mode is.
40         * Without any way to inspect the ACPI tables here we make the following
41         * assumptions
42         *   + There is an override for ISA-IRQ-0 -> GSI 2
43         *   + Only one IOAPIC and error on IRQs >= 24
44         *   + IRQs below 16 are ISA and edge detected polarity high
45         *   + IRQs 16 and above are PCI and level detected polarity low
46         */
47        int vector = irq;
48        if (irq == 0) {
49            irq = 2;
50        }
51        int level;
52        int low_polarity;
53        if (irq >= 16) {
54            level = 1;
55            low_polarity = 1;
56        } else {
57            level = 0;
58            low_polarity = 0;
59        }
60        return simple_default_get_ioapic(data, root, index, depth, 0, irq, level, low_polarity, vector);
61    } else {
62        return seL4_IRQControl_Get(seL4_CapIRQControl, irq, root, index, depth);
63    }
64}
65
66seL4_Error
67simple_default_get_msi(void *data, seL4_CNode root, seL4_Word index, uint8_t depth,
68                       seL4_Word pci_bus, seL4_Word pci_dev, seL4_Word pci_func, seL4_Word handle,
69                       seL4_Word vector)
70{
71    return seL4_IRQControl_GetMSI(seL4_CapIRQControl, root, index, depth, pci_bus, pci_dev,
72                                  pci_func, handle, vector);
73}
74
75seL4_Error
76simple_default_get_IOPort_cap(void *data, uint16_t start_port, uint16_t end_port, seL4_Word root, seL4_Word dest, seL4_Word depth) {
77    return seL4_X86_IOPortControl_Issue(seL4_CapIOPortControl, start_port, end_port, root, dest, depth);
78}
79
80void
81simple_default_init_arch_simple(arch_simple_t *simple, void *data)
82{
83    simple->data = data;
84    simple->msi = simple_default_get_msi;
85    simple->irq = simple_default_get_irq;
86    simple->ioapic = simple_default_get_ioapic;
87    simple->IOPort_cap = simple_default_get_IOPort_cap;
88}
89