⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intmem.c

📁 linux内核源码
💻 C
字号:
/* * Simple allocator for internal RAM in ETRAX FS * * Copyright (c) 2004 Axis Communications AB. */#include <linux/list.h>#include <linux/slab.h>#include <asm/io.h>#include <asm/arch/memmap.h>#define STATUS_FREE 0#define STATUS_ALLOCATED 1struct intmem_allocation {	struct list_head entry;	unsigned int size;	unsigned offset;	char status;};static struct list_head intmem_allocations;static void* intmem_virtual;static void crisv32_intmem_init(void){	static int initiated = 0;	if (!initiated) {		struct intmem_allocation* alloc =		  (struct intmem_allocation*)kmalloc(sizeof *alloc, GFP_KERNEL);		INIT_LIST_HEAD(&intmem_allocations);		intmem_virtual = ioremap(MEM_INTMEM_START, MEM_INTMEM_SIZE);		initiated = 1;		alloc->size = MEM_INTMEM_SIZE;		alloc->offset = 0;		alloc->status = STATUS_FREE;		list_add_tail(&alloc->entry, &intmem_allocations);	}}void* crisv32_intmem_alloc(unsigned size, unsigned align){	struct intmem_allocation* allocation;	struct intmem_allocation* tmp;	void* ret = NULL;	preempt_disable();	crisv32_intmem_init();	list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) {		int alignment = allocation->offset % align;		alignment = alignment ? align - alignment : alignment;		if (allocation->status == STATUS_FREE &&		    allocation->size >= size + alignment) {			if (allocation->size > size + alignment) {				struct intmem_allocation* alloc =					(struct intmem_allocation*)					kmalloc(sizeof *alloc, GFP_ATOMIC);				alloc->status = STATUS_FREE;				alloc->size = allocation->size - size - alignment;				alloc->offset = allocation->offset + size;				list_add(&alloc->entry, &allocation->entry);				if (alignment) {					struct intmem_allocation* tmp;					tmp = (struct intmem_allocation*)						kmalloc(sizeof *tmp, GFP_ATOMIC);					tmp->offset = allocation->offset;					tmp->size = alignment;					tmp->status = STATUS_FREE;					allocation->offset += alignment;					list_add_tail(&tmp->entry, &allocation->entry);				}			}			allocation->status = STATUS_ALLOCATED;			allocation->size = size;			ret = (void*)((int)intmem_virtual + allocation->offset);		}	}	preempt_enable();	return ret;}void crisv32_intmem_free(void* addr){	struct intmem_allocation* allocation;	struct intmem_allocation* tmp;	if (addr == NULL)		return;	preempt_disable();	crisv32_intmem_init();	list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) {		if (allocation->offset == (int)(addr - intmem_virtual)) {			struct intmem_allocation* prev =			  list_entry(allocation->entry.prev,			             struct intmem_allocation, entry);			struct intmem_allocation* next =			  list_entry(allocation->entry.next,				     struct intmem_allocation, entry);			allocation->status = STATUS_FREE;			/* Join with prev and/or next if also free */			if (prev->status == STATUS_FREE) {				prev->size += allocation->size;				list_del(&allocation->entry);				kfree(allocation);				allocation = prev;			}			if (next->status == STATUS_FREE) {				allocation->size += next->size;				list_del(&next->entry);				kfree(next);			}			preempt_enable();			return;		}	}	preempt_enable();}void* crisv32_intmem_phys_to_virt(unsigned long addr){	return (void*)(addr - MEM_INTMEM_START+	               (unsigned long)intmem_virtual);}unsigned long crisv32_intmem_virt_to_phys(void* addr){	return (unsigned long)((unsigned long )addr -	  (unsigned long)intmem_virtual + MEM_INTMEM_START);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -