Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3972 → Rev 3973

/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;