summaryrefslogtreecommitdiff
path: root/libdde-linux26/lib/src/arch/l4/res.c
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2013-07-27 22:15:01 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2013-07-27 22:15:01 +0000
commit7996a3d79d55b7f879dfd62e202bbfe2963718d3 (patch)
tree8d9f6759fec4099b9be503c11c7ed174f7204980 /libdde-linux26/lib/src/arch/l4/res.c
parent4fbe7358c7747a9165f776eb19addbb9baf7def2 (diff)
really properly move files
Diffstat (limited to 'libdde-linux26/lib/src/arch/l4/res.c')
-rw-r--r--libdde-linux26/lib/src/arch/l4/res.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/libdde-linux26/lib/src/arch/l4/res.c b/libdde-linux26/lib/src/arch/l4/res.c
new file mode 100644
index 00000000..a2ffb98f
--- /dev/null
+++ b/libdde-linux26/lib/src/arch/l4/res.c
@@ -0,0 +1,188 @@
+#include "local.h"
+
+#include <linux/ioport.h>
+
+/** Request an IO port region.
+ *
+ * \param start start port
+ * \param n number of ports
+ * \param name name of allocator (unused)
+ *
+ * \return NULL error
+ * \return !=NULL success
+ *
+ * \bug Since no one in Linux uses this function's return value,
+ * we do not allocate and fill a resource struct.
+ */
+static struct resource *l4dde26_request_region(resource_size_t start,
+ resource_size_t n,
+ const char *name)
+{
+ int err = ddekit_request_io(start, n);
+
+ if (err)
+ return NULL;
+
+ return (struct resource *)1;
+}
+
+
+/** List of memory regions that have been requested. This is used to
+ * perform ioremap() and iounmap()
+ */
+static LIST_HEAD(dde_mem_regions);
+
+/** va->pa mapping used to store memory regions */
+struct dde_mem_region {
+ ddekit_addr_t pa;
+ ddekit_addr_t va;
+ unsigned int size;
+ struct list_head list;
+};
+
+void __iomem * ioremap(unsigned long phys_addr, unsigned long size);
+
+/** Request an IO memory region.
+ *
+ * \param start start address
+ * \param n size of memory area
+ * \param name name of allocator (unused)
+ *
+ * \return NULL error
+ * \return !=NULL success
+ *
+ * \bug Since no one in Linux uses this function's return value,
+ * we do not allocate and fill a resource struct.
+ */
+static struct resource *l4dde26_request_mem_region(resource_size_t start,
+ resource_size_t n,
+ const char *name)
+{
+ ddekit_addr_t va = 0;
+ struct dde_mem_region *mreg;
+
+ // do not a resource request twice
+ if (ioremap(start, n))
+ return (struct resource *)1;
+
+ int i = ddekit_request_mem(start, n, &va);
+
+ if (i) {
+ ddekit_printf("request_mem_region() failed (start %lx, size %x)", start, n);
+ return NULL;
+ }
+
+ mreg = kmalloc(sizeof(struct dde_mem_region), GFP_KERNEL);
+ Assert(mreg);
+
+ mreg->pa = start;
+ mreg->va = va;
+ mreg->size = n;
+ list_add(&mreg->list, &dde_mem_regions);
+
+#if 0
+ ddekit_pgtab_set_region_with_size((void *)va, start, n, PTE_TYPE_OTHER);
+#endif
+
+ return (struct resource *)1;
+}
+
+
+struct resource * __request_region(struct resource *parent,
+ resource_size_t start,
+ resource_size_t n,
+ const char *name, int flags)
+{
+ Assert(parent);
+ Assert(parent->flags & IORESOURCE_IO || parent->flags & IORESOURCE_MEM);
+
+ switch (parent->flags)
+ {
+ case IORESOURCE_IO:
+ printk("IO: name: %s, start: %x, len: %d\n",
+ name, start, n);
+ return l4dde26_request_region(start, n, name);
+ case IORESOURCE_MEM:
+ printk("MEM: name: %s, start: %x, len: %d\n",
+ name, start, n);
+ return l4dde26_request_mem_region(start, n, name);
+ }
+
+ return NULL;
+}
+
+
+/** Release IO port region.
+ */
+static void l4dde26_release_region(resource_size_t start, resource_size_t n)
+{
+ /* FIXME: we need a list of "struct resource"s that have been
+ * allocated by request_region() and then need to
+ * free this stuff here! */
+ ddekit_release_io(start, n);
+}
+
+
+/** Release IO memory region.
+ */
+static void l4dde26_release_mem_region(resource_size_t start, resource_size_t n)
+{
+ ddekit_release_mem(start, n);
+ ddekit_pgtab_clear_region((void *)start, PTE_TYPE_OTHER);
+}
+
+
+int __check_region(struct resource *root, resource_size_t s, resource_size_t n)
+{
+ WARN_UNIMPL;
+ return -1;
+}
+
+void __release_region(struct resource *root, resource_size_t start,
+ resource_size_t n)
+{
+ switch (root->flags)
+ {
+ case IORESOURCE_IO:
+ return l4dde26_release_region(start, n);
+ case IORESOURCE_MEM:
+ return l4dde26_release_mem_region(start, n);
+ }
+}
+
+
+/** Map physical I/O region into virtual address space.
+ *
+ * For our sake, this only returns the virtual address belonging to
+ * the physical region, since we don't manage page tables ourselves.
+ */
+void __iomem * ioremap(unsigned long phys_addr, unsigned long size)
+{
+ struct list_head *pos, *head;
+ head = &dde_mem_regions;
+
+ list_for_each(pos, head) {
+ struct dde_mem_region *mreg = list_entry(pos, struct dde_mem_region,
+ list);
+ if (mreg->pa <= phys_addr && mreg->pa + mreg->size >= phys_addr + size)
+ {
+ printk ("ioremap: phys: %x <-> virt: %x\n", phys_addr,
+ (mreg->va + (phys_addr - mreg->pa)));
+ return (void *)(mreg->va + (phys_addr - mreg->pa));
+ }
+ }
+
+ return NULL;
+}
+
+
+void __iomem * ioremap_nocache(unsigned long offset, unsigned long size)
+{
+ return ioremap(offset, size);
+}
+
+
+void iounmap(volatile void __iomem *addr)
+{
+ WARN_UNIMPL;
+}