/trunk/kernel/generic/include/align.h |
---|
26,13 → 26,13 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
/** @addtogroup generic |
* @ingroup others |
* @{ |
*/ |
/** |
* @file |
* @brief Macros for making values and addresses aligned. |
* @brief Macros for making values and addresses aligned. |
*/ |
#ifndef KERN_ALIGN_H_ |
43,7 → 43,7 |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
*/ |
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1)) |
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1)) |
/** Align to the nearest higher address. |
51,7 → 51,7 |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
*/ |
#define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1)) |
#define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1)) |
#endif |
/trunk/kernel/generic/include/mm/frame.h |
---|
39,6 → 39,7 |
#include <arch/types.h> |
#include <adt/list.h> |
#include <mm/buddy.h> |
#include <synch/spinlock.h> |
#include <arch/mm/page.h> |
#include <arch/mm/frame.h> |
67,15 → 68,52 |
typedef uint8_t zone_flags_t; |
/** Available zone (free for allocation) */ |
#define ZONE_AVAILABLE 0x00 |
/** Zone is reserved (not available for allocation) */ |
#define ZONE_RESERVED 0x08 |
#define ZONE_RESERVED 0x08 |
/** Zone is used by firmware (not available for allocation) */ |
#define ZONE_FIRMWARE 0x10 |
#define ZONE_FIRMWARE 0x10 |
/** Currently there is no equivalent zone flags |
for frame flags */ |
#define FRAME_TO_ZONE_FLAGS(frame_flags) 0 |
typedef struct { |
count_t refcount; /**< Tracking of shared frames */ |
uint8_t buddy_order; /**< Buddy system block order */ |
link_t buddy_link; /**< Link to the next free block inside |
one order */ |
void *parent; /**< If allocated by slab, this points there */ |
} frame_t; |
typedef struct { |
pfn_t base; /**< Frame_no of the first frame |
in the frames array */ |
count_t count; /**< Size of zone */ |
count_t free_count; /**< Number of free frame_t |
structures */ |
count_t busy_count; /**< Number of busy frame_t |
structures */ |
zone_flags_t flags; /**< Type of the zone */ |
frame_t *frames; /**< Array of frame_t structures |
in this zone */ |
buddy_system_t *buddy_system; /**< Buddy system for the zone */ |
} zone_t; |
/* |
* The zoneinfo.lock must be locked when accessing zoneinfo structure. |
* Some of the attributes in zone_t structures are 'read-only' |
*/ |
typedef struct { |
SPINLOCK_DECLARE(lock); |
count_t count; |
zone_t info[ZONES_MAX]; |
} zones_t; |
extern zones_t zones; |
static inline uintptr_t PFN2ADDR(pfn_t frame) |
{ |
return (uintptr_t) (frame << FRAME_WIDTH); |
98,6 → 136,11 |
return (size_t) (frames << FRAME_WIDTH); |
} |
static inline bool zone_flags_available(zone_flags_t flags) |
{ |
return ((flags & (ZONE_RESERVED | ZONE_FIRMWARE)) == 0); |
} |
#define IS_BUDDY_ORDER_OK(index, order) \ |
((~(((unative_t) -1) << (order)) & (index)) == 0) |
#define IS_BUDDY_LEFT_BLOCK(zone, frame) \ |
117,6 → 160,7 |
extern void frame_free(uintptr_t); |
extern void frame_reference_add(pfn_t); |
extern count_t find_zone(pfn_t frame, count_t count, count_t hint); |
extern count_t zone_create(pfn_t, count_t, pfn_t, zone_flags_t); |
extern void *frame_get_parent(pfn_t, count_t); |
extern void frame_set_parent(pfn_t, void *, count_t); |
/trunk/kernel/generic/include/mm/page.h |
---|
61,7 → 61,6 |
extern void map_structure(uintptr_t s, size_t size); |
extern uintptr_t hw_map(uintptr_t physaddr, size_t size); |
extern void hw_area(void); |
#endif |
/trunk/kernel/generic/src/ddi/ddi.c |
---|
29,10 → 29,10 |
/** @addtogroup genericddi |
* @{ |
*/ |
/** |
* @file |
* @brief Device Driver Interface functions. |
* @brief Device Driver Interface functions. |
* |
* This file contains functions that comprise the Device Driver Interface. |
* These are the functions for mapping physical memory and enabling I/O |
47,7 → 47,7 |
#include <mm/as.h> |
#include <synch/spinlock.h> |
#include <syscall/copy.h> |
#include <adt/list.h> |
#include <adt/btree.h> |
#include <arch.h> |
#include <align.h> |
#include <errno.h> |
55,13 → 55,13 |
/** This lock protects the parea_btree. */ |
SPINLOCK_INITIALIZE(parea_lock); |
/** List with enabled physical memory areas. */ |
static LIST_INITIALIZE(parea_head); |
/** B+tree with enabled physical memory areas. */ |
static btree_t parea_btree; |
/** Initialize DDI. */ |
void ddi_init(void) |
{ |
hw_area(); |
btree_create(&parea_btree); |
} |
/** Enable piece of physical memory for mapping by physmem_map(). |
68,22 → 68,16 |
* |
* @param parea Pointer to physical area structure. |
* |
* @todo This function doesn't check for overlaps. It depends on the kernel to |
* create disjunct physical memory areas. |
*/ |
void ddi_parea_register(parea_t *parea) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&parea_lock); |
/* |
* TODO: we should really check for overlaps here. |
* However, we should be safe because the kernel is pretty sane. |
* We don't check for overlaps here as the kernel is pretty sane. |
*/ |
link_initialize(&parea->link); |
list_append(&parea->link, &parea_head); |
btree_insert(&parea_btree, (btree_key_t) parea->pbase, parea, NULL); |
spinlock_unlock(&parea_lock); |
interrupts_restore(ipl); |
91,64 → 85,83 |
/** Map piece of physical memory into virtual address space of current task. |
* |
* @param pf Physical address of the starting frame. |
* @param vp Virtual address of the starting page. |
* @param pf Physical address of the starting frame. |
* @param vp Virtual address of the starting page. |
* @param pages Number of pages to map. |
* @param flags Address space area flags for the mapping. |
* |
* @return 0 on success, EPERM if the caller lacks capabilities to use this |
* syscall, ENOENT if there is no task matching the specified ID or the |
* physical address space is not enabled for mapping and ENOMEM if there |
* was a problem in creating address space area. |
* syscall, EBADMEM if pf or vf is not page aligned, ENOENT if there |
* is no task matching the specified ID or the physical address space |
* is not enabled for mapping and ENOMEM if there was a problem in |
* creating address space area. |
* |
*/ |
static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, pfn_t pages, int flags) |
static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, count_t pages, int flags) |
{ |
ipl_t ipl; |
cap_t caps; |
mem_backend_data_t backend_data; |
ASSERT(TASK); |
ASSERT((pf % FRAME_SIZE) == 0); |
ASSERT((vp % PAGE_SIZE) == 0); |
backend_data.base = pf; |
backend_data.frames = pages; |
/* |
* Make sure the caller is authorised to make this syscall. |
*/ |
caps = cap_get(TASK); |
cap_t caps = cap_get(TASK); |
if (!(caps & CAP_MEM_MANAGER)) |
return EPERM; |
ipl = interrupts_disable(); |
mem_backend_data_t backend_data; |
backend_data.base = pf; |
backend_data.frames = pages; |
/* |
* Check if the physical memory area is enabled for mapping. |
*/ |
spinlock_lock(&parea_lock); |
ipl_t ipl = interrupts_disable(); |
bool fnd = false; |
link_t *cur; |
/* Find the zone of the physical memory */ |
spinlock_lock(&zones.lock); |
count_t znum = find_zone(ADDR2PFN(pf), pages, 0); |
for (cur = parea_head.next; cur != &parea_head; cur = cur->next) { |
parea_t *parea = list_get_instance(cur, parea_t, link); |
if ((parea->pbase <= pf) && (ADDR2PFN(pf - parea->pbase) + pages <= parea->frames)) { |
fnd = true; |
break; |
} |
if (znum == (count_t) -1) { |
/* Frames not found in any zones |
* -> assume it is hardware device and allow mapping |
*/ |
spinlock_unlock(&zones.lock); |
goto map; |
} |
spinlock_unlock(&parea_lock); |
if (zones.info[znum].flags & ZONE_FIRMWARE) { |
/* Frames are part of firmware */ |
spinlock_unlock(&zones.lock); |
goto map; |
} |
if (!fnd) { |
/* |
* Physical memory area cannot be mapped. |
if (zone_flags_available(zones.info[znum].flags)) { |
/* Frames are part of physical memory, check if the memory |
* region is enabled for mapping. |
*/ |
interrupts_restore(ipl); |
return ENOENT; |
spinlock_unlock(&zones.lock); |
spinlock_lock(&parea_lock); |
btree_node_t *nodep; |
parea_t *parea = (parea_t *) btree_search(&parea_btree, |
(btree_key_t) pf, &nodep); |
if ((!parea) || (parea->frames < pages)) |
goto err; |
spinlock_unlock(&parea_lock); |
goto map; |
} |
err: |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return ENOENT; |
map: |
spinlock_lock(&TASK->lock); |
if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE, |
&phys_backend, &backend_data)) { |
if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, |
AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) { |
/* |
* The address space area could not have been created. |
* We report it using ENOMEM. |
174,28 → 187,24 |
* @param size Size of the enabled I/O space.. |
* |
* @return 0 on success, EPERM if the caller lacks capabilities to use this |
* syscall, ENOENT if there is no task matching the specified ID. |
* syscall, ENOENT if there is no task matching the specified ID. |
* |
*/ |
static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size) |
{ |
ipl_t ipl; |
cap_t caps; |
task_t *t; |
int rc; |
/* |
* Make sure the caller is authorised to make this syscall. |
*/ |
caps = cap_get(TASK); |
cap_t caps = cap_get(TASK); |
if (!(caps & CAP_IO_MANAGER)) |
return EPERM; |
ipl = interrupts_disable(); |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&tasks_lock); |
t = task_find_by_id(id); |
task_t *task = task_find_by_id(id); |
if ((!t) || (!context_check(CONTEXT, t->context))) { |
if ((!task) || (!context_check(CONTEXT, task->context))) { |
/* |
* There is no task with the specified ID |
* or the task belongs to a different security |
205,15 → 214,16 |
interrupts_restore(ipl); |
return ENOENT; |
} |
/* Lock the task and release the lock protecting tasks_btree. */ |
spinlock_lock(&t->lock); |
spinlock_lock(&task->lock); |
spinlock_unlock(&tasks_lock); |
rc = ddi_iospace_enable_arch(t, ioaddr, size); |
spinlock_unlock(&t->lock); |
int rc = ddi_iospace_enable_arch(task, ioaddr, size); |
spinlock_unlock(&task->lock); |
interrupts_restore(ipl); |
return rc; |
} |
225,13 → 235,14 |
* @param flags Flags of newly mapped pages |
* |
* @return 0 on success, otherwise it returns error code found in errno.h |
*/ |
* |
*/ |
unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base, |
unative_t pages, unative_t flags) |
{ |
return (unative_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base, |
FRAME_SIZE), ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE), |
(pfn_t) pages, (int) flags); |
(count_t) pages, (int) flags); |
} |
/** Wrapper for SYS_ENABLE_IOSPACE syscall. |
239,16 → 250,15 |
* @param uspace_io_arg User space address of DDI argument structure. |
* |
* @return 0 on success, otherwise it returns error code found in errno.h |
*/ |
* |
*/ |
unative_t sys_iospace_enable(ddi_ioarg_t *uspace_io_arg) |
{ |
ddi_ioarg_t arg; |
int rc; |
rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t)); |
int rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t)); |
if (rc != 0) |
return (unative_t) rc; |
return (unative_t) ddi_iospace_enable((task_id_t) arg.task_id, |
(uintptr_t) arg.ioaddr, (size_t) arg.size); |
} |
256,19 → 266,23 |
/** Disable or enable preemption. |
* |
* @param enable If non-zero, the preemption counter will be decremented, |
* leading to potential enabling of preemption. Otherwise the preemption |
* counter will be incremented, preventing preemption from occurring. |
* leading to potential enabling of preemption. Otherwise |
* the preemption counter will be incremented, preventing |
* preemption from occurring. |
* |
* @return Zero on success or EPERM if callers capabilities are not sufficient. |
*/ |
* |
*/ |
unative_t sys_preempt_control(int enable) |
{ |
if (!cap_get(TASK) & CAP_PREEMPT_CONTROL) |
return EPERM; |
if (enable) |
preemption_enable(); |
else |
preemption_disable(); |
return 0; |
} |
/trunk/kernel/generic/src/mm/frame.c |
---|
48,7 → 48,6 |
#include <panic.h> |
#include <debug.h> |
#include <adt/list.h> |
#include <synch/spinlock.h> |
#include <synch/mutex.h> |
#include <synch/condvar.h> |
#include <arch/asm.h> |
60,42 → 59,9 |
#include <macros.h> |
#include <config.h> |
typedef struct { |
count_t refcount; /**< Tracking of shared frames */ |
uint8_t buddy_order; /**< Buddy system block order */ |
link_t buddy_link; /**< Link to the next free block inside |
one order */ |
void *parent; /**< If allocated by slab, this points there */ |
} frame_t; |
zones_t zones; |
typedef struct { |
pfn_t base; /**< Frame_no of the first frame |
in the frames array */ |
count_t count; /**< Size of zone */ |
count_t free_count; /**< Number of free frame_t |
structures */ |
count_t busy_count; /**< Number of busy frame_t |
structures */ |
zone_flags_t flags; /**< Type of the zone */ |
frame_t *frames; /**< Array of frame_t structures |
in this zone */ |
buddy_system_t *buddy_system; /**< Buddy system for the zone */ |
} zone_t; |
/* |
* The zoneinfo.lock must be locked when accessing zoneinfo structure. |
* Some of the attributes in zone_t structures are 'read-only' |
*/ |
typedef struct { |
SPINLOCK_DECLARE(lock); |
count_t count; |
zone_t info[ZONES_MAX]; |
} zones_t; |
static zones_t zones; |
/* |
* Synchronization primitives used to sleep when there is no memory |
* available. |
*/ |
128,11 → 94,6 |
return (frame - zone->frames); |
} |
static inline bool zone_flags_available(zone_flags_t flags) |
{ |
return ((flags & (ZONE_RESERVED | ZONE_FIRMWARE)) == 0); |
} |
/** Initialize frame structure. |
* |
* @param frame Frame structure to be initialized. |
180,8 → 141,11 |
/* Move other zones up */ |
count_t j; |
for (j = i; j < zones.count; j++) |
zones.info[j + 1] = zones.info[j]; |
for (j = zones.count; j > i; j--) { |
zones.info[j] = zones.info[j - 1]; |
zones.info[j].buddy_system->data = |
(void *) &zones.info[j - 1]; |
} |
zones.count++; |
206,18 → 170,19 |
return total; |
} |
/** Find a zone with a given frame. |
/** Find a zone with a given frames. |
* |
* Assume interrupts are disabled and zones lock is |
* locked. |
* |
* @param frame Frame number contained in zone. |
* @param count Number of frames to look for. |
* @param hint Used as zone hint. |
* |
* @return Zone index or -1 if not found. |
* |
*/ |
static count_t find_zone(pfn_t frame, count_t hint) |
count_t find_zone(pfn_t frame, count_t count, count_t hint) |
{ |
if (hint >= zones.count) |
hint = 0; |
225,7 → 190,7 |
count_t i = hint; |
do { |
if ((zones.info[i].base <= frame) |
&& (zones.info[i].base + zones.info[i].count > frame)) |
&& (zones.info[i].base + zones.info[i].count >= frame + count)) |
return i; |
i++; |
765,10 → 730,14 |
ADDR2PFN(KA2PA((uintptr_t) zones.info[z2].frames)), |
zones.info[z2].count); |
/* Shift existing zones */ |
/* Move zones down */ |
count_t i; |
for (i = z2 + 1; i < zones.count; i++) |
for (i = z2 + 1; i < zones.count; i++) { |
zones.info[i - 1] = zones.info[i]; |
zones.info[i - 1].buddy_system->data = |
(void *) &zones.info[i - 1]; |
} |
zones.count--; |
errout: |
964,7 → 933,7 |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
count_t znum = find_zone(pfn, hint); |
count_t znum = find_zone(pfn, 1, hint); |
ASSERT(znum != (count_t) -1); |
980,7 → 949,7 |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
count_t znum = find_zone(pfn, hint); |
count_t znum = find_zone(pfn, 1, hint); |
ASSERT(znum != (count_t) -1); |
1111,7 → 1080,7 |
* First, find host frame zone for addr. |
*/ |
pfn_t pfn = ADDR2PFN(frame); |
count_t znum = find_zone(pfn, NULL); |
count_t znum = find_zone(pfn, 1, NULL); |
ASSERT(znum != (count_t) -1); |
1150,7 → 1119,7 |
/* |
* First, find host frame zone for addr. |
*/ |
count_t znum = find_zone(pfn, NULL); |
count_t znum = find_zone(pfn, 1, NULL); |
ASSERT(znum != (count_t) -1); |
1168,7 → 1137,7 |
count_t i; |
for (i = 0; i < count; i++) { |
count_t znum = find_zone(start + i, 0); |
count_t znum = find_zone(start + i, 1, 0); |
if (znum == (count_t) -1) /* PFN not found */ |
continue; |
1237,13 → 1206,13 |
void zone_print_list(void) |
{ |
#ifdef __32_BITS__ |
printf("# base address flags free frames busy frames\n"); |
printf("-- ------------ -------- ------------ ------------\n"); |
printf("# base address frames flags free frames busy frames\n"); |
printf("-- ------------ ------------ -------- ------------ ------------\n"); |
#endif |
#ifdef __64_BITS__ |
printf("# base address flags free frames busy frames\n"); |
printf("-- -------------------- -------- ------------ ------------\n"); |
printf("# base address frames flags free frames busy frames\n"); |
printf("-- -------------------- ------------ -------- ------------ ------------\n"); |
#endif |
/* |
1269,6 → 1238,7 |
} |
uintptr_t base = PFN2ADDR(zones.info[i].base); |
count_t count = zones.info[i].count; |
zone_flags_t flags = zones.info[i].flags; |
count_t free_count = zones.info[i].free_count; |
count_t busy_count = zones.info[i].busy_count; |
1278,23 → 1248,25 |
bool available = zone_flags_available(flags); |
printf("%-2" PRIc, i); |
#ifdef __32_BITS__ |
printf("%-2" PRIc " %10p %c%c%c ", i, base, |
available ? 'A' : ' ', |
(flags & ZONE_RESERVED) ? 'R' : ' ', |
(flags & ZONE_FIRMWARE) ? 'F' : ' '); |
printf(" %10p", base); |
#endif |
#ifdef __64_BITS__ |
printf("%-2" PRIc " %18p %c%c%c ", i, base, |
printf(" %18p", base); |
#endif |
printf(" %12" PRIc " %c%c%c ", count, |
available ? 'A' : ' ', |
(flags & ZONE_RESERVED) ? 'R' : ' ', |
(flags & ZONE_FIRMWARE) ? 'F' : ' '); |
#endif |
if (available) |
printf("%12" PRIc " %12" PRIc, |
free_count, busy_count); |
printf("\n"); |
} |
} |
/trunk/kernel/arch/sparc64/include/mm/frame.h |
---|
73,7 → 73,6 |
typedef union frame_address frame_address_t; |
extern uintptr_t last_frame; |
extern uintptr_t end_frame; |
extern void frame_arch_init(void); |
#define physmem_print() |
/trunk/kernel/arch/sparc64/src/mm/frame.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64mm |
/** @addtogroup sparc64mm |
* @{ |
*/ |
/** @file |
41,7 → 41,6 |
#include <macros.h> |
uintptr_t last_frame = NULL; |
uintptr_t end_frame = NULL; |
/** Create memory zones according to information stored in bootinfo. |
* |
80,8 → 79,6 |
*/ |
frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1); |
} |
end_frame = last_frame; |
} |
/** @} |
/trunk/kernel/arch/sparc64/src/mm/page.c |
---|
41,11 → 41,7 |
#include <debug.h> |
#include <align.h> |
#include <config.h> |
#include <ddi/ddi.h> |
/** Physical memory area for devices. */ |
static parea_t dev_area; |
#ifdef CONFIG_SMP |
/** Entries locked in DTLB of BSP. |
* |
168,12 → 164,5 |
return virtaddr; |
} |
void hw_area(void) |
{ |
dev_area.pbase = end_frame; |
dev_area.frames = SIZE2FRAMES(0x7ffffffffff - end_frame); |
ddi_parea_register(&dev_area); |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia64/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64mm |
/** @addtogroup ia64mm |
* @{ |
*/ |
/** @file |
35,8 → 35,8 |
#ifndef KERN_ia64_FRAME_H_ |
#define KERN_ia64_FRAME_H_ |
#define FRAME_WIDTH 14 /* 16K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 14 /* 16K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
44,7 → 44,6 |
#include <arch/types.h> |
extern uintptr_t last_frame; |
extern uintptr_t end_frame; |
extern void frame_arch_init(void); |
#define physmem_print() |
/trunk/kernel/arch/ia64/src/mm/frame.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64mm |
/** @addtogroup ia64mm |
* @{ |
*/ |
/** @file |
51,7 → 51,6 |
#define MINCONF 1 |
uintptr_t last_frame = 0; |
uintptr_t end_frame = 0; |
void frame_arch_init(void) |
{ |
/trunk/kernel/arch/ia64/src/mm/page.c |
---|
48,11 → 48,7 |
#include <arch/barrier.h> |
#include <memstr.h> |
#include <align.h> |
#include <ddi/ddi.h> |
/** Physical memory area for devices. */ |
static parea_t dev_area; |
static void set_environment(void); |
/** Initialize ia64 virtual address translation subsystem. */ |
67,9 → 63,9 |
void set_environment(void) |
{ |
region_register rr; |
pta_register pta; |
pta_register pta; |
int i; |
#ifdef CONFIG_VHPT |
#ifdef CONFIG_VHPT |
uintptr_t vhpt_base; |
#endif |
278,12 → 274,5 |
return (uintptr_t)((uint64_t)(PA2KA(physaddr)) + VIO_OFFSET); |
} |
void hw_area(void) |
{ |
dev_area.pbase = end_frame; |
dev_area.frames = SIZE2FRAMES(0x7fffffffffffffffUL - end_frame); |
ddi_parea_register(&dev_area); |
} |
/** @} |
*/ |
/trunk/kernel/arch/arm32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
36,8 → 36,8 |
#ifndef KERN_arm32_FRAME_H_ |
#define KERN_arm32_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4KB frames */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4KB frames */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
44,14 → 44,13 |
#include <arch/types.h> |
#define BOOT_PAGE_TABLE_SIZE 0x4000 |
#define BOOT_PAGE_TABLE_ADDRESS 0x4000 |
#define BOOT_PAGE_TABLE_SIZE 0x4000 |
#define BOOT_PAGE_TABLE_ADDRESS 0x4000 |
#define BOOT_PAGE_TABLE_START_FRAME (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH) |
#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH) |
extern uintptr_t last_frame; |
extern uintptr_t end_frame; |
extern void frame_arch_init(void); |
extern void boot_page_table_free(void); |
/trunk/kernel/arch/arm32/src/mm/frame.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
41,7 → 41,6 |
/** Address of the last frame in the memory. */ |
uintptr_t last_frame = 0; |
uintptr_t end_frame = 0; |
/** Creates memory zones. */ |
void frame_arch_init(void) |
50,7 → 49,6 |
zone_create(0, ADDR2PFN(machine_get_memory_size()), |
BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0); |
last_frame = machine_get_memory_size(); |
end_frame = last_frame; |
/* blacklist boot page table */ |
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME, |
/trunk/kernel/arch/arm32/src/mm/page.c |
---|
43,11 → 43,7 |
#include <arch/types.h> |
#include <interrupt.h> |
#include <arch/mm/frame.h> |
#include <ddi/ddi.h> |
/** Physical memory area for devices. */ |
static parea_t dev_area; |
/** Initializes page tables. |
* |
* 1:1 virtual-physical mapping is created in kernel address space. Mapping |
110,12 → 106,5 |
return virtaddr; |
} |
void hw_area(void) |
{ |
dev_area.pbase = end_frame; |
dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame); |
ddi_parea_register(&dev_area); |
} |
/** @} |
*/ |
/trunk/kernel/arch/ppc32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32mm |
/** @addtogroup ppc32mm |
* @{ |
*/ |
/** @file |
35,8 → 35,8 |
#ifndef KERN_ppc32_FRAME_H_ |
#define KERN_ppc32_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
44,7 → 44,6 |
#include <arch/types.h> |
extern uintptr_t last_frame; |
extern uintptr_t end_frame; |
extern void frame_arch_init(void); |
extern void physmem_print(void); |
/trunk/kernel/arch/ppc32/src/mm/frame.c |
---|
40,7 → 40,6 |
#include <print.h> |
uintptr_t last_frame = 0; |
uintptr_t end_frame = 0; |
void physmem_print(void) |
{ |
76,8 → 75,6 |
last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE); |
} |
end_frame = last_frame; |
/* First is exception vector, second is 'implementation specific', |
third and fourth is reserved, other contain real mode code */ |
frame_mark_unavailable(0, 8); |
/trunk/kernel/arch/ppc32/src/mm/page.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32mm |
/** @addtogroup ppc32mm |
* @{ |
*/ |
/** @file |
37,11 → 37,7 |
#include <mm/as.h> |
#include <align.h> |
#include <config.h> |
#include <ddi/ddi.h> |
/** Physical memory area for devices. */ |
static parea_t dev_area; |
void page_arch_init(void) |
{ |
if (config.cpu_active == 1) |
67,12 → 63,5 |
return virtaddr; |
} |
void hw_area(void) |
{ |
dev_area.pbase = end_frame; |
dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame); |
ddi_parea_register(&dev_area); |
} |
/** @} |
*/ |
/trunk/kernel/arch/amd64/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64mm |
/** @addtogroup amd64mm |
* @{ |
*/ |
/** @file |
39,12 → 39,11 |
#include <arch/types.h> |
#endif /* __ASM__ */ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifndef __ASM__ |
extern uintptr_t last_frame; |
extern uintptr_t end_frame; |
extern void frame_arch_init(void); |
extern void physmem_print(void); |
#endif /* __ASM__ */ |
/trunk/kernel/arch/amd64/src/mm/page.c |
---|
34,8 → 34,6 |
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <genarch/drivers/ega/ega.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <arch/mm/frame.h> |
#include <mm/page.h> |
#include <mm/frame.h> |
48,12 → 46,7 |
#include <print.h> |
#include <panic.h> |
#include <align.h> |
#include <ddi/ddi.h> |
/** Physical memory area for devices. */ |
static parea_t dev_area; |
static parea_t ega_area; |
/* Definitions for identity page mapper */ |
pte_t helper_ptl1[512] __attribute__((aligned (PAGE_SIZE))); |
pte_t helper_ptl2[512] __attribute__((aligned (PAGE_SIZE))); |
221,16 → 214,5 |
return virtaddr; |
} |
void hw_area(void) |
{ |
dev_area.pbase = end_frame; |
dev_area.frames = SIZE2FRAMES(0xfffffffffffff - end_frame); |
ddi_parea_register(&dev_area); |
ega_area.pbase = EGA_VIDEORAM; |
ega_area.frames = SIZE2FRAMES(EGA_VRAM_SIZE); |
ddi_parea_register(&ega_area); |
} |
/** @} |
*/ |
/trunk/kernel/arch/mips32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32mm |
/** @addtogroup mips32mm |
* @{ |
*/ |
/** @file |
46,8 → 46,6 |
extern void frame_arch_init(void); |
extern void physmem_print(void); |
extern uintptr_t end_frame; |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
/trunk/kernel/arch/mips32/src/mm/frame.c |
---|
65,9 → 65,7 |
static count_t phys_regions_count = 0; |
static phys_region_t phys_regions[MAX_REGIONS]; |
uintptr_t end_frame = 0; |
/** Check whether frame is available |
* |
* Returns true if given frame is generally available for use. |
238,10 → 236,8 |
} |
} |
end_frame = frame; |
frame_add_region(start_frame, frame); |
frame_add_region(start_frame, end_frame); |
/* Blacklist interrupt vector frame */ |
frame_mark_unavailable(0, 1); |
/trunk/kernel/arch/mips32/src/mm/page.c |
---|
36,11 → 36,7 |
#include <genarch/mm/page_pt.h> |
#include <mm/page.h> |
#include <mm/frame.h> |
#include <ddi/ddi.h> |
/** Physical memory area for devices. */ |
static parea_t dev_area; |
void page_arch_init(void) |
{ |
page_mapping_operations = &pt_mapping_operations; |
55,12 → 51,5 |
return physaddr + 0xa0000000; |
} |
void hw_area(void) |
{ |
dev_area.pbase = end_frame; |
dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame); |
ddi_parea_register(&dev_area); |
} |
/** @} |
*/ |
/trunk/kernel/arch/ia32/include/boot/memmap.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
35,24 → 35,29 |
#ifndef KERN_ia32_MEMMAP_H_ |
#define KERN_ia32_MEMMAP_H_ |
/* E820h memory range types - other values*/ |
/* Free memory */ |
#define MEMMAP_MEMORY_AVAILABLE 1 |
/* Not available for OS */ |
#define MEMMAP_MEMORY_RESERVED 2 |
/* OS may use it after reading ACPI table */ |
#define MEMMAP_MEMORY_ACPI 3 |
/* Unusable, required to be saved and restored across an NVS sleep */ |
#define MEMMAP_MEMORY_NVS 4 |
/* Corrupted memory */ |
#define MEMMAP_MEMORY_UNUSABLE 5 |
/* E820h memory range types */ |
/* size of one entry */ |
#define MEMMAP_E820_RECORD_SIZE 20 |
/* maximum entries */ |
#define MEMMAP_E820_MAX_RECORDS 32 |
/* Free memory */ |
#define MEMMAP_MEMORY_AVAILABLE 1 |
/* Not available for OS */ |
#define MEMMAP_MEMORY_RESERVED 2 |
/* OS may use it after reading ACPI table */ |
#define MEMMAP_MEMORY_ACPI 3 |
/* Unusable, required to be saved and restored across an NVS sleep */ |
#define MEMMAP_MEMORY_NVS 4 |
/* Corrupted memory */ |
#define MEMMAP_MEMORY_UNUSABLE 5 |
/* Size of one entry */ |
#define MEMMAP_E820_RECORD_SIZE 20 |
/* Maximum entries */ |
#define MEMMAP_E820_MAX_RECORDS 32 |
#ifndef __ASM__ |
#include <arch/types.h> |
/trunk/kernel/arch/ia32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32mm |
/** @addtogroup ia32mm |
* @{ |
*/ |
/** @file |
35,8 → 35,8 |
#ifndef KERN_ia32_FRAME_H_ |
#define KERN_ia32_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
44,7 → 44,6 |
#include <arch/types.h> |
extern uintptr_t last_frame; |
extern uintptr_t end_frame; |
extern void frame_arch_init(void); |
extern void physmem_print(void); |
/trunk/kernel/arch/ia32/src/mm/frame.c |
---|
50,34 → 50,62 |
size_t hardcoded_unmapped_kdata_size = 0; |
uintptr_t last_frame = 0; |
uintptr_t end_frame = 0; |
static void init_e820_memory(pfn_t minconf) |
{ |
unsigned int i; |
pfn_t start, conf; |
size_t size; |
for (i = 0; i < e820counter; i++) { |
uint64_t base = e820table[i].base_address; |
uint64_t size = e820table[i].size; |
#ifdef __32_BITS__ |
/* Ignore physical memory above 4 GB */ |
if ((base >> 32) != 0) |
continue; |
/* Clip regions above 4 GB */ |
if (((base + size) >> 32) != 0) |
size = 0xffffffff - base; |
#endif |
pfn_t pfn; |
count_t count; |
if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { |
start = ADDR2PFN(ALIGN_UP(e820table[i].base_address, FRAME_SIZE)); |
size = SIZE2FRAMES(ALIGN_DOWN(e820table[i].size, FRAME_SIZE)); |
/* To be safe, make available zone possibly smaller */ |
pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)); |
if ((minconf < start) || (minconf >= start + size)) |
conf = start; |
pfn_t conf; |
if ((minconf < pfn) || (minconf >= pfn + count)) |
conf = pfn; |
else |
conf = minconf; |
zone_create(start, size, conf, 0); |
zone_create(pfn, count, conf, ZONE_AVAILABLE); |
if (last_frame < ALIGN_UP(e820table[i].base_address + |
e820table[i].size, FRAME_SIZE)) |
last_frame = |
ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE); |
// XXX this has to be removed |
if (last_frame < ALIGN_UP(base + size, FRAME_SIZE)) |
last_frame = ALIGN_UP(base + size, FRAME_SIZE); |
} |
if (e820table[i].type == MEMMAP_MEMORY_RESERVED) { |
/* To be safe, make reserved zone possibly larger */ |
pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE)); |
zone_create(pfn, count, 0, ZONE_RESERVED); |
} |
if (e820table[i].type == MEMMAP_MEMORY_ACPI) { |
/* To be safe, make firmware zone possibly larger */ |
pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE)); |
zone_create(pfn, count, 0, ZONE_FIRMWARE); |
} |
} |
end_frame = last_frame; |
} |
static char *e820names[] = { |
/trunk/kernel/arch/ia32/src/mm/page.c |
---|
34,8 → 34,6 |
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <genarch/drivers/ega/ega.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <arch/mm/frame.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
50,17 → 48,12 |
#include <memstr.h> |
#include <print.h> |
#include <interrupt.h> |
#include <ddi/ddi.h> |
/** Physical memory area for devices. */ |
static parea_t dev_area; |
static parea_t ega_area; |
void page_arch_init(void) |
{ |
uintptr_t cur; |
int flags; |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
73,12 → 66,12 |
flags |= PAGE_GLOBAL; |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
exc_register(14, "page_fault", (iroutine) page_fault); |
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); |
} else |
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); |
paging_on(); |
} |
100,17 → 93,6 |
return virtaddr; |
} |
void hw_area(void) |
{ |
dev_area.pbase = end_frame; |
dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame); |
ddi_parea_register(&dev_area); |
ega_area.pbase = EGA_VIDEORAM; |
ega_area.frames = SIZE2FRAMES(EGA_VRAM_SIZE); |
ddi_parea_register(&ega_area); |
} |
void page_fault(int n __attribute__((unused)), istate_t *istate) |
{ |
uintptr_t page; |