1235633Sdim/* 2221345Sdim * Copyright 2017, Data61 3193323Sed * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4193323Sed * ABN 41 687 119 230. 5193323Sed * 6193323Sed * This software may be distributed and modified according to the terms of 7221345Sdim * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8193323Sed * See "LICENSE_BSD2.txt" for details. 9193323Sed * 10193323Sed * @TAG(DATA61_BSD) 11193323Sed */ 12193323Sed 13221345Sdim#pragma once 14193323Sed 15193323Sed#include <autoconf.h> 16193323Sed 17193323Sed#include <assert.h> 18193323Sed#include <sel4/sel4.h> 19193323Sed#include <stdlib.h> 20221345Sdim#include <utils/util.h> 21193323Sed#include <vka/cspacepath_t.h> 22193323Sed 23224145Sdim/* Simple does not address initial null caps, including seL4_CapNull */ 24224145Sdim#ifdef CONFIG_IOMMU 25193323Sed#define SIMPLE_SKIPPED_INIT_CAPS 1 26202878Srdivacky#else 27202878Srdivacky/* seL4_CapIOSpace is null if IOMMU isn't supported */ 28193323Sed#define SIMPLE_SKIPPED_INIT_CAPS 2 29263509Sdim#endif 30263509Sdim 31263509Sdim/** 32263509Sdim * Request a cap to the IOPorts 33193323Sed * 34193323Sed * @param data cookie for the underlying implementation 35193323Sed * @param start port number that a cap is needed to 36226890Sdim * @param end port number that a cap is needed to 37226890Sdim * @param root The CNode in which to put this cap 38226890Sdim * @param dest The index within the CNode to put the cap 39226890Sdim * @param depth of index 40235633Sdim */ 41235633Sdimtypedef seL4_Error (*arch_simple_get_IOPort_cap_fn)(void *data, uint16_t start_port, uint16_t end_port, seL4_Word root, seL4_Word dest, seL4_Word depth); 42226890Sdim 43226890Sdim/** 44235633Sdim * Request a cap to a specific MSI IRQ number on the system 45235633Sdim * 46235633Sdim * @param irq the msi irq number to get the cap for 47235633Sdim * @param data cookie for the underlying implementation 48235633Sdim * @param the CNode in which to put this cap 49226890Sdim * @param the index within the CNode to put cap 50226890Sdim * @param Depth of index 51226890Sdim */ 52226890Sdimtypedef seL4_Error (*arch_simple_get_msi_fn)(void *data, seL4_CNode root, seL4_Word index, 53226890Sdim uint8_t depth, seL4_Word pci_bus, seL4_Word pci_dev, 54226890Sdim seL4_Word pci_func, seL4_Word handle, 55226890Sdim seL4_Word vector); 56226890Sdim 57226890Sdimtypedef seL4_Error (*arch_simple_get_ioapic_fn)(void *data, seL4_CNode root, seL4_Word index, 58226890Sdim uint8_t depth, seL4_Word ioapic, seL4_Word pin, 59226890Sdim seL4_Word level, seL4_Word polarity, 60226890Sdim seL4_Word vector); 61226890Sdim 62226890Sdim/** 63226890Sdim * Request a cap to a specific IRQ number on the system 64226890Sdim * 65226890Sdim * @param irq the irq number to get the cap for 66226890Sdim * @param data cookie for the underlying implementation 67235633Sdim * @param the CNode in which to put this cap 68235633Sdim * @param the index within the CNode to put cap 69226890Sdim * @param Depth of index 70226890Sdim */ 71235633Sdimtypedef seL4_Error (*arch_simple_get_IRQ_handler_fn)(void *data, int irq, seL4_CNode cnode, seL4_Word index, 72235633Sdim uint8_t depth); 73235633Sdim 74235633Sdim#ifdef CONFIG_IOMMU 75235633Sdim/** 76235633Sdim * Get the IO space capability for the specified PCI device and domain ID 77235633Sdim * 78235633Sdim * @param data cookie for the underlying implementation 79235633Sdim * @param domainID domain ID to request 80235633Sdim * @param deviceID PCI device ID 81235633Sdim * @param path Path to where to put this cap 82235633Sdim * 83235633Sdim*/ 84235633Sdimtypedef seL4_Error (*arch_simple_get_iospace_fn)(void *data, uint16_t domainID, uint16_t deviceID, 85235633Sdim cspacepath_t *path); 86235633Sdim 87226890Sdim#endif 88226890Sdim 89226890Sdimtypedef struct arch_simple { 90226890Sdim void *data; 91226890Sdim arch_simple_get_IOPort_cap_fn IOPort_cap; 92226890Sdim#ifdef CONFIG_IOMMU 93226890Sdim arch_simple_get_iospace_fn iospace; 94226890Sdim#endif 95226890Sdim arch_simple_get_msi_fn msi; 96226890Sdim arch_simple_get_IRQ_handler_fn irq; 97226890Sdim arch_simple_get_ioapic_fn ioapic; 98226890Sdim} arch_simple_t; 99226890Sdim 100226890Sdimstatic inline seL4_Error 101252723Sdimarch_simple_get_IOPort_cap(arch_simple_t *arch_simple, uint16_t start_port, uint16_t end_port, seL4_Word root, seL4_Word dest, seL4_Word depth) 102252723Sdim{ 103252723Sdim if (!arch_simple) { 104252723Sdim ZF_LOGE("Arch-simple is NULL"); 105252723Sdim return seL4_InvalidArgument; 106252723Sdim } 107226890Sdim 108193323Sed if (!arch_simple->IOPort_cap) { 109193323Sed ZF_LOGE("%s not implemented", __FUNCTION__); 110193323Sed return seL4_InvalidArgument; 111193323Sed } 112193323Sed 113193323Sed return arch_simple->IOPort_cap(arch_simple->data, start_port, end_port, root, dest, depth); 114193323Sed} 115193323Sed 116193323Sedstatic inline seL4_Error 117193323Sedarch_simple_get_msi(arch_simple_t *arch_simple, cspacepath_t path, seL4_Word pci_bus, 118221345Sdim seL4_Word pci_dev, seL4_Word pci_func, seL4_Word handle, 119221345Sdim seL4_Word vector) 120193323Sed{ 121193323Sed if (!arch_simple) { 122221345Sdim ZF_LOGE("Arch-simple is NULL"); 123193323Sed return seL4_InvalidArgument; 124193323Sed } 125221345Sdim 126221345Sdim if (!arch_simple->msi) { 127193323Sed ZF_LOGE("%s not implemented", __FUNCTION__); 128193323Sed } 129193323Sed 130193323Sed return arch_simple->msi(arch_simple->data, path.root, path.capPtr, path.capDepth, pci_bus, 131193323Sed pci_dev, pci_func, handle, vector); 132193323Sed} 133193323Sed 134193323Sedstatic inline seL4_Error 135193323Sedarch_simple_get_ioapic(arch_simple_t *arch_simple, cspacepath_t path, seL4_Word ioapic, 136193323Sed seL4_Word pin, seL4_Word level, seL4_Word polarity, 137193323Sed seL4_Word vector) 138193323Sed{ 139193323Sed if (!arch_simple) { 140193323Sed ZF_LOGE("Arch-simple is NULL"); 141193323Sed return seL4_InvalidArgument; 142193323Sed } 143193323Sed 144193323Sed if (!arch_simple->ioapic) { 145193323Sed ZF_LOGE("%s not implemented", __FUNCTION__); 146193323Sed } 147193323Sed 148193323Sed return arch_simple->ioapic(arch_simple->data, path.root, path.capPtr, path.capDepth, ioapic, 149193323Sed pin, level, polarity, vector); 150245431Sdim} 151245431Sdim 152245431Sdim#ifdef CONFIG_IOMMU 153245431Sdimstatic inline seL4_CPtr 154263509Sdimarch_simple_get_iospace(arch_simple_t *arch_simple, uint16_t domainID, uint16_t deviceID, cspacepath_t *path) 155263509Sdim{ 156263509Sdim if (!arch_simple) { 157263509Sdim ZF_LOGE("Arch-simple is NULL"); 158263509Sdim return seL4_CapNull; 159263509Sdim } 160263509Sdim if (!arch_simple->iospace) { 161263509Sdim ZF_LOGE("%s not implemented", __FUNCTION__); 162263509Sdim return seL4_CapNull; 163263509Sdim } 164245431Sdim 165245431Sdim return arch_simple->iospace(arch_simple->data, domainID, deviceID, path); 166245431Sdim} 167245431Sdim#endif 168245431Sdim 169245431Sdim