diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-07-27 22:15:01 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-07-27 22:15:01 +0000 |
commit | 7996a3d79d55b7f879dfd62e202bbfe2963718d3 (patch) | |
tree | 8d9f6759fec4099b9be503c11c7ed174f7204980 /libdde-linux26/lib/src/arch/l4/res.c | |
parent | 4fbe7358c7747a9165f776eb19addbb9baf7def2 (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.c | 188 |
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; +} |