예제 #1
0
static char	evaluate_freeable(char *ptr, char *previous, char *mem, char *next)
{
	if (*PAGE_SIZE(mem) == ROUND_PAGE(*DATA_SIZE(ptr, 0) +
		PAGE_META + DATA_META))
		return (unmap_page(previous, mem, next));
	delete_memory(ptr, mem);
	if (!memory_is_set(mem + PAGE_META, *PAGE_SIZE(mem) - PAGE_META))
		return (unmap_page(previous, mem, next));
	return (0);
}
예제 #2
0
static char has_one_page_available()
{
	char 	*mem;
	char	av;

	av = 0;
	mem = get_page_list(0, (void *)-1);
	while (mem && av != 3)
	{
		if (*PAGE_SIZE(mem) == get_alloc_size(TINY))
			av |= 1;
		else if (*PAGE_SIZE(mem) == get_alloc_size(SMALL))
			av |= 2;
		mem = *PAGE_NEXT(mem);
	}
	return (av == 3);
}
예제 #3
0
static int tmpfs_mount(void *dev, void *dir) {
	struct node *dir_node, *dev_node;
	struct nas *dir_nas, *dev_nas;
	struct tmpfs_file_info *fi;
	struct tmpfs_fs_info *fsi;
	struct node_fi *dev_fi;

	dev_node = dev;
	dev_nas = dev_node->nas;
	dir_node = dir;
	dir_nas = dir_node->nas;

	if (NULL == (dev_fi = dev_nas->fi)) {
		return -ENODEV;
	}

	if (NULL == (dir_nas->fs = filesystem_create("tmpfs"))) {
		return -ENOMEM;
	}
	dir_nas->fs->bdev = dev_fi->privdata;

	/* allocate this fs info */
	if(NULL == (fsi = pool_alloc(&tmpfs_fs_pool))) {
		filesystem_free(dir_nas->fs);
		return -ENOMEM;
	}
	memset(fsi, 0, sizeof(struct tmpfs_fs_info));
	dir_nas->fs->fsi = fsi;

	fsi->block_per_file = MAX_FILE_SIZE;
	fsi->block_size = PAGE_SIZE();
	fsi->numblocks = block_dev(dev_fi->privdata)->size / PAGE_SIZE();

	/* allocate this directory info */
	if(NULL == (fi = pool_alloc(&tmpfs_file_pool))) {
		return -ENOMEM;
	}
	memset(fi, 0, sizeof(struct tmpfs_file_info));
	fi->index = fi->mode = 0;
	dir_nas->fi->privdata = (void *) fi;

	return 0;
}
예제 #4
0
static int heap_init(void) {
	size_t heap_size = (size_t)&_heap_end - (size_t)&_heap_start;

	__heap_pgallocator = page_allocator_init((char *)&_heap_start, heap_size, PAGE_SIZE());
	if (NULL == __heap_pgallocator) {
		return -ENOSUPP;
	}

	return 0;
}
예제 #5
0
static int tmpfs_truncate(struct node *node, off_t length) {
	struct nas *nas = node->nas;

	if (length > MAX_FILE_SIZE * PAGE_SIZE()) {
		return -EFBIG;
	}

	nas->fi->ni.size = length;

	return 0;
}
예제 #6
0
static char	unmap_page(char *previous, char *mem, char *next)
{
	if (!has_one_page_available())
		return (0);
	if (previous)
		*PAGE_NEXT(previous) = next;
	else
		get_page_list(0, next);
	munmap((void *)mem, *PAGE_SIZE(mem));
	return (0);
}
예제 #7
0
static char	delete_ptrs_page(char *ptr)
{
	char	*mem;
	char	*previous;
	char	*next;

	previous = NULL;
	mem = get_page_list(0, (void *)-1);
	while (mem)
	{
		next = *PAGE_NEXT(mem);
		if (ptr >= mem + PAGE_META && ptr < mem + *PAGE_SIZE(mem))
			return (evaluate_freeable(ptr, previous, mem, next));
		previous = mem;
		mem = next;
	}
	return (0);
}
예제 #8
0
static int tmpfs_format(void *dev) {
	node_t *dev_node;
	struct nas *dev_nas;
	struct node_fi *dev_fi;

	if (NULL == (dev_node = dev)) {
		return -ENODEV;/*device not found*/
	}

	if(!node_is_block_dev(dev_node)) {
		return -ENODEV;
	}
	dev_nas = dev_node->nas;
	dev_fi = dev_nas->fi;

	if(MAX_FILE_SIZE > block_dev(dev_fi->privdata)->size / PAGE_SIZE()) {
		return -ENOSPC;
	}
	return 0;
}
예제 #9
0
static int bochs_init(struct pci_slot_dev *pci_dev) {
	char *mmap_base = (char *)(pci_dev->bar[0] & ~0xf); /* FIXME */
	size_t mmap_len = binalign_bound(VBE_DISPI_MAX_XRES 
			* VBE_DISPI_MAX_YRES 
			* VBE_DISPI_MAX_BPP / 8, PAGE_SIZE());
	struct fb_info *info;

	if (MAP_FAILED == mmap_device_memory(mmap_base,
				mmap_len,
			       	PROT_READ|PROT_WRITE|PROT_NOCACHE,
				MAP_FIXED,
				(unsigned long) mmap_base)) {
		return -EIO;
	}

	info = fb_create(&bochs_ops, mmap_base, mmap_len);
	if (info == NULL) {
		munmap(mmap_base, mmap_len);
		return -ENOMEM;
	}

	return 0;
}
예제 #10
0
static int tmpfs_init(void * par) {
	struct path dir_path, dev_path, root;
	struct node *dev_node;
	int res;
	struct ramdisk *ramdisk;

	if (!par) {
		return 0;
	}

	/*TODO */

	if (0 != vfs_lookup(TMPFS_DIR, &dir_path)) {
		return -ENOENT;
	}

	ramdisk = ramdisk_create(tmpfs_dev, FILESYSTEM_SIZE * PAGE_SIZE());
	if (0 != (res = err(ramdisk))) {
		return res;
	}

	dev_node = ramdisk->bdev->dev_vfs_info;
	if (!dev_node) {
		return -1;
	}

	/* format filesystem */
	if (0 != (res = tmpfs_format((void *) dev_node))) {
		return res;
	}

	/* mount filesystem */
	dev_path.node = dev_node;
	dev_path.mnt_desc = root.mnt_desc;
	return tmpfs_mount(dev_path.node, dir_path.node);
}
예제 #11
0
파일: bochs.c 프로젝트: Julia117/embox
static int bochs_init(struct pci_slot_dev *pci_dev) {
	int ret;
	struct fb_info *info;
	size_t mmap_len;

	assert(pci_dev != NULL);

	info = fb_alloc();
	if (info == NULL) {
		return -ENOMEM;
	}

	memcpy(&info->fix, &bochs_fix_screeninfo, sizeof info->fix);
	fill_var(&info->var);

	info->ops = &bochs_ops;
	info->screen_base = (void *)(pci_dev->bar[0] & ~0xf); /* FIXME */
	mmap_len = binalign_bound(VBE_DISPI_MAX_XRES * VBE_DISPI_MAX_YRES * VBE_DISPI_MAX_BPP / 8, PAGE_SIZE());

	if (MAP_FAILED == mmap_device_memory(info->screen_base,
				mmap_len,
			       	PROT_READ|PROT_WRITE|PROT_NOCACHE,
				MAP_FIXED,
				(unsigned long) info->screen_base)) {
		return -EIO;
	}

	ret = fb_register(info);
	if (ret != 0) {
		fb_release(info);
		return ret;
	}

	return 0;
}
예제 #12
0
POOL_DEF(tmpfs_fs_pool, struct tmpfs_fs_info, OPTION_GET(NUMBER,tmpfs_descriptor_quantity));

/* tmpfs file description pool */
POOL_DEF(tmpfs_file_pool, struct tmpfs_file_info, OPTION_GET(NUMBER,inode_quantity));

INDEX_DEF(tmpfs_file_idx,0,OPTION_GET(NUMBER,inode_quantity));

/* define sizes in 4096 blocks */
#define MAX_FILE_SIZE OPTION_GET(NUMBER,tmpfs_file_size)
#define FILESYSTEM_SIZE OPTION_GET(NUMBER,tmpfs_filesystem_size)

#define TMPFS_NAME "tmpfs"
#define TMPFS_DEV  "/dev/ram#"
#define TMPFS_DIR  "/tmp"

static char sector_buff[PAGE_SIZE()];/* TODO */
static char tmpfs_dev[] = TMPFS_DEV;

static int tmpfs_format(void *path);
static int tmpfs_mount(void *dev, void *dir);

static int tmpfs_init(void * par) {
	struct path dir_path, dev_path, root;
	struct node *dev_node;
	int res;
	struct ramdisk *ramdisk;

	if (!par) {
		return 0;
	}
예제 #13
0
파일: amd64.c 프로젝트: chen0031/libvmi
GSList* get_va_pages_ia32e(vmi_instance_t vmi, addr_t dtb) {

    GSList *ret = NULL;
    uint8_t entry_size = 0x8;

    #define IA32E_ENTRIES_PER_PAGE 0x200 // 0x1000/0x8

    uint64_t *pml4_page = malloc(VMI_PS_4KB);

    addr_t pml4e_location = dtb & VMI_BIT_MASK(12,51);
    if (VMI_PS_4KB != vmi_read_pa(vmi, pml4e_location, pml4_page, VMI_PS_4KB)) {
        free(pml4_page);
        return ret;
    }

    uint64_t *pdpt_page = malloc(VMI_PS_4KB);
    uint64_t *pgd_page = malloc(VMI_PS_4KB);
    uint64_t *pt_page = malloc(VMI_PS_4KB);

    uint64_t pml4e_index;
    for(pml4e_index = 0; pml4e_index < IA32E_ENTRIES_PER_PAGE; pml4e_index++, pml4e_location += entry_size) {

        uint64_t pml4e_value = pml4_page[pml4e_index];

        if(!ENTRY_PRESENT(vmi->os_type, pml4e_value)) {
            continue;
        }

        uint64_t pdpte_location = pml4e_value & VMI_BIT_MASK(12,51);

        if (VMI_PS_4KB != vmi_read_pa(vmi, pdpte_location, pdpt_page, VMI_PS_4KB)) {
            continue;
        }

        uint64_t pdpte_index;
        for(pdpte_index = 0; pdpte_index < IA32E_ENTRIES_PER_PAGE; pdpte_index++, pdpte_location++) {

            uint64_t pdpte_value = pdpt_page[pdpte_index];

            if(!ENTRY_PRESENT(vmi->os_type, pdpte_value)) {
                continue;
            }

            if(PAGE_SIZE(pdpte_value)) {
                page_info_t *info = g_malloc0(sizeof(page_info_t));
                info->vaddr = (pml4e_index << 39) | (pdpte_index << 30);
                info->paddr = get_gigpage_ia32e(info->vaddr, pdpte_value);
                info->size = VMI_PS_1GB;
                info->x86_ia32e.pml4e_location = pml4e_location;
                info->x86_ia32e.pml4e_value = pml4e_value;
                info->x86_ia32e.pdpte_location = pdpte_location;
                info->x86_ia32e.pdpte_value = pdpte_value;
                ret = g_slist_prepend(ret, info);
                continue;
            }

            uint64_t pgd_location = pdpte_value & VMI_BIT_MASK(12,51);

            if (VMI_PS_4KB != vmi_read_pa(vmi, pgd_location, pgd_page, VMI_PS_4KB)) {
                continue;
            }

            uint64_t pgde_index;
            for(pgde_index = 0; pgde_index < IA32E_ENTRIES_PER_PAGE; pgde_index++, pgd_location += entry_size) {

                uint64_t pgd_value = pgd_page[pgde_index];

                if(ENTRY_PRESENT(vmi->os_type, pgd_value)) {

                    if(PAGE_SIZE(pgd_value)) {
                        page_info_t *info = g_malloc0(sizeof(page_info_t));
                        info->vaddr = (pml4e_index << 39) | (pdpte_index << 30) |
                                        (pgde_index << 21);
                        info->paddr = get_2megpage_ia32e(info->vaddr, pgd_value);
                        info->size = VMI_PS_2MB;
                        info->x86_ia32e.pml4e_location = pml4e_location;
                        info->x86_ia32e.pml4e_value = pml4e_value;
                        info->x86_ia32e.pdpte_location = pdpte_location;
                        info->x86_ia32e.pdpte_value = pdpte_value;
                        info->x86_ia32e.pgd_location = pgd_location;
                        info->x86_ia32e.pgd_value = pgd_value;
                        ret = g_slist_prepend(ret, info);
                        continue;
                    }

                    uint64_t pte_location = (pgd_value & VMI_BIT_MASK(12,51));
                    if (VMI_PS_4KB != vmi_read_pa(vmi, pte_location, pt_page, VMI_PS_4KB)) {
                        continue;
                    }

                    uint64_t pte_index;
                    for(pte_index = 0; pte_index < IA32E_ENTRIES_PER_PAGE; pte_index++, pte_location += entry_size) {
                        uint64_t pte_value = pt_page[pte_index];

                        if(ENTRY_PRESENT(vmi->os_type, pte_value)) {
                            page_info_t *info = g_malloc0(sizeof(page_info_t));
                            info->vaddr = (pml4e_index << 39) | (pdpte_index << 30) |
                                            (pgde_index << 21) | (pte_index << 12);
                            info->paddr = get_paddr_ia32e(info->vaddr, pte_value);
                            info->size = VMI_PS_4KB;
                            info->x86_ia32e.pml4e_location = pml4e_location;
                            info->x86_ia32e.pml4e_value = pml4e_value;
                            info->x86_ia32e.pdpte_location = pdpte_location;
                            info->x86_ia32e.pdpte_value = pdpte_value;
                            info->x86_ia32e.pgd_location = pgd_location;
                            info->x86_ia32e.pgd_value = pgd_value;
                            info->x86_ia32e.pte_location = pte_location;
                            info->x86_ia32e.pte_value = pte_value;
                            ret = g_slist_prepend(ret, info);
                            continue;
                        }
                    }
                }
            }
        }
    }

    free(pt_page);
    free(pgd_page);
    free(pdpt_page);
    free(pml4_page);

    return ret;
}
예제 #14
0
파일: amd64.c 프로젝트: chen0031/libvmi
status_t v2p_ia32e (vmi_instance_t vmi,
    addr_t dtb,
    addr_t vaddr,
    page_info_t *info)
{
    status_t status = VMI_FAILURE;

    // are we in compatibility mode OR 64-bit mode ???

    // validate address based on above (e.g., is it canonical?)

    // determine what MAXPHYADDR is

    dbprint(VMI_DEBUG_PTLOOKUP, "--PTLookup: lookup vaddr = 0x%.16"PRIx64"\n", vaddr);
    dbprint(VMI_DEBUG_PTLOOKUP, "--PTLookup: dtb = 0x%.16"PRIx64"\n", dtb);

    status = get_pml4e(vmi, vaddr, dtb, &info->x86_ia32e.pml4e_location, &info->x86_ia32e.pml4e_value);
    if (status != VMI_SUCCESS) {
        goto done;
    }

    if (!ENTRY_PRESENT(vmi->os_type, info->x86_ia32e.pml4e_value)) {
        status = VMI_FAILURE;
        goto done;
    }

    status = get_pdpte_ia32e(vmi, vaddr, info->x86_ia32e.pml4e_value, &info->x86_ia32e.pdpte_location,
                             &info->x86_ia32e.pdpte_value);
    if (status != VMI_SUCCESS) {
        goto done;
    }

    if (!ENTRY_PRESENT(vmi->os_type, info->x86_ia32e.pdpte_value)) {
        status = VMI_FAILURE;
        goto done;
    }

    if (PAGE_SIZE(info->x86_ia32e.pdpte_value)) { // pdpte maps a 1GB page
        info->size = VMI_PS_1GB;
        info->paddr = get_gigpage_ia32e(vaddr, info->x86_ia32e.pdpte_value);
        status = VMI_SUCCESS;
        dbprint(VMI_DEBUG_PTLOOKUP, "--PTLookup: 1GB page\n");
        goto done;
    }

    status = get_pde_ia32e(vmi, vaddr, info->x86_ia32e.pdpte_value, &info->x86_ia32e.pgd_location,
                           &info->x86_ia32e.pgd_value);
    if (status != VMI_SUCCESS) {
        goto done;
    }

    if (!ENTRY_PRESENT(vmi->os_type, info->x86_ia32e.pgd_value)) {
        status = VMI_FAILURE;
        goto done;
    }

    if (PAGE_SIZE(info->x86_ia32e.pgd_value)) { // pde maps a 2MB page
        info->size = VMI_PS_2MB;
        info->paddr = get_2megpage_ia32e(vaddr, info->x86_ia32e.pgd_value);
        status = VMI_SUCCESS;
        dbprint(VMI_DEBUG_PTLOOKUP, "--PTLookup: 2MB page\n");
        goto done;
    }

    status = get_pte_ia32e(vmi, vaddr, info->x86_ia32e.pgd_value, &info->x86_ia32e.pte_location,
                           &info->x86_ia32e.pte_value);
    if (status != VMI_SUCCESS) {
        goto done;
    }

    if (!ENTRY_PRESENT(vmi->os_type, info->x86_ia32e.pte_value)) {
        status = VMI_FAILURE;
        goto done;
    }

    info->size = VMI_PS_4KB;
    info->paddr = get_paddr_ia32e(vaddr, info->x86_ia32e.pte_value);
    status = VMI_SUCCESS;

done:
    dbprint(VMI_DEBUG_PTLOOKUP, "--PTLookup: paddr = 0x%.16"PRIx64"\n", info->paddr);
    return status;
}
예제 #15
0
#include <mem/page.h>

#include <kernel/thread.h>
#include <mem/misc/pool.h>
#include <assert.h>


#define STACK_SZ      OPTION_GET(NUMBER, thread_stack_size)
static_assert(STACK_SZ > sizeof(struct thread));

#define POOL_SZ       OPTION_GET(NUMBER, thread_pool_size)

typedef union thread_pool_entry {
	struct thread thread;
	char stack[STACK_SZ];
} thread_pool_entry_t __attribute__((aligned(PAGE_SIZE())));

POOL_DEF(thread_pool, thread_pool_entry_t, POOL_SZ);

struct thread *thread_alloc(void) {
	thread_pool_entry_t *block;
	struct thread *t;

	if (!(block = (thread_pool_entry_t *) pool_alloc(&thread_pool))) {
		return NULL;
	}
	memset(block, 0x53, sizeof(*block));

	t = &block->thread;

	thread_stack_init(t, STACK_SZ);