| /* |
| * Copyright 2017, Data61 |
| * Commonwealth Scientific and Industrial Research Organisation (CSIRO) |
| * ABN 41 687 119 230. |
| * |
| * This software may be distributed and modified according to the terms of |
| * the BSD 2-Clause license. Note that NO WARRANTY is provided. |
| * See "LICENSE_BSD2.txt" for details. |
| * |
| * @TAG(DATA61_BSD) |
| */ |
| #include <autoconf.h> |
| #include <sel4platsupport/gen_config.h> |
| #include <sel4platsupport/device.h> |
| #include <sel4platsupport/irq.h> |
| #include <sel4platsupport/platsupport.h> |
| #include <stddef.h> |
| #include <vka/capops.h> |
| #include <utils/util.h> |
| |
| seL4_Error sel4platsupport_copy_irq_cap(vka_t *vka, simple_t *simple, ps_irq_t *irq, cspacepath_t *dest) |
| { |
| seL4_CPtr cap; |
| |
| /* allocate a cslot for the irq cap */ |
| int error = vka_cspace_alloc(vka, &cap); |
| if (error != 0) { |
| ZF_LOGE("Failed to allocate cslot for irq"); |
| return error; |
| } |
| |
| vka_cspace_make_path(vka, cap, dest); |
| assert(irq->type != PS_NONE); |
| if (irq->type == PS_INTERRUPT) { |
| error = simple_get_IRQ_handler(simple, irq->irq.number, *dest); |
| } else { |
| error = sel4platsupport_arch_copy_irq_cap(&simple->arch_simple, irq, dest); |
| } |
| |
| if (error != seL4_NoError) { |
| ZF_LOGE("Failed to get cap for irq"); |
| vka_cspace_free(vka, cap); |
| } |
| return error; |
| } |
| |
| seL4_Error sel4platsupport_alloc_frame_at(vka_t *vka, uintptr_t paddr, size_t size_bits, vka_object_t *frame) |
| { |
| /* find the physical frame */ |
| int error = vka_alloc_frame_at(vka, size_bits, paddr, frame); |
| if (error) { |
| ZF_LOGE("Failed to find frame at paddr %p", (void *)paddr); |
| } |
| |
| return error; |
| } |
| |
| void *sel4platsupport_map_frame_at(vka_t *vka, vspace_t *vspace, uintptr_t paddr, size_t size_bits, vka_object_t *frame) |
| { |
| int error; |
| error = sel4platsupport_alloc_frame_at(vka, paddr, size_bits, frame); |
| if (error) { |
| return NULL; |
| } |
| void *vaddr = vspace_map_pages(vspace, &frame->cptr, &frame->ut, seL4_AllRights, 1, size_bits, 0); |
| if (!vaddr) { |
| ZF_LOGE("Failed to map frame at paddr %p", (void *)paddr); |
| vka_free_object(vka, frame); |
| } |
| return vaddr; |
| } |