blob: 9e9f2d40160b7219ce40018fc2521fa2ed31ed51 [file] [log] [blame]
Anna Lyonsadbaab72016-03-29 13:59:06 +11001/*
Gerwin Klein600fe152021-02-10 19:19:17 +11002 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
Anna Lyonsadbaab72016-03-29 13:59:06 +11003 *
Gerwin Klein600fe152021-02-10 19:19:17 +11004 * SPDX-License-Identifier: BSD-2-Clause
Anna Lyonsadbaab72016-03-29 13:59:06 +11005 */
6#include <autoconf.h>
Yu Houe23dc542019-05-20 15:29:15 +10007#include <sel4platsupport/gen_config.h>
Anna Lyonsadbaab72016-03-29 13:59:06 +11008#include <sel4platsupport/device.h>
Anna Lyons882395e2017-07-20 11:07:46 +10009#include <sel4platsupport/irq.h>
Anna Lyonsadbaab72016-03-29 13:59:06 +110010#include <sel4platsupport/platsupport.h>
Matthew Fernandez92702162016-06-10 15:35:43 +100011#include <stddef.h>
Anna Lyonsadbaab72016-03-29 13:59:06 +110012#include <vka/capops.h>
13#include <utils/util.h>
14
Yu Houe9a9ff42019-07-18 17:26:01 +100015seL4_Error sel4platsupport_copy_irq_cap(vka_t *vka, simple_t *simple, ps_irq_t *irq, cspacepath_t *dest)
Anna Lyonsadbaab72016-03-29 13:59:06 +110016{
Anna Lyons882395e2017-07-20 11:07:46 +100017 seL4_CPtr cap;
Anna Lyonsadbaab72016-03-29 13:59:06 +110018
19 /* allocate a cslot for the irq cap */
Anna Lyons882395e2017-07-20 11:07:46 +100020 int error = vka_cspace_alloc(vka, &cap);
Anna Lyonsadbaab72016-03-29 13:59:06 +110021 if (error != 0) {
Adrian Danisa0b6bbf2017-01-11 17:15:49 +110022 ZF_LOGE("Failed to allocate cslot for irq");
Anna Lyonsadbaab72016-03-29 13:59:06 +110023 return error;
24 }
25
Anna Lyons882395e2017-07-20 11:07:46 +100026 vka_cspace_make_path(vka, cap, dest);
27 assert(irq->type != PS_NONE);
28 if (irq->type == PS_INTERRUPT) {
29 error = simple_get_IRQ_handler(simple, irq->irq.number, *dest);
30 } else {
31 error = sel4platsupport_arch_copy_irq_cap(&simple->arch_simple, irq, dest);
Anna Lyonsadbaab72016-03-29 13:59:06 +110032 }
33
Yu Houe9a9ff42019-07-18 17:26:01 +100034 if (error != seL4_NoError) {
Anna Lyons882395e2017-07-20 11:07:46 +100035 ZF_LOGE("Failed to get cap for irq");
36 vka_cspace_free(vka, cap);
37 }
38 return error;
Anna Lyonsadbaab72016-03-29 13:59:06 +110039}
Anna Lyonsadbaab72016-03-29 13:59:06 +110040
Yu Houe9a9ff42019-07-18 17:26:01 +100041seL4_Error sel4platsupport_alloc_frame_at(vka_t *vka, uintptr_t paddr, size_t size_bits, vka_object_t *frame)
Anna Lyons76fcd2c2016-10-05 12:21:33 +110042{
Anna Lyonsadbaab72016-03-29 13:59:06 +110043 /* find the physical frame */
Anna Lyons76fcd2c2016-10-05 12:21:33 +110044 int error = vka_alloc_frame_at(vka, size_bits, paddr, frame);
Anna Lyonsadbaab72016-03-29 13:59:06 +110045 if (error) {
Yu Houe9a9ff42019-07-18 17:26:01 +100046 ZF_LOGE("Failed to find frame at paddr %p", (void *)paddr);
Anna Lyonsadbaab72016-03-29 13:59:06 +110047 }
48
49 return error;
50}
51
Yu Houe9a9ff42019-07-18 17:26:01 +100052void *sel4platsupport_map_frame_at(vka_t *vka, vspace_t *vspace, uintptr_t paddr, size_t size_bits, vka_object_t *frame)
Adrian Danis9f3238b2017-01-11 17:17:14 +110053{
54 int error;
55 error = sel4platsupport_alloc_frame_at(vka, paddr, size_bits, frame);
56 if (error) {
57 return NULL;
58 }
59 void *vaddr = vspace_map_pages(vspace, &frame->cptr, &frame->ut, seL4_AllRights, 1, size_bits, 0);
60 if (!vaddr) {
Yu Houe9a9ff42019-07-18 17:26:01 +100061 ZF_LOGE("Failed to map frame at paddr %p", (void *)paddr);
Adrian Danis9f3238b2017-01-11 17:17:14 +110062 vka_free_object(vka, frame);
63 }
64 return vaddr;
65}