blob: 9e9f2d40160b7219ce40018fc2521fa2ed31ed51 [file] [log] [blame]
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#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;
}