Changeset e49e234 in mainline
- Timestamp:
- 2009-02-27T11:32:31Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c1f7f6ea
- Parents:
- 5f0f29ce
- Location:
- kernel
- Files:
-
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/include/mm/frame.h
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup amd64mm 29 /** @addtogroup amd64mm 30 30 * @{ 31 31 */ … … 40 40 #endif /* __ASM__ */ 41 41 42 #define FRAME_WIDTH 12/* 4K */43 #define FRAME_SIZE 42 #define FRAME_WIDTH 12 /* 4K */ 43 #define FRAME_SIZE (1 << FRAME_WIDTH) 44 44 45 45 #ifndef __ASM__ 46 46 extern uintptr_t last_frame; 47 extern uintptr_t end_frame;48 47 extern void frame_arch_init(void); 49 48 extern void physmem_print(void); -
kernel/arch/amd64/src/mm/page.c
r5f0f29ce re49e234 35 35 #include <arch/mm/page.h> 36 36 #include <genarch/mm/page_pt.h> 37 #include <genarch/drivers/ega/ega.h>38 #include <genarch/drivers/legacy/ia32/io.h>39 37 #include <arch/mm/frame.h> 40 38 #include <mm/page.h> … … 49 47 #include <panic.h> 50 48 #include <align.h> 51 #include <ddi/ddi.h>52 53 /** Physical memory area for devices. */54 static parea_t dev_area;55 static parea_t ega_area;56 49 57 50 /* Definitions for identity page mapper */ … … 222 215 } 223 216 224 void hw_area(void)225 {226 dev_area.pbase = end_frame;227 dev_area.frames = SIZE2FRAMES(0xfffffffffffff - end_frame);228 ddi_parea_register(&dev_area);229 230 ega_area.pbase = EGA_VIDEORAM;231 ega_area.frames = SIZE2FRAMES(EGA_VRAM_SIZE);232 ddi_parea_register(&ega_area);233 }234 235 217 /** @} 236 218 */ -
kernel/arch/arm32/include/mm/frame.h
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup arm32mm 29 /** @addtogroup arm32mm 30 30 * @{ 31 31 */ … … 37 37 #define KERN_arm32_FRAME_H_ 38 38 39 #define FRAME_WIDTH 12/* 4KB frames */40 #define FRAME_SIZE 39 #define FRAME_WIDTH 12 /* 4KB frames */ 40 #define FRAME_SIZE (1 << FRAME_WIDTH) 41 41 42 42 #ifdef KERNEL … … 45 45 #include <arch/types.h> 46 46 47 #define BOOT_PAGE_TABLE_SIZE 0x400048 #define BOOT_PAGE_TABLE_ADDRESS 0x400047 #define BOOT_PAGE_TABLE_SIZE 0x4000 48 #define BOOT_PAGE_TABLE_ADDRESS 0x4000 49 49 50 50 #define BOOT_PAGE_TABLE_START_FRAME (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH) … … 52 52 53 53 extern uintptr_t last_frame; 54 extern uintptr_t end_frame;55 54 56 55 extern void frame_arch_init(void); -
kernel/arch/arm32/src/mm/frame.c
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup arm32mm 29 /** @addtogroup arm32mm 30 30 * @{ 31 31 */ … … 42 42 /** Address of the last frame in the memory. */ 43 43 uintptr_t last_frame = 0; 44 uintptr_t end_frame = 0;45 44 46 45 /** Creates memory zones. */ … … 51 50 BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0); 52 51 last_frame = machine_get_memory_size(); 53 end_frame = last_frame;54 52 55 53 /* blacklist boot page table */ -
kernel/arch/arm32/src/mm/page.c
r5f0f29ce re49e234 44 44 #include <interrupt.h> 45 45 #include <arch/mm/frame.h> 46 #include <ddi/ddi.h>47 48 /** Physical memory area for devices. */49 static parea_t dev_area;50 46 51 47 /** Initializes page tables. … … 111 107 } 112 108 113 void hw_area(void)114 {115 dev_area.pbase = end_frame;116 dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame);117 ddi_parea_register(&dev_area);118 }119 120 109 /** @} 121 110 */ -
kernel/arch/ia32/include/boot/memmap.h
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_MEMMAP_H_ 37 37 38 /* E820h memory range types - other values*/ 39 /* Free memory */ 40 #define MEMMAP_MEMORY_AVAILABLE 1 41 /* Not available for OS */ 42 #define MEMMAP_MEMORY_RESERVED 2 43 /* OS may use it after reading ACPI table */ 44 #define MEMMAP_MEMORY_ACPI 3 45 /* Unusable, required to be saved and restored across an NVS sleep */ 46 #define MEMMAP_MEMORY_NVS 4 47 /* Corrupted memory */ 48 #define MEMMAP_MEMORY_UNUSABLE 5 38 /* E820h memory range types */ 49 39 50 /* size of one entry */ 51 #define MEMMAP_E820_RECORD_SIZE 20 52 /* maximum entries */ 53 #define MEMMAP_E820_MAX_RECORDS 32 40 /* Free memory */ 41 #define MEMMAP_MEMORY_AVAILABLE 1 54 42 43 /* Not available for OS */ 44 #define MEMMAP_MEMORY_RESERVED 2 45 46 /* OS may use it after reading ACPI table */ 47 #define MEMMAP_MEMORY_ACPI 3 48 49 /* Unusable, required to be saved and restored across an NVS sleep */ 50 #define MEMMAP_MEMORY_NVS 4 51 52 /* Corrupted memory */ 53 #define MEMMAP_MEMORY_UNUSABLE 5 54 55 /* Size of one entry */ 56 #define MEMMAP_E820_RECORD_SIZE 20 57 58 /* Maximum entries */ 59 #define MEMMAP_E820_MAX_RECORDS 32 55 60 56 61 #ifndef __ASM__ -
kernel/arch/ia32/include/mm/frame.h
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup ia32mm 29 /** @addtogroup ia32mm 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia32_FRAME_H_ 37 37 38 #define FRAME_WIDTH 12/* 4K */39 #define FRAME_SIZE 38 #define FRAME_WIDTH 12 /* 4K */ 39 #define FRAME_SIZE (1 << FRAME_WIDTH) 40 40 41 41 #ifdef KERNEL … … 45 45 46 46 extern uintptr_t last_frame; 47 extern uintptr_t end_frame;48 47 49 48 extern void frame_arch_init(void); -
kernel/arch/ia32/src/mm/frame.c
r5f0f29ce re49e234 51 51 52 52 uintptr_t last_frame = 0; 53 uintptr_t end_frame = 0;54 53 55 54 static void init_e820_memory(pfn_t minconf) 56 55 { 57 56 unsigned int i; 58 pfn_t start, conf;59 size_t size;60 61 57 for (i = 0; i < e820counter; i++) { 58 uint64_t base = e820table[i].base_address; 59 uint64_t size = e820table[i].size; 60 61 #ifdef __32_BITS__ 62 63 /* Ignore physical memory above 4 GB */ 64 if ((base >> 32) != 0) 65 continue; 66 67 /* Clip regions above 4 GB */ 68 if (((base + size) >> 32) != 0) 69 size = 0xffffffff - base; 70 71 #endif 72 pfn_t pfn; 73 count_t count; 74 62 75 if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { 63 start = ADDR2PFN(ALIGN_UP(e820table[i].base_address, FRAME_SIZE)); 64 size = SIZE2FRAMES(ALIGN_DOWN(e820table[i].size, FRAME_SIZE)); 76 /* To be safe, make available zone possibly smaller */ 77 pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE)); 78 count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)); 65 79 66 if ((minconf < start) || (minconf >= start + size)) 67 conf = start; 80 pfn_t conf; 81 if ((minconf < pfn) || (minconf >= pfn + count)) 82 conf = pfn; 68 83 else 69 84 conf = minconf; 70 85 71 zone_create( start, size, conf, 0);86 zone_create(pfn, count, conf, ZONE_AVAILABLE); 72 87 73 if (last_frame < ALIGN_UP(e820table[i].base_address + 74 e820table[i].size, FRAME_SIZE)) 75 last_frame = 76 ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE); 88 // XXX this has to be removed 89 if (last_frame < ALIGN_UP(base + size, FRAME_SIZE)) 90 last_frame = ALIGN_UP(base + size, FRAME_SIZE); 91 } 92 93 if (e820table[i].type == MEMMAP_MEMORY_RESERVED) { 94 /* To be safe, make reserved zone possibly larger */ 95 pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE)); 96 count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE)); 97 98 zone_create(pfn, count, 0, ZONE_RESERVED); 99 } 100 101 if (e820table[i].type == MEMMAP_MEMORY_ACPI) { 102 /* To be safe, make firmware zone possibly larger */ 103 pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE)); 104 count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE)); 105 106 zone_create(pfn, count, 0, ZONE_FIRMWARE); 77 107 } 78 108 } 79 80 end_frame = last_frame;81 109 } 82 110 -
kernel/arch/ia32/src/mm/page.c
r5f0f29ce re49e234 35 35 #include <arch/mm/page.h> 36 36 #include <genarch/mm/page_pt.h> 37 #include <genarch/drivers/ega/ega.h>38 #include <genarch/drivers/legacy/ia32/io.h>39 37 #include <arch/mm/frame.h> 40 38 #include <mm/frame.h> … … 51 49 #include <print.h> 52 50 #include <interrupt.h> 53 #include <ddi/ddi.h>54 55 /** Physical memory area for devices. */56 static parea_t dev_area;57 static parea_t ega_area;58 51 59 52 void page_arch_init(void) … … 61 54 uintptr_t cur; 62 55 int flags; 63 56 64 57 if (config.cpu_active == 1) { 65 58 page_mapping_operations = &pt_mapping_operations; … … 74 67 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); 75 68 } 76 69 77 70 exc_register(14, "page_fault", (iroutine) page_fault); 78 71 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); 79 72 } else 80 73 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); 81 74 82 75 paging_on(); 83 76 } … … 99 92 100 93 return virtaddr; 101 }102 103 void hw_area(void)104 {105 dev_area.pbase = end_frame;106 dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame);107 ddi_parea_register(&dev_area);108 109 ega_area.pbase = EGA_VIDEORAM;110 ega_area.frames = SIZE2FRAMES(EGA_VRAM_SIZE);111 ddi_parea_register(&ega_area);112 94 } 113 95 -
kernel/arch/ia64/include/mm/frame.h
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup ia64mm 29 /** @addtogroup ia64mm 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia64_FRAME_H_ 37 37 38 #define FRAME_WIDTH 14/* 16K */39 #define FRAME_SIZE 38 #define FRAME_WIDTH 14 /* 16K */ 39 #define FRAME_SIZE (1 << FRAME_WIDTH) 40 40 41 41 #ifdef KERNEL … … 45 45 46 46 extern uintptr_t last_frame; 47 extern uintptr_t end_frame;48 47 49 48 extern void frame_arch_init(void); -
kernel/arch/ia64/src/mm/frame.c
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup ia64mm 29 /** @addtogroup ia64mm 30 30 * @{ 31 31 */ … … 52 52 53 53 uintptr_t last_frame = 0; 54 uintptr_t end_frame = 0;55 54 56 55 void frame_arch_init(void) -
kernel/arch/ia64/src/mm/page.c
r5f0f29ce re49e234 49 49 #include <memstr.h> 50 50 #include <align.h> 51 #include <ddi/ddi.h>52 53 /** Physical memory area for devices. */54 static parea_t dev_area;55 51 56 52 static void set_environment(void); … … 68 64 { 69 65 region_register rr; 70 pta_register pta; 66 pta_register pta; 71 67 int i; 72 #ifdef CONFIG_VHPT 68 #ifdef CONFIG_VHPT 73 69 uintptr_t vhpt_base; 74 70 #endif … … 279 275 } 280 276 281 void hw_area(void)282 {283 dev_area.pbase = end_frame;284 dev_area.frames = SIZE2FRAMES(0x7fffffffffffffffUL - end_frame);285 ddi_parea_register(&dev_area);286 }287 288 277 /** @} 289 278 */ -
kernel/arch/mips32/include/mm/frame.h
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup mips32mm 29 /** @addtogroup mips32mm 30 30 * @{ 31 31 */ … … 47 47 extern void physmem_print(void); 48 48 49 extern uintptr_t end_frame;50 51 49 #endif /* __ASM__ */ 52 50 #endif /* KERNEL */ -
kernel/arch/mips32/src/mm/frame.c
r5f0f29ce re49e234 65 65 static count_t phys_regions_count = 0; 66 66 static phys_region_t phys_regions[MAX_REGIONS]; 67 68 uintptr_t end_frame = 0;69 67 70 68 … … 239 237 } 240 238 241 end_frame = frame; 242 243 frame_add_region(start_frame, end_frame); 239 frame_add_region(start_frame, frame); 244 240 245 241 /* Blacklist interrupt vector frame */ -
kernel/arch/mips32/src/mm/page.c
r5f0f29ce re49e234 37 37 #include <mm/page.h> 38 38 #include <mm/frame.h> 39 #include <ddi/ddi.h>40 41 /** Physical memory area for devices. */42 static parea_t dev_area;43 39 44 40 void page_arch_init(void) … … 56 52 } 57 53 58 void hw_area(void)59 {60 dev_area.pbase = end_frame;61 dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame);62 ddi_parea_register(&dev_area);63 }64 65 54 /** @} 66 55 */ -
kernel/arch/ppc32/include/mm/frame.h
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup ppc32mm 29 /** @addtogroup ppc32mm 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ppc32_FRAME_H_ 37 37 38 #define FRAME_WIDTH 12/* 4K */39 #define FRAME_SIZE 38 #define FRAME_WIDTH 12 /* 4K */ 39 #define FRAME_SIZE (1 << FRAME_WIDTH) 40 40 41 41 #ifdef KERNEL … … 45 45 46 46 extern uintptr_t last_frame; 47 extern uintptr_t end_frame;48 47 49 48 extern void frame_arch_init(void); -
kernel/arch/ppc32/src/mm/frame.c
r5f0f29ce re49e234 41 41 42 42 uintptr_t last_frame = 0; 43 uintptr_t end_frame = 0;44 43 45 44 void physmem_print(void) … … 77 76 } 78 77 79 end_frame = last_frame;80 81 78 /* First is exception vector, second is 'implementation specific', 82 79 third and fourth is reserved, other contain real mode code */ -
kernel/arch/ppc32/src/mm/page.c
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup ppc32mm 29 /** @addtogroup ppc32mm 30 30 * @{ 31 31 */ … … 38 38 #include <align.h> 39 39 #include <config.h> 40 #include <ddi/ddi.h>41 42 /** Physical memory area for devices. */43 static parea_t dev_area;44 40 45 41 void page_arch_init(void) … … 68 64 } 69 65 70 void hw_area(void)71 {72 dev_area.pbase = end_frame;73 dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame);74 ddi_parea_register(&dev_area);75 }76 77 66 /** @} 78 67 */ -
kernel/arch/sparc64/include/mm/frame.h
r5f0f29ce re49e234 74 74 75 75 extern uintptr_t last_frame; 76 extern uintptr_t end_frame;77 76 extern void frame_arch_init(void); 78 77 #define physmem_print() -
kernel/arch/sparc64/src/mm/frame.c
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup sparc64mm 29 /** @addtogroup sparc64mm 30 30 * @{ 31 31 */ … … 42 42 43 43 uintptr_t last_frame = NULL; 44 uintptr_t end_frame = NULL;45 44 46 45 /** Create memory zones according to information stored in bootinfo. … … 81 80 frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1); 82 81 } 83 84 end_frame = last_frame;85 82 } 86 83 -
kernel/arch/sparc64/src/mm/page.c
r5f0f29ce re49e234 42 42 #include <align.h> 43 43 #include <config.h> 44 #include <ddi/ddi.h>45 46 /** Physical memory area for devices. */47 static parea_t dev_area;48 44 49 45 #ifdef CONFIG_SMP … … 169 165 } 170 166 171 void hw_area(void)172 {173 dev_area.pbase = end_frame;174 dev_area.frames = SIZE2FRAMES(0x7ffffffffff - end_frame);175 ddi_parea_register(&dev_area);176 }177 178 167 /** @} 179 168 */ -
kernel/generic/include/align.h
r5f0f29ce re49e234 27 27 */ 28 28 29 /** @addtogroup generic 29 /** @addtogroup generic 30 30 * @ingroup others 31 31 * @{ … … 33 33 /** 34 34 * @file 35 * @brief 35 * @brief Macros for making values and addresses aligned. 36 36 */ 37 37 … … 44 44 * @param a Size of alignment, must be power of 2. 45 45 */ 46 #define ALIGN_DOWN(s, a) 46 #define ALIGN_DOWN(s, a) ((s) & ~((a) - 1)) 47 47 48 48 … … 52 52 * @param a Size of alignment, must be power of 2. 53 53 */ 54 #define ALIGN_UP(s, a) 54 #define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1)) 55 55 56 56 #endif -
kernel/generic/include/mm/frame.h
r5f0f29ce re49e234 40 40 #include <adt/list.h> 41 41 #include <mm/buddy.h> 42 #include <synch/spinlock.h> 42 43 #include <arch/mm/page.h> 43 44 #include <arch/mm/frame.h> … … 68 69 typedef uint8_t zone_flags_t; 69 70 71 /** Available zone (free for allocation) */ 72 #define ZONE_AVAILABLE 0x00 70 73 /** Zone is reserved (not available for allocation) */ 71 #define ZONE_RESERVED 0x0874 #define ZONE_RESERVED 0x08 72 75 /** Zone is used by firmware (not available for allocation) */ 73 #define ZONE_FIRMWARE 0x1076 #define ZONE_FIRMWARE 0x10 74 77 75 78 /** Currently there is no equivalent zone flags 76 79 for frame flags */ 77 80 #define FRAME_TO_ZONE_FLAGS(frame_flags) 0 81 82 typedef struct { 83 count_t refcount; /**< Tracking of shared frames */ 84 uint8_t buddy_order; /**< Buddy system block order */ 85 link_t buddy_link; /**< Link to the next free block inside 86 one order */ 87 void *parent; /**< If allocated by slab, this points there */ 88 } frame_t; 89 90 typedef struct { 91 pfn_t base; /**< Frame_no of the first frame 92 in the frames array */ 93 count_t count; /**< Size of zone */ 94 count_t free_count; /**< Number of free frame_t 95 structures */ 96 count_t busy_count; /**< Number of busy frame_t 97 structures */ 98 zone_flags_t flags; /**< Type of the zone */ 99 100 frame_t *frames; /**< Array of frame_t structures 101 in this zone */ 102 buddy_system_t *buddy_system; /**< Buddy system for the zone */ 103 } zone_t; 104 105 /* 106 * The zoneinfo.lock must be locked when accessing zoneinfo structure. 107 * Some of the attributes in zone_t structures are 'read-only' 108 */ 109 typedef struct { 110 SPINLOCK_DECLARE(lock); 111 count_t count; 112 zone_t info[ZONES_MAX]; 113 } zones_t; 114 115 extern zones_t zones; 78 116 79 117 static inline uintptr_t PFN2ADDR(pfn_t frame) … … 99 137 } 100 138 139 static inline bool zone_flags_available(zone_flags_t flags) 140 { 141 return ((flags & (ZONE_RESERVED | ZONE_FIRMWARE)) == 0); 142 } 143 101 144 #define IS_BUDDY_ORDER_OK(index, order) \ 102 145 ((~(((unative_t) -1) << (order)) & (index)) == 0) … … 118 161 extern void frame_reference_add(pfn_t); 119 162 163 extern count_t find_zone(pfn_t frame, count_t count, count_t hint); 120 164 extern count_t zone_create(pfn_t, count_t, pfn_t, zone_flags_t); 121 165 extern void *frame_get_parent(pfn_t, count_t); -
kernel/generic/include/mm/page.h
r5f0f29ce re49e234 62 62 63 63 extern uintptr_t hw_map(uintptr_t physaddr, size_t size); 64 extern void hw_area(void);65 64 66 65 #endif -
kernel/generic/src/ddi/ddi.c
r5f0f29ce re49e234 30 30 * @{ 31 31 */ 32 32 33 33 /** 34 34 * @file 35 * @brief 35 * @brief Device Driver Interface functions. 36 36 * 37 37 * This file contains functions that comprise the Device Driver Interface. … … 48 48 #include <synch/spinlock.h> 49 49 #include <syscall/copy.h> 50 #include <adt/ list.h>50 #include <adt/btree.h> 51 51 #include <arch.h> 52 52 #include <align.h> … … 56 56 SPINLOCK_INITIALIZE(parea_lock); 57 57 58 /** Listwith enabled physical memory areas. */59 static LIST_INITIALIZE(parea_head);58 /** B+tree with enabled physical memory areas. */ 59 static btree_t parea_btree; 60 60 61 61 /** Initialize DDI. */ 62 62 void ddi_init(void) 63 63 { 64 hw_area();64 btree_create(&parea_btree); 65 65 } 66 66 … … 69 69 * @param parea Pointer to physical area structure. 70 70 * 71 * @todo This function doesn't check for overlaps. It depends on the kernel to72 * create disjunct physical memory areas.73 71 */ 74 72 void ddi_parea_register(parea_t *parea) 75 73 { 76 ipl_t ipl; 77 78 ipl = interrupts_disable(); 74 ipl_t ipl = interrupts_disable(); 79 75 spinlock_lock(&parea_lock); 80 76 81 77 /* 82 * TODO: we should really check for overlaps here. 83 * However, we should be safe because the kernel is pretty sane. 84 */ 85 link_initialize(&parea->link); 86 list_append(&parea->link, &parea_head); 78 * We don't check for overlaps here as the kernel is pretty sane. 79 */ 80 btree_insert(&parea_btree, (btree_key_t) parea->pbase, parea, NULL); 87 81 88 82 spinlock_unlock(&parea_lock); … … 92 86 /** Map piece of physical memory into virtual address space of current task. 93 87 * 94 * @param pf Physical address of the starting frame.95 * @param vp Virtual address of the starting page.88 * @param pf Physical address of the starting frame. 89 * @param vp Virtual address of the starting page. 96 90 * @param pages Number of pages to map. 97 91 * @param flags Address space area flags for the mapping. 98 92 * 99 93 * @return 0 on success, EPERM if the caller lacks capabilities to use this 100 * syscall, ENOENT if there is no task matching the specified ID or the 101 * physical address space is not enabled for mapping and ENOMEM if there 102 * was a problem in creating address space area. 103 */ 104 static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, pfn_t pages, int flags) 105 { 106 ipl_t ipl; 107 cap_t caps; 94 * syscall, EBADMEM if pf or vf is not page aligned, ENOENT if there 95 * is no task matching the specified ID or the physical address space 96 * is not enabled for mapping and ENOMEM if there was a problem in 97 * creating address space area. 98 * 99 */ 100 static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, count_t pages, int flags) 101 { 102 ASSERT(TASK); 103 ASSERT((pf % FRAME_SIZE) == 0); 104 ASSERT((vp % PAGE_SIZE) == 0); 105 106 /* 107 * Make sure the caller is authorised to make this syscall. 108 */ 109 cap_t caps = cap_get(TASK); 110 if (!(caps & CAP_MEM_MANAGER)) 111 return EPERM; 112 108 113 mem_backend_data_t backend_data; 109 110 114 backend_data.base = pf; 111 115 backend_data.frames = pages; 112 116 113 /* 114 * Make sure the caller is authorised to make this syscall. 115 */ 116 caps = cap_get(TASK); 117 if (!(caps & CAP_MEM_MANAGER)) 118 return EPERM; 119 120 ipl = interrupts_disable(); 121 122 /* 123 * Check if the physical memory area is enabled for mapping. 124 */ 125 spinlock_lock(&parea_lock); 126 127 bool fnd = false; 128 link_t *cur; 129 130 for (cur = parea_head.next; cur != &parea_head; cur = cur->next) { 131 parea_t *parea = list_get_instance(cur, parea_t, link); 132 if ((parea->pbase <= pf) && (ADDR2PFN(pf - parea->pbase) + pages <= parea->frames)) { 133 fnd = true; 134 break; 135 } 136 } 137 138 spinlock_unlock(&parea_lock); 139 140 if (!fnd) { 141 /* 142 * Physical memory area cannot be mapped. 143 */ 144 interrupts_restore(ipl); 145 return ENOENT; 146 } 147 117 ipl_t ipl = interrupts_disable(); 118 119 /* Find the zone of the physical memory */ 120 spinlock_lock(&zones.lock); 121 count_t znum = find_zone(ADDR2PFN(pf), pages, 0); 122 123 if (znum == (count_t) -1) { 124 /* Frames not found in any zones 125 * -> assume it is hardware device and allow mapping 126 */ 127 spinlock_unlock(&zones.lock); 128 goto map; 129 } 130 131 if (zones.info[znum].flags & ZONE_FIRMWARE) { 132 /* Frames are part of firmware */ 133 spinlock_unlock(&zones.lock); 134 goto map; 135 } 136 137 if (zone_flags_available(zones.info[znum].flags)) { 138 /* Frames are part of physical memory, check if the memory 139 * region is enabled for mapping. 140 */ 141 spinlock_unlock(&zones.lock); 142 143 spinlock_lock(&parea_lock); 144 btree_node_t *nodep; 145 parea_t *parea = (parea_t *) btree_search(&parea_btree, 146 (btree_key_t) pf, &nodep); 147 148 if ((!parea) || (parea->frames < pages)) 149 goto err; 150 151 spinlock_unlock(&parea_lock); 152 goto map; 153 } 154 155 err: 156 spinlock_unlock(&zones.lock); 157 interrupts_restore(ipl); 158 return ENOENT; 159 160 map: 148 161 spinlock_lock(&TASK->lock); 149 162 150 if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE,151 163 if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, 164 AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) { 152 165 /* 153 166 * The address space area could not have been created. … … 175 188 * 176 189 * @return 0 on success, EPERM if the caller lacks capabilities to use this 177 * syscall, ENOENT if there is no task matching the specified ID. 190 * syscall, ENOENT if there is no task matching the specified ID. 191 * 178 192 */ 179 193 static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size) 180 194 { 181 ipl_t ipl;182 cap_t caps;183 task_t *t;184 int rc;185 186 195 /* 187 196 * Make sure the caller is authorised to make this syscall. 188 197 */ 189 cap s = cap_get(TASK);198 cap_t caps = cap_get(TASK); 190 199 if (!(caps & CAP_IO_MANAGER)) 191 200 return EPERM; 192 201 193 ipl = interrupts_disable();202 ipl_t ipl = interrupts_disable(); 194 203 spinlock_lock(&tasks_lock); 195 204 196 t = task_find_by_id(id);197 198 if ((!t ) || (!context_check(CONTEXT, t->context))) {205 task_t *task = task_find_by_id(id); 206 207 if ((!task) || (!context_check(CONTEXT, task->context))) { 199 208 /* 200 209 * There is no task with the specified ID … … 206 215 return ENOENT; 207 216 } 208 217 209 218 /* Lock the task and release the lock protecting tasks_btree. */ 210 spinlock_lock(&t ->lock);219 spinlock_lock(&task->lock); 211 220 spinlock_unlock(&tasks_lock); 212 213 rc = ddi_iospace_enable_arch(t, ioaddr, size); 214 215 spinlock_unlock(&t->lock); 216 interrupts_restore(ipl); 221 222 int rc = ddi_iospace_enable_arch(task, ioaddr, size); 223 224 spinlock_unlock(&task->lock); 225 interrupts_restore(ipl); 226 217 227 return rc; 218 228 } … … 226 236 * 227 237 * @return 0 on success, otherwise it returns error code found in errno.h 228 */ 238 * 239 */ 229 240 unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base, 230 241 unative_t pages, unative_t flags) … … 232 243 return (unative_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base, 233 244 FRAME_SIZE), ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE), 234 ( pfn_t) pages, (int) flags);245 (count_t) pages, (int) flags); 235 246 } 236 247 … … 240 251 * 241 252 * @return 0 on success, otherwise it returns error code found in errno.h 242 */ 253 * 254 */ 243 255 unative_t sys_iospace_enable(ddi_ioarg_t *uspace_io_arg) 244 256 { 245 257 ddi_ioarg_t arg; 246 int rc; 247 248 rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t)); 258 int rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t)); 249 259 if (rc != 0) 250 260 return (unative_t) rc; 251 261 252 262 return (unative_t) ddi_iospace_enable((task_id_t) arg.task_id, 253 263 (uintptr_t) arg.ioaddr, (size_t) arg.size); … … 257 267 * 258 268 * @param enable If non-zero, the preemption counter will be decremented, 259 * leading to potential enabling of preemption. Otherwise the preemption 260 * counter will be incremented, preventing preemption from occurring. 269 * leading to potential enabling of preemption. Otherwise 270 * the preemption counter will be incremented, preventing 271 * preemption from occurring. 261 272 * 262 273 * @return Zero on success or EPERM if callers capabilities are not sufficient. 263 */ 274 * 275 */ 264 276 unative_t sys_preempt_control(int enable) 265 277 { 266 278 if (!cap_get(TASK) & CAP_PREEMPT_CONTROL) 267 279 return EPERM; 280 268 281 if (enable) 269 282 preemption_enable(); 270 283 else 271 284 preemption_disable(); 285 272 286 return 0; 273 287 } -
kernel/generic/src/mm/frame.c
r5f0f29ce re49e234 49 49 #include <debug.h> 50 50 #include <adt/list.h> 51 #include <synch/spinlock.h>52 51 #include <synch/mutex.h> 53 52 #include <synch/condvar.h> … … 61 60 #include <config.h> 62 61 63 typedef struct { 64 count_t refcount; /**< Tracking of shared frames */ 65 uint8_t buddy_order; /**< Buddy system block order */ 66 link_t buddy_link; /**< Link to the next free block inside 67 one order */ 68 void *parent; /**< If allocated by slab, this points there */ 69 } frame_t; 70 71 typedef struct { 72 pfn_t base; /**< Frame_no of the first frame 73 in the frames array */ 74 count_t count; /**< Size of zone */ 75 count_t free_count; /**< Number of free frame_t 76 structures */ 77 count_t busy_count; /**< Number of busy frame_t 78 structures */ 79 zone_flags_t flags; /**< Type of the zone */ 80 81 frame_t *frames; /**< Array of frame_t structures 82 in this zone */ 83 buddy_system_t *buddy_system; /**< Buddy system for the zone */ 84 } zone_t; 85 86 /* 87 * The zoneinfo.lock must be locked when accessing zoneinfo structure. 88 * Some of the attributes in zone_t structures are 'read-only' 89 */ 90 typedef struct { 91 SPINLOCK_DECLARE(lock); 92 count_t count; 93 zone_t info[ZONES_MAX]; 94 } zones_t; 95 96 static zones_t zones; 62 zones_t zones; 97 63 98 64 /* … … 127 93 { 128 94 return (frame - zone->frames); 129 }130 131 static inline bool zone_flags_available(zone_flags_t flags)132 {133 return ((flags & (ZONE_RESERVED | ZONE_FIRMWARE)) == 0);134 95 } 135 96 … … 181 142 /* Move other zones up */ 182 143 count_t j; 183 for (j = i; j < zones.count; j++) 184 zones.info[j + 1] = zones.info[j]; 144 for (j = zones.count; j > i; j--) { 145 zones.info[j] = zones.info[j - 1]; 146 zones.info[j].buddy_system->data = 147 (void *) &zones.info[j - 1]; 148 } 185 149 186 150 zones.count++; … … 207 171 } 208 172 209 /** Find a zone with a given frame .173 /** Find a zone with a given frames. 210 174 * 211 175 * Assume interrupts are disabled and zones lock is … … 213 177 * 214 178 * @param frame Frame number contained in zone. 179 * @param count Number of frames to look for. 215 180 * @param hint Used as zone hint. 216 181 * … … 218 183 * 219 184 */ 220 static count_t find_zone(pfn_t frame, count_t hint)185 count_t find_zone(pfn_t frame, count_t count, count_t hint) 221 186 { 222 187 if (hint >= zones.count) … … 226 191 do { 227 192 if ((zones.info[i].base <= frame) 228 && (zones.info[i].base + zones.info[i].count > frame))193 && (zones.info[i].base + zones.info[i].count >= frame + count)) 229 194 return i; 230 195 … … 766 731 zones.info[z2].count); 767 732 768 /* Shift existing zones*/733 /* Move zones down */ 769 734 count_t i; 770 for (i = z2 + 1; i < zones.count; i++) 735 for (i = z2 + 1; i < zones.count; i++) { 771 736 zones.info[i - 1] = zones.info[i]; 737 zones.info[i - 1].buddy_system->data = 738 (void *) &zones.info[i - 1]; 739 } 740 772 741 zones.count--; 773 742 … … 965 934 spinlock_lock(&zones.lock); 966 935 967 count_t znum = find_zone(pfn, hint);936 count_t znum = find_zone(pfn, 1, hint); 968 937 969 938 ASSERT(znum != (count_t) -1); … … 981 950 spinlock_lock(&zones.lock); 982 951 983 count_t znum = find_zone(pfn, hint);952 count_t znum = find_zone(pfn, 1, hint); 984 953 985 954 ASSERT(znum != (count_t) -1); … … 1112 1081 */ 1113 1082 pfn_t pfn = ADDR2PFN(frame); 1114 count_t znum = find_zone(pfn, NULL);1083 count_t znum = find_zone(pfn, 1, NULL); 1115 1084 1116 1085 ASSERT(znum != (count_t) -1); … … 1151 1120 * First, find host frame zone for addr. 1152 1121 */ 1153 count_t znum = find_zone(pfn, NULL);1122 count_t znum = find_zone(pfn, 1, NULL); 1154 1123 1155 1124 ASSERT(znum != (count_t) -1); … … 1169 1138 count_t i; 1170 1139 for (i = 0; i < count; i++) { 1171 count_t znum = find_zone(start + i, 0);1140 count_t znum = find_zone(start + i, 1, 0); 1172 1141 if (znum == (count_t) -1) /* PFN not found */ 1173 1142 continue; … … 1238 1207 { 1239 1208 #ifdef __32_BITS__ 1240 printf("# base address f lags free frames busy frames\n");1241 printf("-- ------------ -------- ------------ ------------\n");1209 printf("# base address frames flags free frames busy frames\n"); 1210 printf("-- ------------ ------------ -------- ------------ ------------\n"); 1242 1211 #endif 1243 1212 1244 1213 #ifdef __64_BITS__ 1245 printf("# base address flags free frames busy frames\n");1246 printf("-- -------------------- -------- ------------ ------------\n");1214 printf("# base address frames flags free frames busy frames\n"); 1215 printf("-- -------------------- ------------ -------- ------------ ------------\n"); 1247 1216 #endif 1248 1217 … … 1270 1239 1271 1240 uintptr_t base = PFN2ADDR(zones.info[i].base); 1241 count_t count = zones.info[i].count; 1272 1242 zone_flags_t flags = zones.info[i].flags; 1273 1243 count_t free_count = zones.info[i].free_count; … … 1279 1249 bool available = zone_flags_available(flags); 1280 1250 1251 printf("%-2" PRIc, i); 1252 1281 1253 #ifdef __32_BITS__ 1282 printf("%-2" PRIc " %10p %c%c%c ", i, base, 1254 printf(" %10p", base); 1255 #endif 1256 1257 #ifdef __64_BITS__ 1258 printf(" %18p", base); 1259 #endif 1260 1261 printf(" %12" PRIc " %c%c%c ", count, 1283 1262 available ? 'A' : ' ', 1284 1263 (flags & ZONE_RESERVED) ? 'R' : ' ', 1285 1264 (flags & ZONE_FIRMWARE) ? 'F' : ' '); 1286 #endif1287 1288 #ifdef __64_BITS__1289 printf("%-2" PRIc " %18p %c%c%c ", i, base,1290 available ? 'A' : ' ',1291 (flags & ZONE_RESERVED) ? 'R' : ' ',1292 (flags & ZONE_FIRMWARE) ? 'F' : ' ');1293 #endif1294 1265 1295 1266 if (available) 1296 1267 printf("%12" PRIc " %12" PRIc, 1297 1268 free_count, busy_count); 1269 1298 1270 printf("\n"); 1299 1271 }
Note:
See TracChangeset
for help on using the changeset viewer.