Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev HEAD → Rev 2131

/branches/arm/kernel/generic/include/mm/as.h
53,6 → 53,10
#include <adt/btree.h>
#include <lib/elf.h>
 
#ifdef __OBJC__
#include <lib/objc.h>
#endif
 
/**
* Defined to be true if user address space and kernel address space shadow each
* other.
80,6 → 84,45
/** The page fault was caused by memcpy_from_uspace() or memcpy_to_uspace(). */
#define AS_PF_DEFER 2
 
#ifdef __OBJC__
@interface as_t : base_t {
@public
/** Protected by asidlock. */
link_t inactive_as_with_asid_link;
mutex_t lock;
/** Number of references (i.e tasks that reference this as). */
count_t refcount;
/** Number of processors on wich is this address space active. */
count_t cpu_refcount;
/** B+tree of address space areas. */
btree_t as_area_btree;
/**
* Address space identifier.
* Constant on architectures that do not support ASIDs.
*/
asid_t asid;
/** Non-generic content. */
as_genarch_t genarch;
/** Architecture specific content. */
as_arch_t arch;
}
 
+ (pte_t *) page_table_create: (int) flags;
+ (void) page_table_destroy: (pte_t *) page_table;
- (void) page_table_lock: (bool) _lock;
- (void) page_table_unlock: (bool) unlock;
 
@end
 
#else
 
/** Address space structure.
*
* as_t contains the list of as_areas of userspace accessible
90,26 → 133,24
typedef struct as {
/** Protected by asidlock. */
link_t inactive_as_with_asid_link;
/**
* Number of processors on wich is this address space active.
* Protected by asidlock.
*/
size_t cpu_refcount;
/**
* Address space identifier.
* Constant on architectures that do not support ASIDs.
* Protected by asidlock.
*/
asid_t asid;
 
mutex_t lock;
 
/** Number of references (i.e tasks that reference this as). */
atomic_t refcount;
count_t refcount;
 
mutex_t lock;
/** Number of processors on wich is this address space active. */
count_t cpu_refcount;
 
/** B+tree of address space areas. */
btree_t as_area_btree;
/**
* Address space identifier.
* Constant on architectures that do not support ASIDs.
*/
asid_t asid;
/** Non-generic content. */
as_genarch_t genarch;
 
123,6 → 164,7
void (* page_table_lock)(as_t *as, bool lock);
void (* page_table_unlock)(as_t *as, bool unlock);
} as_operations_t;
#endif
 
/**
* This structure contains information associated with the shared address space
132,7 → 174,7
/** This lock must be acquired only when the as_area lock is held. */
mutex_t lock;
/** This structure can be deallocated if refcount drops to 0. */
size_t refcount;
count_t refcount;
/**
* B+tree containing complete map of anonymous pages of the shared area.
*/
156,7 → 198,7
};
struct { /**< phys_backend members */
uintptr_t base;
size_t frames;
count_t frames;
};
} mem_backend_data_t;
 
163,6 → 205,7
/** Address space area structure.
*
* Each as_area_t structure describes one contiguous area of virtual memory.
* In the future, it should not be difficult to support shared areas.
*/
typedef struct {
mutex_t lock;
175,7 → 218,7
/** Attributes related to the address space area itself. */
int attributes;
/** Size of this area in multiples of PAGE_SIZE. */
size_t pages;
count_t pages;
/** Base address of this area. */
uintptr_t base;
/** Map of used space. */
203,7 → 246,11
 
extern as_t *AS_KERNEL;
 
#ifndef __OBJC__
extern as_operations_t *as_operations;
#endif
 
SPINLOCK_EXTERN(inactive_as_with_asid_lock);
extern link_t inactive_as_with_asid_head;
 
extern void as_init(void);
220,13 → 267,12
extern int as_area_resize(as_t *as, uintptr_t address, size_t size, int flags);
int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
as_t *dst_as, uintptr_t dst_base, int dst_flags_mask);
extern int as_area_change_flags(as_t *as, int flags, uintptr_t address);
 
extern int as_area_get_flags(as_area_t *area);
extern bool as_area_check_access(as_area_t *area, pf_access_t access);
extern size_t as_area_get_size(uintptr_t base);
extern int used_space_insert(as_area_t *a, uintptr_t page, size_t count);
extern int used_space_remove(as_area_t *a, uintptr_t page, size_t count);
extern size_t as_get_size(uintptr_t base);
extern int used_space_insert(as_area_t *a, uintptr_t page, count_t count);
extern int used_space_remove(as_area_t *a, uintptr_t page, count_t count);
 
 
/* Interface to be implemented by architectures. */
251,19 → 297,11
extern mem_backend_t elf_backend;
extern mem_backend_t phys_backend;
 
/**
* This flags is passed when running the loader, otherwise elf_load()
* would return with a EE_LOADER error code.
*/
#define ELD_F_NONE 0
#define ELD_F_LOADER 1
extern int elf_load(elf_header_t *header, as_t *as);
 
extern unsigned int elf_load(elf_header_t *header, as_t *as, int flags);
 
/* Address space area related syscalls. */
extern unative_t sys_as_area_create(uintptr_t address, size_t size, int flags);
extern unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags);
extern unative_t sys_as_area_change_flags(uintptr_t address, int flags);
extern unative_t sys_as_area_destroy(uintptr_t address);
 
/* Introspection functions. */
/branches/arm/kernel/generic/include/mm/slab.h
41,40 → 41,39
#include <mm/frame.h>
 
/** Minimum size to be allocated by malloc */
#define SLAB_MIN_MALLOC_W 4
#define SLAB_MIN_MALLOC_W 4
 
/** Maximum size to be allocated by malloc */
#define SLAB_MAX_MALLOC_W 22
#define SLAB_MAX_MALLOC_W 18
 
/** Initial Magazine size (TODO: dynamically growing magazines) */
#define SLAB_MAG_SIZE 4
 
/** If object size is less, store control structure inside SLAB */
#define SLAB_INSIDE_SIZE (PAGE_SIZE >> 3)
#define SLAB_INSIDE_SIZE (PAGE_SIZE >> 3)
 
/** Maximum wasted space we allow for cache */
#define SLAB_MAX_BADNESS(cache) \
(((unsigned int) PAGE_SIZE << (cache)->order) >> 2)
#define SLAB_MAX_BADNESS(cache) ((PAGE_SIZE << (cache)->order) >> 2)
 
/* slab_reclaim constants */
 
/** Reclaim all possible memory, because we are in memory stress */
#define SLAB_RECLAIM_ALL 0x01
#define SLAB_RECLAIM_ALL 0x1
 
/* cache_create flags */
 
/** Do not use per-cpu cache */
#define SLAB_CACHE_NOMAGAZINE 0x01
#define SLAB_CACHE_NOMAGAZINE 0x1
/** Have control structure inside SLAB */
#define SLAB_CACHE_SLINSIDE 0x02
#define SLAB_CACHE_SLINSIDE 0x2
/** We add magazine cache later, if we have this flag */
#define SLAB_CACHE_MAGDEFERRED (0x04 | SLAB_CACHE_NOMAGAZINE)
#define SLAB_CACHE_MAGDEFERRED (0x4 | SLAB_CACHE_NOMAGAZINE)
 
typedef struct {
link_t link;
size_t busy; /**< Count of full slots in magazine */
size_t size; /**< Number of slots in magazine */
void *objs[]; /**< Slots in magazine */
count_t busy; /**< Count of full slots in magazine */
count_t size; /**< Number of slots in magazine */
void *objs[0]; /**< Slots in magazine */
} slab_magazine_t;
 
typedef struct {
86,23 → 85,23
 
typedef struct {
char *name;
 
link_t link;
 
/* Configuration */
/** Size of slab position - align_up(sizeof(obj)) */
size_t size;
 
int (*constructor)(void *obj, int kmflag);
int (*destructor)(void *obj);
 
/** Flags changing behaviour of cache */
int flags;
 
/* Computed values */
uint8_t order; /**< Order of frames to be allocated */
unsigned int objects; /**< Number of objects that fit in */
uint8_t order; /**< Order of frames to be allocated */
int objects; /**< Number of objects that fit in */
 
/* Statistics */
atomic_t allocated_slabs;
atomic_t allocated_objs;
109,26 → 108,27
atomic_t cached_objs;
/** How many magazines in magazines list */
atomic_t magazine_counter;
 
/* Slabs */
link_t full_slabs; /**< List of full slabs */
link_t partial_slabs; /**< List of partial slabs */
link_t full_slabs; /**< List of full slabs */
link_t partial_slabs; /**< List of partial slabs */
SPINLOCK_DECLARE(slablock);
/* Magazines */
link_t magazines; /**< List o full magazines */
/* Magazines */
link_t magazines; /**< List o full magazines */
SPINLOCK_DECLARE(maglock);
 
/** CPU cache */
slab_mag_cache_t *mag_cache;
} slab_cache_t;
 
extern slab_cache_t *slab_cache_create(char *, size_t, size_t,
int (*)(void *, int), int (*)(void *), int);
extern void slab_cache_destroy(slab_cache_t *);
extern slab_cache_t * slab_cache_create(char *name, size_t size, size_t align,
int (*constructor)(void *obj, int kmflag), int (*destructor)(void *obj),
int flags);
extern void slab_cache_destroy(slab_cache_t *cache);
 
extern void * slab_alloc(slab_cache_t *, int);
extern void slab_free(slab_cache_t *, void *);
extern size_t slab_reclaim(int);
extern void * slab_alloc(slab_cache_t *cache, int flags);
extern void slab_free(slab_cache_t *cache, void *obj);
extern count_t slab_reclaim(int flags);
 
/* slab subsytem initialization */
extern void slab_cache_init(void);
138,10 → 138,9
extern void slab_print_list(void);
 
/* malloc support */
extern void *malloc(unsigned int, int);
extern void *realloc(void *, unsigned int, int);
extern void free(void *);
 
extern void * malloc(unsigned int size, int flags);
extern void * realloc(void *ptr, unsigned int size, int flags);
extern void free(void *ptr);
#endif
 
/** @}
/branches/arm/kernel/generic/include/mm/frame.h
38,82 → 38,33
 
#include <arch/types.h>
#include <adt/list.h>
#include <synch/spinlock.h>
#include <mm/buddy.h>
#include <synch/spinlock.h>
#include <arch/mm/page.h>
#include <arch/mm/frame.h>
 
#define ONE_FRAME 0
#define TWO_FRAMES 1
#define FOUR_FRAMES 2
#define ONE_FRAME 0
#define TWO_FRAMES 1
 
 
#ifdef ARCH_STACK_FRAMES
#define STACK_FRAMES ARCH_STACK_FRAMES
#define STACK_FRAMES ARCH_STACK_FRAMES
#else
#define STACK_FRAMES ONE_FRAME
#define STACK_FRAMES ONE_FRAME
#endif
 
/** Maximum number of zones in the system. */
#define ZONES_MAX 32
/** Maximum number of zones in system. */
#define ZONES_MAX 16
 
typedef uint8_t frame_flags_t;
/** If possible, merge with neighbouring zones. */
#define ZONE_JOIN 0x1
 
/** Convert the frame address to kernel VA. */
#define FRAME_KA 0x01
/** Convert the frame address to kernel va. */
#define FRAME_KA 0x1
/** Do not panic and do not sleep on failure. */
#define FRAME_ATOMIC 0x02
#define FRAME_ATOMIC 0x2
/** Do not start reclaiming when no free memory. */
#define FRAME_NO_RECLAIM 0x04
#define FRAME_NO_RECLAIM 0x4
 
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
/** Zone is used by firmware (not available for allocation) */
#define ZONE_FIRMWARE 0x10
 
/** Currently there is no equivalent zone flags
for frame flags */
#define FRAME_TO_ZONE_FLAGS(frame_flags) 0
 
typedef struct {
size_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 */
size_t count; /**< Size of zone */
size_t free_count; /**< Number of free frame_t
structures */
size_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);
size_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);
124,57 → 75,45
return (pfn_t) (addr >> FRAME_WIDTH);
}
 
static inline size_t SIZE2FRAMES(size_t size)
static inline count_t SIZE2FRAMES(size_t size)
{
if (!size)
return 0;
return (size_t) ((size - 1) >> FRAME_WIDTH) + 1;
return (count_t) ((size - 1) >> FRAME_WIDTH) + 1;
}
 
static inline size_t FRAMES2SIZE(size_t frames)
{
return (size_t) (frames << FRAME_WIDTH);
}
#define IS_BUDDY_ORDER_OK(index, order) \
((~(((unative_t) -1) << (order)) & (index)) == 0)
#define IS_BUDDY_LEFT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
#define IS_BUDDY_RIGHT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
 
static inline bool zone_flags_available(zone_flags_t flags)
{
return ((flags & (ZONE_RESERVED | ZONE_FIRMWARE)) == 0);
}
#define frame_alloc(order, flags) \
frame_alloc_generic(order, flags, NULL)
 
#define IS_BUDDY_ORDER_OK(index, order) \
((~(((unative_t) -1) << (order)) & (index)) == 0)
#define IS_BUDDY_LEFT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 0)
#define IS_BUDDY_RIGHT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 1)
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 0)
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 1)
 
#define frame_alloc(order, flags) \
frame_alloc_generic(order, flags, NULL)
 
extern void frame_init(void);
extern void *frame_alloc_generic(uint8_t, frame_flags_t, size_t *);
extern void frame_free(uintptr_t);
extern void frame_reference_add(pfn_t);
extern void *frame_alloc_generic(uint8_t order, int flags, unsigned int *pzone);
extern void frame_free(uintptr_t frame);
extern void frame_reference_add(pfn_t pfn);
 
extern size_t find_zone(pfn_t frame, size_t count, size_t hint);
extern size_t zone_create(pfn_t, size_t, pfn_t, zone_flags_t);
extern void *frame_get_parent(pfn_t, size_t);
extern void frame_set_parent(pfn_t, void *, size_t);
extern void frame_mark_unavailable(pfn_t, size_t);
extern uintptr_t zone_conf_size(size_t);
extern bool zone_merge(size_t, size_t);
extern void zone_merge_all(void);
extern uint64_t zone_total_size(void);
extern int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags);
void *frame_get_parent(pfn_t frame, unsigned int hint);
void frame_set_parent(pfn_t frame, void *data, unsigned int hint);
void frame_mark_unavailable(pfn_t start, count_t count);
uintptr_t zone_conf_size(count_t count);
void zone_merge(unsigned int z1, unsigned int z2);
void zone_merge_all(void);
 
/*
* Console functions
*/
extern void zone_print_list(void);
extern void zone_print_one(size_t);
void zone_print_one(unsigned int znum);
 
#endif
 
/branches/arm/kernel/generic/include/mm/page.h
39,10 → 39,15
#include <mm/as.h>
#include <memstr.h>
 
/**
* Macro for computing page color.
*/
#define PAGE_COLOR(va) (((va) >> PAGE_WIDTH) & ((1 << PAGE_COLOR_BITS) - 1))
 
/** Operations to manipulate page mappings. */
typedef struct {
void (* mapping_insert)(as_t *as, uintptr_t page, uintptr_t frame,
int flags);
int flags);
void (* mapping_remove)(as_t *as, uintptr_t page);
pte_t *(* mapping_find)(as_t *as, uintptr_t page);
} page_mapping_operations_t;
59,7 → 64,6
extern pte_t *page_table_create(int flags);
extern void page_table_destroy(pte_t *page_table);
extern void map_structure(uintptr_t s, size_t size);
 
extern uintptr_t hw_map(uintptr_t physaddr, size_t size);
 
#endif
/branches/arm/kernel/generic/include/mm/tlb.h
61,7 → 61,7
tlb_invalidate_type_t type; /**< Message type. */
asid_t asid; /**< Address space identifier. */
uintptr_t page; /**< Page address. */
size_t count; /**< Number of pages to invalidate. */
count_t count; /**< Number of pages to invalidate. */
} tlb_shootdown_msg_t;
 
extern void tlb_init(void);
68,7 → 68,7
 
#ifdef CONFIG_SMP
extern void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
uintptr_t page, size_t count);
uintptr_t page, count_t count);
extern void tlb_shootdown_finalize(void);
extern void tlb_shootdown_ipi_recv(void);
#else
84,7 → 84,7
 
extern void tlb_invalidate_all(void);
extern void tlb_invalidate_asid(asid_t asid);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt);
#endif
 
/** @}
/branches/arm/kernel/generic/include/mm/buddy.h
66,6 → 66,7
void (*mark_available)(struct buddy_system *, link_t *);
/** Find parent of block that has given order */
link_t *(* find_block)(struct buddy_system *, link_t *, uint8_t);
void (* print_id)(struct buddy_system *, link_t *);
} buddy_system_operations_t;
 
typedef struct buddy_system {
77,13 → 78,14
void *data;
} buddy_system_t;
 
extern void buddy_system_create(buddy_system_t *, uint8_t,
buddy_system_operations_t *, void *);
extern link_t *buddy_system_alloc(buddy_system_t *, uint8_t);
extern bool buddy_system_can_alloc(buddy_system_t *, uint8_t);
extern void buddy_system_free(buddy_system_t *, link_t *);
extern size_t buddy_conf_size(size_t);
extern link_t *buddy_system_alloc_block(buddy_system_t *, link_t *);
extern void buddy_system_create(buddy_system_t *b, uint8_t max_order,
buddy_system_operations_t *op, void *data);
extern link_t *buddy_system_alloc(buddy_system_t *b, uint8_t i);
extern bool buddy_system_can_alloc(buddy_system_t *b, uint8_t order);
extern void buddy_system_free(buddy_system_t *b, link_t *block);
extern void buddy_system_structure_print(buddy_system_t *b, size_t elem_size);
extern size_t buddy_conf_size(int max_order);
extern link_t *buddy_system_alloc_block(buddy_system_t *b, link_t *block);
 
#endif