From 45cd9a13de1fdbde70881af313cff50fc6641873 Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Sat, 1 Aug 2020 02:06:45 +0900 Subject: [PATCH] kernel/arch: Add page_attrs_t type for page attributes --- config.h | 1 + kernel/arch/paging.c | 18 +++++----- kernel/include/arch.h | 84 ++++++++++++++++++++++--------------------- 3 files changed, 54 insertions(+), 49 deletions(-) diff --git a/config.h b/config.h index eeef1b2..8657407 100644 --- a/config.h +++ b/config.h @@ -44,6 +44,7 @@ #define CONFIG_POSIX 1 #define CONFIG_PAGING_DIR_MAXREGIONS 16 +#define CONFIG_PAGING_NX 0 #define CONFIG_DEBUG 0 #define CONFIG_DEBUG_SCHED 0 diff --git a/kernel/arch/paging.c b/kernel/arch/paging.c index b0c9fce..7509d27 100644 --- a/kernel/arch/paging.c +++ b/kernel/arch/paging.c @@ -60,7 +60,7 @@ static const char *_str_pg_mode[] = { "Intel64 mode" }; -static int _pg_dir_add_region(pg_dir_t*, void*, u32_t, region_type_t, u32_t, region_opts_t); +static int _pg_dir_add_region(pg_dir_t*, void*, u32_t, region_type_t, page_attrs_t, region_opts_t); int _pg_dir_vpxlate(pg_dir_t*, u32_t, u32_t*); int _pg_dir_pagesize(pg_dir_t*, u32_t, u32_t*); int _pg_dir_xfer(pg_dir_t*, void*, pg_dir_t*, void*, u32_t); @@ -314,7 +314,7 @@ void* pg_init(struct multiboot_info *info) for(mmap = (struct memory_map*)info->mmap_addr; (void*)mmap < (void*)(info->mmap_addr + info->mmap_length); mmap = (struct memory_map*)((void*)mmap + mmap->size + sizeof(mmap->size))) { - u32_t attrs; + page_attrs_t attrs; u64_t addr; #if FEATURE(DEBUG) @@ -831,7 +831,7 @@ int _pg_dir_kstack_map(struct pagedir *pgdir) frame = pg_frame_alloc_end(); if(ret_val) { - u32_t attrs; + page_attrs_t attrs; void* vaddr; vaddr = CONFIG_KERNEL_STACK_BASE; @@ -876,7 +876,7 @@ int _pg_dir_ustack_map(struct pagedir *pgdir) frame = pg_frame_alloc_end(); if(ret_val) { - u32_t attrs; + page_attrs_t attrs; void* vaddr; vaddr = (void*)((u32_t)CONFIG_KERNEL_STACK_BASE - PAGE_SIZE); @@ -1029,7 +1029,7 @@ static int _pg_dir_heap_map(pg_dir_t *pd, u32_t heap_size) /* we found a place to allocate the heap segment */ if(heap_start) { - u32_t attrs; + page_attrs_t attrs; /* the heap shouldn't be executable, right? */ attrs = PAGE_ATTR_PRESENT | PAGE_ATTR_WRITABLE | @@ -1574,7 +1574,7 @@ int pg_dir_foreach_region(pg_dir_t *pd, int (*func)(pg_dir_t*, region_t*, void*) } static int _pg_dir_add_region(pg_dir_t *pd, void *base, u32_t size, - region_type_t type, u32_t attrs, region_opts_t opts) + region_type_t type, page_attrs_t attrs, region_opts_t opts) { struct region *reg; int ret_val; @@ -1692,7 +1692,8 @@ void* pg_dir_sbrk(pg_dir_t *pd, i32_t increment) /* round up to the page size */ nbytes = ALIGN(increment, heap->reg_pgsize); - err = pg_dir_map(pd, 0, heap->reg_base + heap->reg_size, nbytes, heap->reg_attrs); + err = pg_dir_map(pd, 0, heap->reg_base + heap->reg_size, + nbytes, heap->reg_attrs); if(!err) { /* successfully mapped pages - keep track of the increased heap size */ @@ -1705,7 +1706,8 @@ void* pg_dir_sbrk(pg_dir_t *pd, i32_t increment) /* value may be zero, e.g. if the caller wants to free less than a page */ if(nbytes) { /* remove nbytes of space at the end of the region */ - err = pg_dir_unmap(pd, heap->reg_base + heap->reg_size - nbytes, nbytes); + err = pg_dir_unmap(pd, heap->reg_base + heap->reg_size - nbytes, + nbytes); if(!err) { heap->reg_size -= nbytes; diff --git a/kernel/include/arch.h b/kernel/include/arch.h index b0a9716..d1f8a1f 100644 --- a/kernel/include/arch.h +++ b/kernel/include/arch.h @@ -117,6 +117,41 @@ struct task { pid_t t_pid; } __attribute__((packed)); +#define ALIGNED(_v, _a) (!((_v) & (((_a) - 1)))) +#define ALIGN(_v, _a) (ALIGNED((_v), (_a)) ? (_v) : (((_v) & ~((_a) - 1)) + (_a))) + +#if FEATURE(SMP) && FEATURE(APIC) +#define CPU_ID cpu_get_id() +#else /* !(FEATURE(SMP) && FEATURE(APIC)) */ +#define CPU_ID 0 +#endif /* !(FEATURE(SMP) && FEATURE(APIC)) */ + +#define PDPT_ALIGN 32 +#define PAGE_ALIGN 0x1000 +#define ARCH_ALIGN sizeof(void*) + +#define PAGE_SIZE 0x1000 +#define PAGE_SIZE_BIG 0x200000 +#define PAGE_SIZE_LARGE 0x400000 +#define PAGE_SIZE_HUGE 0x40000000 + +typedef enum { + PAGE_ATTR_PRESENT = (1 << 0), + PAGE_ATTR_WRITABLE = (1 << 1), + PAGE_ATTR_USER = (1 << 2), + PAGE_ATTR_WRITE_THRU = (1 << 3), + PAGE_ATTR_CACHE_DISABLE = (1 << 4), + PAGE_ATTR_ACCESSED = (1 << 5), + PAGE_ATTR_DIRTY = (1 << 6), + PAGE_ATTR_SIZE = (1 << 7), + PAGE_ATTR_GLOBAL = (1 << 8), +#if FEATURE(PAGING_NX) + PAGE_ATTR_NO_EXEC = (1 << 63) +#else /* !FEATURE(PAGING_NX) */ + PAGE_ATTR_NO_EXEC = 0 +#endif /* !FEATURE(PAGING_NX) */ +} page_attrs_t; + typedef enum { REGION_TYPE_TEXT = 0, REGION_TYPE_BSS, @@ -137,20 +172,16 @@ typedef enum { typedef struct region region_t; struct region { - void *reg_base; + void *reg_base; region_type_t reg_type; - u32_t reg_size; - u32_t reg_pgsize; - u32_t reg_attrs; /* page attributes */ + u32_t reg_size; + u32_t reg_pgsize; + page_attrs_t reg_attrs; region_opts_t reg_opts; - u32_t reg_refs; + u32_t reg_refs; }; -#if FEATURE(SMP) && FEATURE(APIC) -#define CPU_ID cpu_get_id() -#else /* !(FEATURE(SMP) && FEATURE(APIC)) */ -#define CPU_ID 0 -#endif /* !(FEATURE(SMP) && FEATURE(APIC)) */ +typedef struct pagedir pg_dir_t; int cpu_get_id(void); u64_t cpu_get_capabilities(void); @@ -169,35 +200,6 @@ void task_move_stack(void*, void*, u32_t); void task_lock(task_t*); int task_unlock(task_t*); -/* - * Definitions, types, and prototypes related to paging - */ - -#define ALIGNED(_v, _a) (!((_v) & (((_a) - 1)))) -#define ALIGN(_v, _a) (ALIGNED((_v), (_a)) ? (_v) : (((_v) & ~((_a) - 1)) + (_a))) - -#define PDPT_ALIGN 32 -#define PAGE_ALIGN 0x1000 -#define ARCH_ALIGN sizeof(void*) - -#define PAGE_SIZE 0x1000 -#define PAGE_SIZE_BIG 0x200000 -#define PAGE_SIZE_LARGE 0x400000 -#define PAGE_SIZE_HUGE 0x40000000 - -#define PAGE_ATTR_PRESENT (1 << 0) -#define PAGE_ATTR_WRITABLE (1 << 1) -#define PAGE_ATTR_USER (1 << 2) -#define PAGE_ATTR_WRITE_THRU (1 << 3) -#define PAGE_ATTR_CACHE_DISABLE (1 << 4) -#define PAGE_ATTR_ACCESSED (1 << 5) -#define PAGE_ATTR_DIRTY (1 << 6) -#define PAGE_ATTR_SIZE (1 << 7) -#define PAGE_ATTR_GLOBAL (1 << 8) -#define PAGE_ATTR_NO_EXEC 0 /* (1 << 63) */ - -typedef struct pagedir pg_dir_t; - int pg_dir_create(pg_dir_t**); /* @@ -205,7 +207,7 @@ int pg_dir_create(pg_dir_t**); * * SYNOPSIS * int pg_dir_map(pg_dir_t* pd, const void *paddr, const void *vaddr, - * const u32_t bytes, const u32_t attrs); + * const u32_t bytes, const page_attrs_t); * * DESCRIPTION * The pg_dir_map() function attempts to map page frames (physical pages) into @@ -228,7 +230,7 @@ int pg_dir_create(pg_dir_t**); * -ENOSYS The function is not implemented for this paging mode * -EFAULT Could not determine the paging mode used by the page directory */ -int pg_dir_map(pg_dir_t*, const void*, const void*, const u32_t, const u32_t); +int pg_dir_map(pg_dir_t*, const void*, const void*, const u32_t, const page_attrs_t); int pg_dir_map_region(pg_dir_t*, pg_dir_t*, region_t*); int pg_dir_clone_region(pg_dir_t*, pg_dir_t*, region_t*); int pg_dir_unmap(pg_dir_t*, const void*, const u32_t); -- 2.47.3