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#include <autoconf.h>
13#include <sel4platsupport/gen_config.h>
14#include <sel4platsupport/device.h>
15#include <sel4platsupport/irq.h>
16#include <sel4platsupport/platsupport.h>
17#include <stddef.h>
18#include <vka/capops.h>
19#include <utils/util.h>
20
21seL4_Error sel4platsupport_copy_irq_cap(vka_t *vka, simple_t *simple, ps_irq_t *irq, cspacepath_t *dest)
22{
23    seL4_CPtr cap;
24
25    /* allocate a cslot for the irq cap */
26    int error = vka_cspace_alloc(vka, &cap);
27    if (error != 0) {
28        ZF_LOGE("Failed to allocate cslot for irq");
29        return error;
30    }
31
32    vka_cspace_make_path(vka, cap, dest);
33    assert(irq->type != PS_NONE);
34    if (irq->type == PS_INTERRUPT) {
35        error = simple_get_IRQ_handler(simple, irq->irq.number, *dest);
36    } else {
37        error = sel4platsupport_arch_copy_irq_cap(&simple->arch_simple, irq, dest);
38    }
39
40    if (error != seL4_NoError) {
41        ZF_LOGE("Failed to get cap for irq");
42        vka_cspace_free(vka, cap);
43    }
44    return error;
45}
46
47seL4_Error sel4platsupport_alloc_frame_at(vka_t *vka, uintptr_t paddr, size_t size_bits, vka_object_t *frame)
48{
49    /* find the physical frame */
50    int error = vka_alloc_frame_at(vka, size_bits, paddr, frame);
51    if (error) {
52        ZF_LOGE("Failed to find frame at paddr %p", (void *)paddr);
53    }
54
55    return error;
56}
57
58void *sel4platsupport_map_frame_at(vka_t *vka, vspace_t *vspace, uintptr_t paddr, size_t size_bits, vka_object_t *frame)
59{
60    int error;
61    error = sel4platsupport_alloc_frame_at(vka, paddr, size_bits, frame);
62    if (error) {
63        return NULL;
64    }
65    void *vaddr = vspace_map_pages(vspace, &frame->cptr, &frame->ut, seL4_AllRights, 1, size_bits, 0);
66    if (!vaddr) {
67        ZF_LOGE("Failed to map frame at paddr %p", (void *)paddr);
68        vka_free_object(vka, frame);
69    }
70    return vaddr;
71}
72