00001
00002
00011
00012
00013
00014
00015
00029
00030 #include <l4/sys/types.h>
00031 #include <l4/env/errno.h>
00032 #include <l4/l4rm/l4rm.h>
00033 #include <l4/dm_mem/dm_mem.h>
00034
00035 #include <l4/dde_linux/dde.h>
00036
00037
00038 #include <asm/page.h>
00039 #include <linux/mm.h>
00040
00041
00042 #include "__config.h"
00043 #include "internal.h"
00044
00045 #include "fastcall.h"
00046
00059 unsigned long FASTCALL(__get_free_pages(unsigned int gfp_mask, unsigned int order))
00060 {
00061 int error, pages;
00062 l4_addr_t page;
00063 l4_size_t size;
00064
00065 l4_size_t tmp;
00066 l4dm_mem_addr_t dm_paddr;
00067
00068 if (gfp_mask & GFP_DMA)
00069 LOGd(DEBUG_MSG, "Warning: No ISA DMA memory zone implemented.");
00070
00071 size = L4_PAGESIZE << order;
00072 pages = 1 << order;
00073
00074 LOGd(DEBUG_PALLOC, "requesting %d page(s) (pages)\n", pages);
00075
00076
00077 page = (l4_addr_t) \
00078 l4dm_mem_allocate_named(size,
00079 L4DM_CONTIGUOUS | L4DM_PINNED |\
00080 L4RM_MAP | L4RM_LOG2_ALIGNED,
00081 "dde pages");
00082 if (!page)
00083 {
00084 LOGdL(DEBUG_ERRORS, "Error: allocating pages");
00085 return 0;
00086 }
00087
00088 error = l4dm_mem_phys_addr((void *)page, 1, &dm_paddr, 1, &tmp);
00089 if (error != 1)
00090 {
00091 if (error>1 || !error)
00092 Panic("Ouch, what's that?");
00093 LOGdL(DEBUG_ERRORS, "Error: getting physical address (%d)", error);
00094 return 0;
00095 }
00096
00097
00098 l4dde_add_region(page, dm_paddr.addr, size);
00099
00100 LOGd(DEBUG_PALLOC, "allocated %d pages @ 0x%08lx (phys. 0x%08lx)",
00101 pages, page, dm_paddr.addr);
00102
00103 return (unsigned long) page;
00104 }
00105
00113 unsigned long FASTCALL(get_zeroed_page(unsigned int gfp_mask))
00114 {
00115 unsigned long page = __get_free_pages(gfp_mask, 0);
00116
00117 if (!page)
00118 return 0;
00119
00120 memset((void *) page, 0, L4_PAGESIZE);
00121
00122 return page;
00123 }
00124
00133 void FASTCALL(free_pages(unsigned long addr, unsigned int order))
00134 {
00135 int ret;
00136 l4_addr_t start;
00137 l4_size_t size;
00138 l4dm_dataspace_t ds;
00139 l4_offs_t offset;
00140 l4_threadid_t pager;
00141
00142 ret = l4rm_lookup((void *)addr, &start, &size, &ds, &offset, &pager);
00143
00144 if (ret == L4RM_REGION_DATASPACE)
00145 {
00146 if (size == (L4_PAGESIZE << order))
00147 {
00148 l4dm_mem_release((const void *)addr);
00149
00150 LOGd(DEBUG_PALLOC, "%s 2^%d pages released, addr= 0x%08lx, ",
00151 __FUNCTION__, order, addr);
00152 }
00153 else
00154 LOG_Error("size (%u) != mapped size (%u), skip release of addr=%08lx\n",
00155 L4_PAGESIZE << order, size, addr);
00156 }
00157 else
00158 LOG_Error("Couldn't release memory of addr=%08lx\n", addr);
00159 }
00160
00170 void FASTCALL(__free_pages(struct page *page, unsigned int order))
00171 {
00172
00173 if (page == NULL)
00174 {
00175 LOG_Error("attempt to free NULL page ...\n");
00176 return;
00177 }
00178
00179 if (!put_page_testzero(page))
00180 {
00181 LOGd(DEBUG_PALLOC, "free page=%p denied, page->virtual=%p,"
00182 " because counter (%d) > 0 \n", page, page->virtual, page_count(page));
00183 return;
00184 }
00185 else
00186 {
00187 if (page->virtual != NULL)
00188 {
00189 LOGd(DEBUG_PALLOC, "free_pages: %p count=%d\n",
00190 page->virtual, page_count(page));
00191
00192 free_pages((unsigned long)page->virtual, order);
00193 }
00194 else
00195 LOG_Error("attempt to free page->virtual==NULL, page=%p\n", page);
00196 }
00197
00198 kfree(page);
00199 }