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#pragma once 14 15#include <sel4platsupport/pmem.h> 16#include <platsupport/timer.h> 17#include <platsupport/ltimer.h> 18#include <sel4platsupport/irq.h> 19#include <simple/simple.h> 20#include <vka/vka.h> 21#include <vka/object.h> 22#include <vspace/vspace.h> 23 24#define MAX_IRQS 4 25#define MAX_OBJS 4 26 27typedef struct seL4_timer seL4_timer_t; 28 29typedef void (*handle_irq_fn_t)(seL4_timer_t *timer, uint32_t irq); 30typedef void (*destroy_fn_t)(seL4_timer_t *timer, vka_t *vka, vspace_t *vspace); 31 32typedef struct timer_objects { 33 /* this struct is copied using c's struct deep copy semantics. 34 * avoid adding pointers to it */ 35 size_t nirqs; 36 sel4ps_irq_t irqs[MAX_IRQS]; 37 size_t nobjs; 38 sel4ps_pmem_t objs[MAX_OBJS]; 39} timer_objects_t; 40 41struct seL4_timer { 42 /* os independent timer interface */ 43 ltimer_t ltimer; 44 45 /* objects allocated for this timer */ 46 timer_objects_t to; 47 48 /* sel4 specific functions to call to deal with timer */ 49 handle_irq_fn_t handle_irq; 50 51 /* destroy this timer, it will no longer be valid */ 52 destroy_fn_t destroy; 53}; 54 55/** 56 * Creates caps required for calling sel4platsupport_get_default_timer and stores them 57 * in supplied timer_objects_t. 58 * 59 * Uses the provided vka, vspace and simple interfaces for creating the caps. 60 * (A vspace is required because on some platforms devices may need to be mapped in 61 * order to query hardware features.) 62 * 63 * @param vka Allocator to allocate objects with 64 * @param vspace vspace for mapping device frames into memory if necessary. 65 * @param simple simple interface for access to init caps 66 * @param timer_objects struct for returning cap meta data. 67 * @return 0 on success, otherwise failure. 68 */ 69int sel4platsupport_init_default_timer_caps(vka_t *vka, vspace_t *vspace, simple_t *simple, 70 timer_objects_t *timer_objects); 71 72/* 73 * Initialise the default timer for this platform and do all of the seL4 related work. 74 * 75 * After this operation is complete, the irqs from the ltimer will be delivered to the 76 * provided notification object with badges of BIT(seL4_BadgeBits - 1) - n where n is the index 77 * of the irq in the default ltimer. 78 * 79 * The passed ops interface is retained by the timer and must stay valid until the timer is destroyed 80 * 81 * @param vka an initialised vka implementation that can allocate the physical 82 * addresses (if any) required by the ltimer. 83 * @param vspace an initialised vspace for manging virtual memory. 84 * @param simple for getting irq capabilities for the ltimer irqs. 85 * @param ops I/O ops interface for interacting with hardware resources 86 * @param ntfn notification object capability for irqs to be delivered to. 87 * @param timer a timer structure to initialise. 88 * @return 0 on success. 89 */ 90int sel4platsupport_init_default_timer_ops(vka_t *vka, vspace_t *vspace, simple_t *simple, ps_io_ops_t ops, 91 seL4_CPtr notification, seL4_timer_t *timer); 92 93/* 94 * Wrapper around sel4platsupport_init_default_timer_ops that generates as much of an 95 * io_ops interface as it can from the given vka and vspace 96 */ 97int sel4platsupport_init_default_timer(vka_t *vka, vspace_t *vspace, simple_t *simple, 98 seL4_CPtr notification, seL4_timer_t *timer); 99/* 100 * Initialise an seL4_timer with irqs from provided timer objects. As per sel4platsupport_init_timer, 101 * timer_objects are provided and the user is expected to initialise the ltimer after calling this function 102 * (to avoid unacked irqs due to irq caps not being set up). 103 * 104 * This function just does the seL4 parts of the timer init. 105 * 106 * 107 * @param vka an initialised vka implementation that can allocate the physical 108 * address returned by sel4platsupport_get_default_timer_paddr. 109 * @param simple for getting irq capabilities for the ltimer irqs. 110 * @param ntfn notification object capability for irqs to be delivered to. 111 * @param timer a timer structure to populate. 112 * @param objects the timer objects that this timer needs to initialise. 113 * @return 0 on success. 114 */ 115int sel4platsupport_init_timer_irqs(vka_t *vka, simple_t *simple, seL4_CPtr ntfn, 116 seL4_timer_t *timer, timer_objects_t *objects); 117 118/* 119 * Handle a timer irq for this timer. 120 * 121 * @param timer initialised timer. 122 * @param badge badge recieved on the notification object this timer was initialised with. 123 */ 124void sel4platsupport_handle_timer_irq(seL4_timer_t *timer, seL4_Word badge); 125 126/* 127 * Destroy the timer, freeing any resources allocated during initialisation. 128 * 129 * @param timer initialised timer. 130 * @param vka vka used to initialise the timer. 131 * 132 */ 133void sel4platsupport_destroy_timer(seL4_timer_t *timer, vka_t *vka); 134 135/* 136 * Helper function for getting the nth irq cap out of the timer_objects struct if its type is 137 * known. This is often used for initialising an arch_simple interface. 138 * 139 * @param to timer_objects struct containing irq caps. 140 * @param id index of irq in the struct. 141 * @param type Interrupt type 142 * 143 * @return IRQ cap on success, otherwise seL4_CapNull on failure. 144 */ 145seL4_CPtr sel4platsupport_timer_objs_get_irq_cap(timer_objects_t *to, int id, irq_type_t type); 146