forked from KolibriOS/kolibrios
1) slab allocator
2) new kernel heap git-svn-id: svn://kolibrios.org@859 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
67aca9ac45
commit
2b91637d4d
@ -69,7 +69,7 @@ __start:
|
|||||||
|
|
||||||
; ENABLE PAGING
|
; ENABLE PAGING
|
||||||
|
|
||||||
mov ecx, 32
|
mov ecx, 64
|
||||||
mov edi, _sys_pdbr+(OS_BASE shr 20)+(0x100000000-OS_BASE)
|
mov edi, _sys_pdbr+(OS_BASE shr 20)+(0x100000000-OS_BASE)
|
||||||
mov eax, PG_LARGE+PG_SW
|
mov eax, PG_LARGE+PG_SW
|
||||||
@@:
|
@@:
|
||||||
|
@ -544,8 +544,6 @@ struc MEM_STATE
|
|||||||
struc PG_DATA
|
struc PG_DATA
|
||||||
{ .mem_amount dd ?
|
{ .mem_amount dd ?
|
||||||
.vesa_mem dd ?
|
.vesa_mem dd ?
|
||||||
.pages_count dd ?
|
|
||||||
.pages_free dd ?
|
|
||||||
.pages_faults dd ?
|
.pages_faults dd ?
|
||||||
.pagemap_size dd ?
|
.pagemap_size dd ?
|
||||||
.kernel_pages dd ?
|
.kernel_pages dd ?
|
||||||
|
295
kernel/branches/kolibri_pe/core/heap.c
Normal file
295
kernel/branches/kolibri_pe/core/heap.c
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <core.h>
|
||||||
|
#include <spinlock.h>
|
||||||
|
#include <link.h>
|
||||||
|
#include <mm.h>
|
||||||
|
#include <slab.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
link_t link;
|
||||||
|
link_t adj;
|
||||||
|
addr_t base;
|
||||||
|
size_t size;
|
||||||
|
void* parent;
|
||||||
|
u32_t reserved;
|
||||||
|
}md_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
|
||||||
|
|
||||||
|
u32_t availmask;
|
||||||
|
link_t list[32];
|
||||||
|
}heap_t;
|
||||||
|
|
||||||
|
slab_cache_t *md_slab;
|
||||||
|
slab_cache_t *phm_slab;
|
||||||
|
|
||||||
|
heap_t lheap;
|
||||||
|
heap_t sheap;
|
||||||
|
|
||||||
|
static inline void _set_lmask(count_t idx)
|
||||||
|
{ asm volatile ("bts DWORD PTR [_lheap], %0"::"r"(idx):"cc"); }
|
||||||
|
|
||||||
|
static inline void _reset_lmask(count_t idx)
|
||||||
|
{ asm volatile ("btr DWORD PTR [_lheap], %0"::"r"(idx):"cc"); }
|
||||||
|
|
||||||
|
static inline void _set_smask(count_t idx)
|
||||||
|
{ asm volatile ("bts DWORD PTR [_sheap], %0"::"r"(idx):"cc"); }
|
||||||
|
|
||||||
|
static inline void _reset_smask(count_t idx)
|
||||||
|
{ asm volatile ("btr DWORD PTR [_sheap], %0"::"r"(idx):"cc"); }
|
||||||
|
|
||||||
|
|
||||||
|
int __fastcall init_heap(addr_t base, size_t size)
|
||||||
|
{
|
||||||
|
md_t *md;
|
||||||
|
u32_t i;
|
||||||
|
|
||||||
|
ASSERT(base != 0);
|
||||||
|
ASSERT(size != 0)
|
||||||
|
ASSERT(base & 0x3FFFFF == 0);
|
||||||
|
ASSERT(size & 0x3FFFFF == 0);
|
||||||
|
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
list_initialize(&lheap.list[i]);
|
||||||
|
list_initialize(&sheap.list[i]);
|
||||||
|
};
|
||||||
|
|
||||||
|
md_slab = slab_cache_create(sizeof(md_t), 32,NULL,NULL,SLAB_CACHE_MAGDEFERRED);
|
||||||
|
|
||||||
|
md = (md_t*)slab_alloc(md_slab,0);
|
||||||
|
|
||||||
|
list_initialize(&md->adj);
|
||||||
|
md->base = base;
|
||||||
|
md->size = size;
|
||||||
|
md->parent = NULL;
|
||||||
|
md->reserved = 0;
|
||||||
|
|
||||||
|
list_prepend(&md->link, &lheap.list[31]);
|
||||||
|
lheap.availmask = 0x80000000;
|
||||||
|
sheap.availmask = 0x00000000;
|
||||||
|
|
||||||
|
// phm_slab = slab_cache_create(sizeof(phismem_t), 32,NULL,NULL,SLAB_CACHE_MAGDEFERRED);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
md_t* __fastcall find_large_md(size_t size)
|
||||||
|
{
|
||||||
|
md_t *md = NULL;
|
||||||
|
|
||||||
|
count_t idx0;
|
||||||
|
u32_t mask;
|
||||||
|
|
||||||
|
ASSERT(size & 0x3FFFFF == 0);
|
||||||
|
|
||||||
|
idx0 = (size>>22) - 1 < 32 ? (size>>22) - 1 : 31;
|
||||||
|
mask = lheap.availmask & ( -1<<idx0 );
|
||||||
|
|
||||||
|
if(mask)
|
||||||
|
{
|
||||||
|
idx0 = _bsf(mask);
|
||||||
|
|
||||||
|
ASSERT( !list_empty(&lheap.list[idx0]))
|
||||||
|
|
||||||
|
md = (md_t*)lheap.list[idx0].next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
list_remove((link_t*)md);
|
||||||
|
if(list_empty(&lheap.list[idx0]))
|
||||||
|
_reset_lmask(idx0);
|
||||||
|
|
||||||
|
if(md->size > size)
|
||||||
|
{
|
||||||
|
count_t idx1;
|
||||||
|
md_t *new_md = (md_t*)slab_alloc(md_slab,0);
|
||||||
|
|
||||||
|
link_initialize(&new_md->link);
|
||||||
|
list_insert(&md->adj, &new_md->adj);
|
||||||
|
|
||||||
|
new_md->base = md->base;
|
||||||
|
new_md->size = size;
|
||||||
|
|
||||||
|
md->base+= size;
|
||||||
|
md->size-= size;
|
||||||
|
|
||||||
|
idx1 = (md->size>>22) - 1 < 32 ? (md->size>>22) - 1 : 31;
|
||||||
|
|
||||||
|
list_prepend(&md->link, &lheap.list[idx1]);
|
||||||
|
_set_lmask(idx1);
|
||||||
|
|
||||||
|
return new_md;
|
||||||
|
}
|
||||||
|
return md;
|
||||||
|
}
|
||||||
|
|
||||||
|
md_t* __fastcall find_small_md(size_t size)
|
||||||
|
{
|
||||||
|
eflags_t efl;
|
||||||
|
|
||||||
|
md_t *md = NULL;
|
||||||
|
|
||||||
|
count_t idx0;
|
||||||
|
u32_t mask;
|
||||||
|
|
||||||
|
ASSERT(size & 0xFFF == 0);
|
||||||
|
|
||||||
|
efl = safe_cli();
|
||||||
|
|
||||||
|
idx0 = (size>>12) - 1 < 32 ? (size>>12) - 1 : 31;
|
||||||
|
mask = sheap.availmask & ( -1<<idx0 );
|
||||||
|
|
||||||
|
if(mask)
|
||||||
|
{
|
||||||
|
idx0 = _bsf(mask);
|
||||||
|
|
||||||
|
ASSERT( !list_empty(&sheap.list[idx0]))
|
||||||
|
|
||||||
|
md = (md_t*)sheap.list[idx0].next;
|
||||||
|
|
||||||
|
list_remove((link_t*)md);
|
||||||
|
if(list_empty(&sheap.list[idx0]))
|
||||||
|
_reset_smask(idx0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
md_t *lmd;
|
||||||
|
lmd = find_large_md((size+0x3FFFFF)&~0x3FFFFF);
|
||||||
|
if( !lmd)
|
||||||
|
{
|
||||||
|
safe_sti(efl);
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
md = (md_t*)slab_alloc(md_slab,0);
|
||||||
|
link_initialize(&md->link);
|
||||||
|
list_initialize(&md->adj);
|
||||||
|
md->base = lmd->base;
|
||||||
|
md->size = lmd->size;
|
||||||
|
md->parent = lmd;
|
||||||
|
md->reserved = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
if(md->size > size)
|
||||||
|
{
|
||||||
|
count_t idx1;
|
||||||
|
md_t *new_md = (md_t*)slab_alloc(md_slab,0);
|
||||||
|
|
||||||
|
link_initialize(&new_md->link);
|
||||||
|
list_insert(&md->adj, &new_md->adj);
|
||||||
|
|
||||||
|
new_md->base = md->base;
|
||||||
|
new_md->size = size;
|
||||||
|
new_md->parent = md->parent;
|
||||||
|
new_md->reserved = 0;
|
||||||
|
|
||||||
|
md->base+= size;
|
||||||
|
md->size-= size;
|
||||||
|
|
||||||
|
idx1 = (md->size>>22) - 1 < 32 ? (md->size>>22) - 1 : 31;
|
||||||
|
|
||||||
|
list_prepend(&md->link, &sheap.list[idx1]);
|
||||||
|
_set_smask(idx1);
|
||||||
|
|
||||||
|
safe_sti(efl);
|
||||||
|
|
||||||
|
return new_md;
|
||||||
|
}
|
||||||
|
safe_sti(efl);
|
||||||
|
return md;
|
||||||
|
}
|
||||||
|
|
||||||
|
phismem_t* __fastcall phis_alloc(count_t count)
|
||||||
|
{
|
||||||
|
phismem_t *phm;
|
||||||
|
count_t tmp;
|
||||||
|
phm = (phismem_t*)slab_alloc(phm_slab, 0);
|
||||||
|
|
||||||
|
phm->count = count;
|
||||||
|
tmp = count;
|
||||||
|
while(tmp)
|
||||||
|
{
|
||||||
|
u32_t order;
|
||||||
|
|
||||||
|
asm volatile ("bsr %0, %1":"=&r"(order):"r"(tmp):"cc");
|
||||||
|
asm volatile ("btr %0, %1" :"=r"(tmp):"r"(order):"cc");
|
||||||
|
|
||||||
|
phm->frames[order] = core_alloc(order);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return phm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define page_tabs 0xDF800000
|
||||||
|
|
||||||
|
void map_phm(addr_t base, phismem_t *phm, u32_t mapflags)
|
||||||
|
{
|
||||||
|
count_t count;
|
||||||
|
addr_t *pte;
|
||||||
|
|
||||||
|
count = phm->count;
|
||||||
|
pte = &((addr_t*)page_tabs)[base>>12];
|
||||||
|
|
||||||
|
while(count)
|
||||||
|
{
|
||||||
|
u32_t order;
|
||||||
|
addr_t frame;
|
||||||
|
count_t size;
|
||||||
|
|
||||||
|
asm volatile ("bsr %0, %1":"=&r"(order):"r"(count):"cc");
|
||||||
|
asm volatile ("btr %0, %1" :"=r"(count):"r"(order):"cc");
|
||||||
|
|
||||||
|
frame = phm->frames[order] | mapflags;
|
||||||
|
size = (1 << order);
|
||||||
|
while(size--)
|
||||||
|
{
|
||||||
|
*pte++ = frame;
|
||||||
|
frame+= 4096;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void* __fastcall mem_alloc(size_t size, u32_t flags)
|
||||||
|
{
|
||||||
|
md_t *md;
|
||||||
|
phismem_t *phm;
|
||||||
|
|
||||||
|
size = (size+4095)&~4095;
|
||||||
|
|
||||||
|
md = find_small_md(size);
|
||||||
|
if( md )
|
||||||
|
{
|
||||||
|
phm = phis_alloc(size>>12);
|
||||||
|
map_phm(md->base, phm, flags);
|
||||||
|
return (void*)md->base;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
void* __stdcall alloc_kernel_space(size_t size); //__asm__("alloc_kernel_space");
|
||||||
|
|
||||||
|
|
||||||
|
void* __stdcall alloc_kernel_space(size_t size)
|
||||||
|
{
|
||||||
|
md_t *md;
|
||||||
|
|
||||||
|
size = (size+4095)&~4095;
|
||||||
|
|
||||||
|
md = find_small_md(size);
|
||||||
|
if( md )
|
||||||
|
return (void*)md->base;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//void* __stdcall kernel_alloc(size_t size)
|
||||||
|
//{
|
||||||
|
//
|
||||||
|
// return NULL;
|
||||||
|
//}
|
||||||
|
//*/
|
@ -38,506 +38,10 @@ block_base equ MEM_BLOCK.base
|
|||||||
block_size equ MEM_BLOCK.size
|
block_size equ MEM_BLOCK.size
|
||||||
block_flags equ MEM_BLOCK.flags
|
block_flags equ MEM_BLOCK.flags
|
||||||
|
|
||||||
macro calc_index op
|
|
||||||
{ shr op, 12
|
|
||||||
dec op
|
|
||||||
cmp op, 63
|
|
||||||
jna @f
|
|
||||||
mov op, 63
|
|
||||||
@@:
|
|
||||||
}
|
|
||||||
|
|
||||||
macro remove_from_list op
|
|
||||||
{ mov edx, [op+list_fd]
|
|
||||||
mov ecx, [op+list_bk]
|
|
||||||
test edx, edx
|
|
||||||
jz @f
|
|
||||||
mov [edx+list_bk], ecx
|
|
||||||
@@:
|
|
||||||
test ecx, ecx
|
|
||||||
jz @f
|
|
||||||
mov [ecx+list_fd], edx
|
|
||||||
@@:
|
|
||||||
mov [op+list_fd],0
|
|
||||||
mov [op+list_bk],0
|
|
||||||
}
|
|
||||||
|
|
||||||
macro remove_from_free op
|
|
||||||
{
|
|
||||||
remove_from_list op
|
|
||||||
|
|
||||||
mov eax, [op+block_size]
|
|
||||||
calc_index eax
|
|
||||||
cmp [mem_block_list+eax*4], op
|
|
||||||
jne @f
|
|
||||||
mov [mem_block_list+eax*4], edx
|
|
||||||
@@:
|
|
||||||
cmp [mem_block_list+eax*4], 0
|
|
||||||
jne @f
|
|
||||||
btr [mem_block_mask], eax
|
|
||||||
@@:
|
|
||||||
}
|
|
||||||
|
|
||||||
macro remove_from_used op
|
|
||||||
{
|
|
||||||
mov edx, [op+list_fd]
|
|
||||||
mov ecx, [op+list_bk]
|
|
||||||
mov [edx+list_bk], ecx
|
|
||||||
mov [ecx+list_fd], edx
|
|
||||||
mov [op+list_fd], 0
|
|
||||||
mov [op+list_bk], 0
|
|
||||||
}
|
|
||||||
|
|
||||||
align 4
|
|
||||||
init_kernel_heap:
|
|
||||||
|
|
||||||
mov ecx, 64/4
|
|
||||||
mov edi, mem_block_list
|
|
||||||
xor eax, eax
|
|
||||||
cld
|
|
||||||
rep stosd
|
|
||||||
|
|
||||||
mov ecx, 512/4
|
|
||||||
mov edi, mem_block_map
|
|
||||||
not eax
|
|
||||||
rep stosd
|
|
||||||
|
|
||||||
mov ecx, 128*1024
|
|
||||||
fastcall _balloc
|
|
||||||
|
|
||||||
mov [mem_block_start], mem_block_map
|
|
||||||
mov [mem_block_end], mem_block_map+512
|
|
||||||
mov [mem_block_arr], eax
|
|
||||||
|
|
||||||
mov ebx, mem_used.fd-MEM_LIST_OFFSET
|
|
||||||
mov [mem_used.fd], ebx
|
|
||||||
mov [mem_used.bk], ebx
|
|
||||||
|
|
||||||
xor edx, edx
|
|
||||||
|
|
||||||
mov [eax+block_next], edx
|
|
||||||
mov [eax+block_prev], edx
|
|
||||||
mov [eax+list_fd], edx
|
|
||||||
mov [eax+list_bk], edx
|
|
||||||
mov [eax+block_base], HEAP_BASE
|
|
||||||
mov [eax+block_size], page_tabs-HEAP_BASE
|
|
||||||
mov [eax+block_flags], FREE_BLOCK
|
|
||||||
|
|
||||||
mov [heap_size], page_tabs-HEAP_BASE
|
|
||||||
mov [heap_free], page_tabs-HEAP_BASE
|
|
||||||
|
|
||||||
mov [mem_block_mask], edx
|
|
||||||
mov [mem_block_mask+4],0x80000000
|
|
||||||
|
|
||||||
mov [mem_block_list+63*4], eax
|
|
||||||
mov byte [mem_block_map], 0xFE
|
|
||||||
and [heap_mutex], 0
|
|
||||||
mov [heap_blocks], 4096
|
|
||||||
mov [free_blocks], 4096
|
|
||||||
ret
|
|
||||||
|
|
||||||
; param
|
|
||||||
; eax= required size
|
|
||||||
;
|
|
||||||
; retval
|
|
||||||
; edi= memory block descriptor
|
|
||||||
; ebx= descriptor index
|
|
||||||
|
|
||||||
align 4
|
|
||||||
get_small_block:
|
|
||||||
mov ecx, eax
|
|
||||||
shr ecx, 12
|
|
||||||
dec ecx
|
|
||||||
cmp ecx, 63
|
|
||||||
jle .get_index
|
|
||||||
mov ecx, 63
|
|
||||||
.get_index:
|
|
||||||
lea esi, [mem_block_mask]
|
|
||||||
xor ebx, ebx
|
|
||||||
or edx, -1
|
|
||||||
|
|
||||||
cmp ecx, 32
|
|
||||||
jb .bit_test
|
|
||||||
|
|
||||||
sub ecx, 32
|
|
||||||
add ebx, 32
|
|
||||||
add esi, 4
|
|
||||||
.bit_test:
|
|
||||||
shl edx, cl
|
|
||||||
and edx, [esi]
|
|
||||||
.find:
|
|
||||||
bsf edi, edx
|
|
||||||
jz .high_mask
|
|
||||||
add ebx, edi
|
|
||||||
mov edi, [mem_block_list+ebx*4]
|
|
||||||
.check_size:
|
|
||||||
cmp eax, [edi+block_size]
|
|
||||||
ja .next
|
|
||||||
ret
|
|
||||||
|
|
||||||
.high_mask:
|
|
||||||
add esi, 4
|
|
||||||
cmp esi, mem_block_mask+8
|
|
||||||
jae .err
|
|
||||||
add ebx, 32
|
|
||||||
mov edx, [esi]
|
|
||||||
jmp .find
|
|
||||||
.next:
|
|
||||||
mov edi, [edi+list_fd]
|
|
||||||
test edi, edi
|
|
||||||
jnz .check_size
|
|
||||||
.err:
|
|
||||||
xor edi, edi
|
|
||||||
ret
|
|
||||||
; param
|
|
||||||
; eax= required size
|
|
||||||
;
|
|
||||||
; retval
|
|
||||||
; edi= memory block descriptor
|
|
||||||
; ebx= descriptor index
|
|
||||||
align 4
|
|
||||||
get_large_block:
|
|
||||||
mov edx, -1
|
|
||||||
mov ecx, eax
|
|
||||||
shr ecx, 22
|
|
||||||
dec ecx
|
|
||||||
cmp ecx, 31
|
|
||||||
jle .get_index
|
|
||||||
mov ecx, 31
|
|
||||||
.get_index:
|
|
||||||
shl edx, cl
|
|
||||||
and edx, [large_block_mask]
|
|
||||||
.find:
|
|
||||||
bsf edi, edx
|
|
||||||
mov ebx, edi
|
|
||||||
mov edi, [large_block_list+edi*4]
|
|
||||||
.check_size:
|
|
||||||
cmp eax, [edi+block_size]
|
|
||||||
ja .next
|
|
||||||
ret
|
|
||||||
.next:
|
|
||||||
mov edi, [edi+list_fd]
|
|
||||||
test edi, edi
|
|
||||||
jnz .check_size
|
|
||||||
.fail:
|
|
||||||
xor edi, edi
|
|
||||||
ret
|
|
||||||
|
|
||||||
align 4
|
|
||||||
alloc_mem_block:
|
|
||||||
|
|
||||||
mov ebx, [mem_block_start]
|
|
||||||
mov ecx, [mem_block_end]
|
|
||||||
.l1:
|
|
||||||
bsf eax,[ebx];
|
|
||||||
jnz found
|
|
||||||
add ebx,4
|
|
||||||
cmp ebx, ecx
|
|
||||||
jb .l1
|
|
||||||
xor eax,eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
found:
|
|
||||||
btr [ebx], eax
|
|
||||||
mov [mem_block_start],ebx
|
|
||||||
sub ebx, mem_block_map
|
|
||||||
lea eax,[eax+ebx*8]
|
|
||||||
shl eax, 5
|
|
||||||
add eax, [mem_block_arr]
|
|
||||||
dec [free_blocks]
|
|
||||||
ret
|
|
||||||
align 4
|
|
||||||
free_mem_block:
|
|
||||||
mov dword [eax], 0
|
|
||||||
mov dword [eax+4], 0
|
|
||||||
mov dword [eax+8], 0
|
|
||||||
mov dword [eax+12], 0
|
|
||||||
mov dword [eax+16], 0
|
|
||||||
; mov dword [eax+20], 0
|
|
||||||
mov dword [eax+24], 0
|
|
||||||
mov dword [eax+28], 0
|
|
||||||
|
|
||||||
sub eax, [mem_block_arr]
|
|
||||||
shr eax, 5
|
|
||||||
|
|
||||||
mov ebx, mem_block_map
|
|
||||||
bts [ebx], eax
|
|
||||||
inc [free_blocks]
|
|
||||||
shr eax, 3
|
|
||||||
and eax, not 3
|
|
||||||
add eax, ebx
|
|
||||||
cmp [mem_block_start], eax
|
|
||||||
ja @f
|
|
||||||
ret
|
|
||||||
@@:
|
|
||||||
mov [mem_block_start], eax
|
|
||||||
ret
|
|
||||||
.err:
|
|
||||||
xor eax, eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
align 4
|
|
||||||
proc alloc_kernel_space stdcall, size:dword
|
|
||||||
local block_ind:DWORD
|
|
||||||
|
|
||||||
push ebx
|
|
||||||
push esi
|
|
||||||
push edi
|
|
||||||
|
|
||||||
mov eax, [size]
|
|
||||||
add eax, 4095
|
|
||||||
and eax, not 4095
|
|
||||||
mov [size], eax
|
|
||||||
|
|
||||||
mov ebx, heap_mutex
|
|
||||||
call wait_mutex ;ebx
|
|
||||||
|
|
||||||
cmp eax, [heap_free]
|
|
||||||
ja .error
|
|
||||||
|
|
||||||
call get_small_block ; eax
|
|
||||||
test edi, edi
|
|
||||||
jz .error
|
|
||||||
|
|
||||||
cmp [edi+block_flags], FREE_BLOCK
|
|
||||||
jne .error
|
|
||||||
|
|
||||||
mov [block_ind], ebx ;index of allocated block
|
|
||||||
|
|
||||||
mov eax, [edi+block_size]
|
|
||||||
cmp eax, [size]
|
|
||||||
je .m_eq_size
|
|
||||||
|
|
||||||
call alloc_mem_block
|
|
||||||
test eax, eax
|
|
||||||
jz .error
|
|
||||||
|
|
||||||
mov esi, eax ;esi - splitted block
|
|
||||||
|
|
||||||
mov [esi+block_next], edi
|
|
||||||
mov eax, [edi+block_prev]
|
|
||||||
mov [esi+block_prev], eax
|
|
||||||
mov [edi+block_prev], esi
|
|
||||||
mov [esi+list_fd], 0
|
|
||||||
mov [esi+list_bk], 0
|
|
||||||
test eax, eax
|
|
||||||
jz @f
|
|
||||||
mov [eax+block_next], esi
|
|
||||||
@@:
|
|
||||||
mov ebx, [edi+block_base]
|
|
||||||
mov [esi+block_base], ebx
|
|
||||||
mov edx, [size]
|
|
||||||
mov [esi+block_size], edx
|
|
||||||
add [edi+block_base], edx
|
|
||||||
sub [edi+block_size], edx
|
|
||||||
|
|
||||||
mov eax, [edi+block_size]
|
|
||||||
shr eax, 12
|
|
||||||
sub eax, 1
|
|
||||||
cmp eax, 63
|
|
||||||
jna @f
|
|
||||||
mov eax, 63
|
|
||||||
@@:
|
|
||||||
cmp eax, [block_ind]
|
|
||||||
je .m_eq_ind
|
|
||||||
|
|
||||||
remove_from_list edi
|
|
||||||
|
|
||||||
mov ecx, [block_ind]
|
|
||||||
mov [mem_block_list+ecx*4], edx
|
|
||||||
|
|
||||||
test edx, edx
|
|
||||||
jnz @f
|
|
||||||
btr [mem_block_mask], ecx
|
|
||||||
@@:
|
|
||||||
mov edx, [mem_block_list+eax*4]
|
|
||||||
mov [edi+list_fd], edx
|
|
||||||
test edx, edx
|
|
||||||
jz @f
|
|
||||||
mov [edx+list_bk], edi
|
|
||||||
@@:
|
|
||||||
mov [mem_block_list+eax*4], edi
|
|
||||||
bts [mem_block_mask], eax
|
|
||||||
.m_eq_ind:
|
|
||||||
mov ecx, mem_used.fd-MEM_LIST_OFFSET
|
|
||||||
mov edx, [ecx+list_fd]
|
|
||||||
mov [esi+list_fd], edx
|
|
||||||
mov [esi+list_bk], ecx
|
|
||||||
mov [ecx+list_fd], esi
|
|
||||||
mov [edx+list_bk], esi
|
|
||||||
|
|
||||||
mov [esi+block_flags], USED_BLOCK
|
|
||||||
mov eax, [esi+block_base]
|
|
||||||
mov ebx, [size]
|
|
||||||
sub [heap_free], ebx
|
|
||||||
and [heap_mutex], 0
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebx
|
|
||||||
ret
|
|
||||||
.m_eq_size:
|
|
||||||
remove_from_list edi
|
|
||||||
mov [mem_block_list+ebx*4], edx
|
|
||||||
and edx, edx
|
|
||||||
jnz @f
|
|
||||||
btr [mem_block_mask], ebx
|
|
||||||
@@:
|
|
||||||
mov ecx, mem_used.fd-MEM_LIST_OFFSET
|
|
||||||
mov edx, [ecx+list_fd]
|
|
||||||
mov [edi+list_fd], edx
|
|
||||||
mov [edi+list_bk], ecx
|
|
||||||
mov [ecx+list_fd], edi
|
|
||||||
mov [edx+list_bk], edi
|
|
||||||
|
|
||||||
mov [edi+block_flags], USED_BLOCK
|
|
||||||
mov eax, [edi+block_base]
|
|
||||||
mov ebx, [size]
|
|
||||||
sub [heap_free], ebx
|
|
||||||
and [heap_mutex], 0
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebx
|
|
||||||
ret
|
|
||||||
.error:
|
|
||||||
xor eax, eax
|
|
||||||
mov [heap_mutex], eax
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebx
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
|
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
|
||||||
push ebx
|
|
||||||
push esi
|
|
||||||
push edi
|
|
||||||
mov ebx, heap_mutex
|
|
||||||
call wait_mutex ;ebx
|
|
||||||
|
|
||||||
mov eax, [base]
|
|
||||||
mov esi, [mem_used.fd]
|
|
||||||
@@:
|
|
||||||
cmp esi, mem_used.fd-MEM_LIST_OFFSET
|
|
||||||
je .fail
|
|
||||||
|
|
||||||
cmp [esi+block_base], eax
|
|
||||||
je .found
|
|
||||||
mov esi, [esi+list_fd]
|
|
||||||
jmp @b
|
|
||||||
.found:
|
|
||||||
cmp [esi+block_flags], USED_BLOCK
|
|
||||||
jne .fail
|
|
||||||
|
|
||||||
mov eax, [esi+block_size]
|
|
||||||
add [heap_free], eax
|
|
||||||
|
|
||||||
mov edi, [esi+block_next]
|
|
||||||
test edi, edi
|
|
||||||
jz .prev
|
|
||||||
|
|
||||||
cmp [edi+block_flags], FREE_BLOCK
|
|
||||||
jne .prev
|
|
||||||
|
|
||||||
remove_from_free edi
|
|
||||||
|
|
||||||
mov edx, [edi+block_next]
|
|
||||||
mov [esi+block_next], edx
|
|
||||||
test edx, edx
|
|
||||||
jz @f
|
|
||||||
|
|
||||||
mov [edx+block_prev], esi
|
|
||||||
@@:
|
|
||||||
mov ecx, [edi+block_size]
|
|
||||||
add [esi+block_size], ecx
|
|
||||||
|
|
||||||
mov eax, edi
|
|
||||||
call free_mem_block
|
|
||||||
.prev:
|
|
||||||
mov edi, [esi+block_prev]
|
|
||||||
test edi, edi
|
|
||||||
jz .insert
|
|
||||||
|
|
||||||
cmp [edi+block_flags], FREE_BLOCK
|
|
||||||
jne .insert
|
|
||||||
|
|
||||||
remove_from_used esi
|
|
||||||
|
|
||||||
mov edx, [esi+block_next]
|
|
||||||
mov [edi+block_next], edx
|
|
||||||
test edx, edx
|
|
||||||
jz @f
|
|
||||||
mov [edx+block_prev], edi
|
|
||||||
@@:
|
|
||||||
mov eax, esi
|
|
||||||
call free_mem_block
|
|
||||||
|
|
||||||
mov ecx, [edi+block_size]
|
|
||||||
mov eax, [esi+block_size]
|
|
||||||
add eax, ecx
|
|
||||||
mov [edi+block_size], eax
|
|
||||||
|
|
||||||
calc_index eax
|
|
||||||
calc_index ecx
|
|
||||||
cmp eax, ecx
|
|
||||||
je .m_eq
|
|
||||||
|
|
||||||
push ecx
|
|
||||||
remove_from_list edi
|
|
||||||
pop ecx
|
|
||||||
|
|
||||||
cmp [mem_block_list+ecx*4], edi
|
|
||||||
jne @f
|
|
||||||
mov [mem_block_list+ecx*4], edx
|
|
||||||
@@:
|
|
||||||
cmp [mem_block_list+ecx*4], 0
|
|
||||||
jne @f
|
|
||||||
btr [mem_block_mask], ecx
|
|
||||||
@@:
|
|
||||||
mov esi, [mem_block_list+eax*4]
|
|
||||||
mov [mem_block_list+eax*4], edi
|
|
||||||
mov [edi+list_fd], esi
|
|
||||||
test esi, esi
|
|
||||||
jz @f
|
|
||||||
mov [esi+list_bk], edi
|
|
||||||
@@:
|
|
||||||
bts [mem_block_mask], eax
|
|
||||||
.m_eq:
|
|
||||||
xor eax, eax
|
|
||||||
mov [heap_mutex], eax
|
|
||||||
dec eax
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebx
|
|
||||||
ret
|
|
||||||
.insert:
|
|
||||||
remove_from_used esi
|
|
||||||
|
|
||||||
mov eax, [esi+block_size]
|
|
||||||
calc_index eax
|
|
||||||
|
|
||||||
mov edi, [mem_block_list+eax*4]
|
|
||||||
mov [mem_block_list+eax*4], esi
|
|
||||||
mov [esi+list_fd], edi
|
|
||||||
test edi, edi
|
|
||||||
jz @f
|
|
||||||
mov [edi+list_bk], esi
|
|
||||||
@@:
|
|
||||||
bts [mem_block_mask], eax
|
|
||||||
mov [esi+block_flags],FREE_BLOCK
|
|
||||||
xor eax, eax
|
|
||||||
mov [heap_mutex], eax
|
|
||||||
dec eax
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebx
|
|
||||||
ret
|
|
||||||
.fail:
|
|
||||||
xor eax, eax
|
|
||||||
mov [heap_mutex], eax
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebx
|
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
@ -555,8 +59,9 @@ proc kernel_alloc stdcall, size:dword
|
|||||||
add eax, 4095
|
add eax, 4095
|
||||||
and eax, not 4095;
|
and eax, not 4095;
|
||||||
mov [size], eax
|
mov [size], eax
|
||||||
and eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
|
|
||||||
mov ebx, eax
|
mov ebx, eax
|
||||||
shr ebx, 12
|
shr ebx, 12
|
||||||
mov [pages_count], ebx
|
mov [pages_count], ebx
|
||||||
@ -617,172 +122,11 @@ endp
|
|||||||
|
|
||||||
align 4
|
align 4
|
||||||
proc kernel_free stdcall, base:dword
|
proc kernel_free stdcall, base:dword
|
||||||
push ebx esi
|
|
||||||
|
|
||||||
mov ebx, heap_mutex
|
|
||||||
call wait_mutex ;ebx
|
|
||||||
|
|
||||||
mov eax, [base]
|
|
||||||
mov esi, [mem_used.fd]
|
|
||||||
@@:
|
|
||||||
cmp esi, mem_used.fd-MEM_LIST_OFFSET
|
|
||||||
je .fail
|
|
||||||
|
|
||||||
cmp [esi+block_base], eax
|
|
||||||
je .found
|
|
||||||
mov esi, [esi+list_fd]
|
|
||||||
jmp @b
|
|
||||||
.found:
|
|
||||||
cmp [esi+block_flags], USED_BLOCK
|
|
||||||
jne .fail
|
|
||||||
|
|
||||||
and [heap_mutex], 0
|
|
||||||
|
|
||||||
push ecx
|
|
||||||
mov ecx, [esi+block_size];
|
|
||||||
shr ecx, 12
|
|
||||||
call release_pages ;eax, ecx
|
|
||||||
pop ecx
|
|
||||||
stdcall free_kernel_space, [base]
|
|
||||||
pop esi ebx
|
|
||||||
ret
|
|
||||||
.fail:
|
|
||||||
and [heap_mutex], 0
|
|
||||||
pop esi ebx
|
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
|
|
||||||
align 4
|
|
||||||
proc alloc_large stdcall, size:dword
|
|
||||||
local block_ind:DWORD
|
|
||||||
|
|
||||||
push ebx
|
|
||||||
push esi
|
|
||||||
push edi
|
|
||||||
|
|
||||||
mov eax, [size]
|
|
||||||
add eax, 0x3FFFFF
|
|
||||||
and eax, not 0x3FFFFF
|
|
||||||
mov [size], eax
|
|
||||||
|
|
||||||
; mov ebx, heap_mutex
|
|
||||||
; call wait_mutex ;ebx
|
|
||||||
|
|
||||||
; cmp eax, [heap_free]
|
|
||||||
; ja .error
|
|
||||||
|
|
||||||
call get_large_block ; eax
|
|
||||||
test edi, edi
|
|
||||||
jz .error
|
|
||||||
|
|
||||||
cmp [edi+block_flags], FREE_BLOCK
|
|
||||||
jne .error
|
|
||||||
|
|
||||||
mov [block_ind], ebx ;index of allocated block
|
|
||||||
|
|
||||||
mov eax, [edi+block_size]
|
|
||||||
cmp eax, [size]
|
|
||||||
je .m_eq_size
|
|
||||||
|
|
||||||
call alloc_mem_block
|
|
||||||
and eax, eax
|
|
||||||
jz .error
|
|
||||||
|
|
||||||
mov esi, eax ;esi - splitted block
|
|
||||||
|
|
||||||
mov [esi+block_next], edi
|
|
||||||
mov eax, [edi+block_prev]
|
|
||||||
mov [esi+block_prev], eax
|
|
||||||
mov [edi+block_prev], esi
|
|
||||||
mov [esi+list_fd], 0
|
|
||||||
mov [esi+list_bk], 0
|
|
||||||
test eax, eax
|
|
||||||
jz @f
|
|
||||||
mov [eax+block_next], esi
|
|
||||||
@@:
|
|
||||||
mov ebx, [edi+block_base]
|
|
||||||
mov [esi+block_base], ebx
|
|
||||||
mov edx, [size]
|
|
||||||
mov [esi+block_size], edx
|
|
||||||
add [edi+block_base], edx
|
|
||||||
sub [edi+block_size], edx
|
|
||||||
|
|
||||||
mov eax, [edi+block_size]
|
|
||||||
shr eax, 22
|
|
||||||
dec eax
|
|
||||||
cmp eax, 31
|
|
||||||
jna @f
|
|
||||||
mov eax, 31
|
|
||||||
@@:
|
|
||||||
cmp eax, [block_ind]
|
|
||||||
je .m_eq_ind
|
|
||||||
|
|
||||||
remove_from_list edi
|
|
||||||
|
|
||||||
mov ecx, [block_ind]
|
|
||||||
mov [large_block_list+ecx*4], edx
|
|
||||||
|
|
||||||
test edx, edx
|
|
||||||
jnz @f
|
|
||||||
btr [large_block_mask], ecx
|
|
||||||
@@:
|
|
||||||
mov edx, [large_block_list+eax*4]
|
|
||||||
mov [edi+list_fd], edx
|
|
||||||
test edx, edx
|
|
||||||
jz @f
|
|
||||||
mov [edx+list_bk], edi
|
|
||||||
@@:
|
|
||||||
mov [large_block_list+eax*4], edi
|
|
||||||
bts [large_block_mask], eax
|
|
||||||
.m_eq_ind:
|
|
||||||
mov ecx, mem_used.fd-MEM_LIST_OFFSET
|
|
||||||
mov edx, [ecx+list_fd]
|
|
||||||
mov [esi+list_fd], edx
|
|
||||||
mov [esi+list_bk], ecx
|
|
||||||
mov [ecx+list_fd], esi
|
|
||||||
mov [edx+list_bk], esi
|
|
||||||
|
|
||||||
mov [esi+block_flags], USED_BLOCK
|
|
||||||
mov eax, [esi+block_base]
|
|
||||||
mov ebx, [size]
|
|
||||||
sub [heap_free], ebx
|
|
||||||
and [heap_mutex], 0
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebx
|
|
||||||
ret
|
|
||||||
.m_eq_size:
|
|
||||||
remove_from_list edi
|
|
||||||
mov [large_block_list+ebx*4], edx
|
|
||||||
and edx, edx
|
|
||||||
jnz @f
|
|
||||||
btr [large_block_mask], ebx
|
|
||||||
@@:
|
|
||||||
mov ecx, mem_used.fd-MEM_LIST_OFFSET
|
|
||||||
mov edx, [ecx+list_fd]
|
|
||||||
mov [edi+list_fd], edx
|
|
||||||
mov [edi+list_bk], ecx
|
|
||||||
mov [ecx+list_fd], edi
|
|
||||||
mov [edx+list_bk], edi
|
|
||||||
|
|
||||||
mov [edi+block_flags], USED_BLOCK
|
|
||||||
mov eax, [edi+block_base]
|
|
||||||
mov ebx, [size]
|
|
||||||
sub [heap_free], ebx
|
|
||||||
and [heap_mutex], 0
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebx
|
|
||||||
ret
|
|
||||||
.error:
|
|
||||||
xor eax, eax
|
|
||||||
mov [heap_mutex], eax
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebx
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
restore block_next
|
restore block_next
|
||||||
restore block_prev
|
restore block_prev
|
||||||
|
@ -174,7 +174,7 @@ release_pages:
|
|||||||
add esi, 4
|
add esi, 4
|
||||||
dec ecx
|
dec ecx
|
||||||
jnz @B
|
jnz @B
|
||||||
mov [pg_data.pages_free], ebp
|
; mov [pg_data.pages_free], ebp
|
||||||
and [pg_data.pg_mutex],0
|
and [pg_data.pg_mutex],0
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
@ -901,12 +901,13 @@ sysfn_meminfo:
|
|||||||
cmp ebx, OS_BASE
|
cmp ebx, OS_BASE
|
||||||
jae .fail
|
jae .fail
|
||||||
|
|
||||||
mov eax, [pg_data.pages_count]
|
mov eax, [_mem_amount]
|
||||||
|
shr eax, 12
|
||||||
mov [ebx], eax
|
mov [ebx], eax
|
||||||
shl eax, 12
|
shl eax, 12
|
||||||
mov [esp+36], eax
|
mov [esp+36], eax
|
||||||
mov ecx, [pg_data.pages_free]
|
call _get_free_mem
|
||||||
mov [ebx+4], ecx
|
mov [ebx+4], eax
|
||||||
mov edx, [pg_data.pages_faults]
|
mov edx, [pg_data.pages_faults]
|
||||||
mov [ebx+8], edx
|
mov [ebx+8], edx
|
||||||
mov esi, [heap_size]
|
mov esi, [heap_size]
|
||||||
|
@ -30,13 +30,12 @@ static void __fastcall buddy_system_free(zone_t *z, link_t *block);
|
|||||||
static void zone_mark_unavailable(zone_t *zone, index_t frame_idx);
|
static void zone_mark_unavailable(zone_t *zone, index_t frame_idx);
|
||||||
|
|
||||||
static addr_t __fastcall zone_alloc(zone_t *zone, u32_t order);
|
static addr_t __fastcall zone_alloc(zone_t *zone, u32_t order);
|
||||||
|
void __fastcall zone_free(zone_t *zone, pfn_t frame_idx);
|
||||||
|
|
||||||
size_t buddy_conf_size(int max_order);
|
size_t buddy_conf_size(int max_order);
|
||||||
|
|
||||||
static inline void frame_initialize(frame_t *frame);
|
static inline void frame_initialize(frame_t *frame);
|
||||||
|
|
||||||
static inline u32_t fnzb(u32_t arg);
|
|
||||||
|
|
||||||
void init_mm();
|
void init_mm();
|
||||||
|
|
||||||
|
|
||||||
@ -211,16 +210,6 @@ static inline void frame_initialize(frame_t *frame)
|
|||||||
frame->buddy_order = 0;
|
frame->buddy_order = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline count_t fnzb(u32_t arg)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
asm volatile ("xor %0, %0 \n\t"
|
|
||||||
"bsr %0, %1"
|
|
||||||
:"=r" (n)
|
|
||||||
:"r"(arg)
|
|
||||||
);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static link_t *buddy_find_block(zone_t *zone, link_t *child,
|
static link_t *buddy_find_block(zone_t *zone, link_t *child,
|
||||||
u32_t order)
|
u32_t order)
|
||||||
@ -502,6 +491,7 @@ static __fastcall pfn_t zone_frame_alloc(zone_t *zone, u32_t order)
|
|||||||
|
|
||||||
/* get frame address */
|
/* get frame address */
|
||||||
v = make_frame_index(zone, frame);
|
v = make_frame_index(zone, frame);
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,6 +508,17 @@ void __fastcall frame_set_parent(pfn_t pfn, void *data)
|
|||||||
spinlock_unlock(&z_core.lock);
|
spinlock_unlock(&z_core.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* __fastcall frame_get_parent(pfn_t pfn)
|
||||||
|
{
|
||||||
|
// zone_t *zone = find_zone_and_lock(pfn, &hint);
|
||||||
|
void *res;
|
||||||
|
|
||||||
|
spinlock_lock(&z_core.lock);
|
||||||
|
res = zone_get_frame(&z_core, pfn)->parent;
|
||||||
|
spinlock_unlock(&z_core.lock);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int to_order(count_t arg)
|
static inline int to_order(count_t arg)
|
||||||
{
|
{
|
||||||
@ -548,7 +549,7 @@ addr_t __fastcall zone_alloc(zone_t *zone, u32_t order)
|
|||||||
return (v << FRAME_WIDTH);
|
return (v << FRAME_WIDTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t core_alloc(u32_t order) //__cdecl __dllexport
|
addr_t __fastcall core_alloc(u32_t order) //export
|
||||||
{
|
{
|
||||||
eflags_t efl;
|
eflags_t efl;
|
||||||
pfn_t v;
|
pfn_t v;
|
||||||
@ -562,7 +563,18 @@ addr_t core_alloc(u32_t order) //__cdecl __dllexport
|
|||||||
return (v << FRAME_WIDTH);
|
return (v << FRAME_WIDTH);
|
||||||
};
|
};
|
||||||
|
|
||||||
addr_t alloc_page() //obsolete
|
void __fastcall core_free(addr_t frame) //export
|
||||||
|
{
|
||||||
|
eflags_t efl;
|
||||||
|
|
||||||
|
efl = safe_cli();
|
||||||
|
spinlock_lock(&z_core.lock);
|
||||||
|
zone_free(&z_core, frame>>12);
|
||||||
|
spinlock_unlock(&z_core.lock);
|
||||||
|
safe_sti(efl);
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_t alloc_page() //obsolete
|
||||||
{
|
{
|
||||||
eflags_t efl;
|
eflags_t efl;
|
||||||
u32_t edx;
|
u32_t edx;
|
||||||
@ -619,17 +631,6 @@ void __fastcall zone_free(zone_t *zone, pfn_t frame_idx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_free(addr_t frame) //export
|
|
||||||
{
|
|
||||||
eflags_t efl;
|
|
||||||
|
|
||||||
efl = safe_cli();
|
|
||||||
spinlock_lock(&z_core.lock);
|
|
||||||
zone_free(&z_core, frame>>12);
|
|
||||||
spinlock_unlock(&z_core.lock);
|
|
||||||
safe_sti(efl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void frame_free(addr_t frame) //export
|
void frame_free(addr_t frame) //export
|
||||||
{
|
{
|
||||||
eflags_t efl;
|
eflags_t efl;
|
||||||
@ -642,3 +643,8 @@ void frame_free(addr_t frame) //export
|
|||||||
safe_sti(efl);
|
safe_sti(efl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
count_t get_free_mem()
|
||||||
|
{
|
||||||
|
return z_core.free_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -213,10 +213,10 @@ do_change_task:
|
|||||||
|
|
||||||
; set thread io map
|
; set thread io map
|
||||||
|
|
||||||
mov ecx, [ebx+APPDATA.io_map]
|
; mov ecx, [ebx+APPDATA.io_map]
|
||||||
mov edx, [ebx+APPDATA.io_map+4]
|
; mov edx, [ebx+APPDATA.io_map+4]
|
||||||
mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)], ecx
|
; mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)], ecx
|
||||||
mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)], edx
|
; mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)], edx
|
||||||
|
|
||||||
mov eax, [ebx+APPDATA.dir_table]
|
mov eax, [ebx+APPDATA.dir_table]
|
||||||
cmp eax, [esi+APPDATA.dir_table]
|
cmp eax, [esi+APPDATA.dir_table]
|
||||||
|
471
kernel/branches/kolibri_pe/core/slab.c
Normal file
471
kernel/branches/kolibri_pe/core/slab.c
Normal file
@ -0,0 +1,471 @@
|
|||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <core.h>
|
||||||
|
#include <spinlock.h>
|
||||||
|
#include <link.h>
|
||||||
|
#include <mm.h>
|
||||||
|
#include <slab.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern zone_t z_core;
|
||||||
|
|
||||||
|
|
||||||
|
static LIST_INITIALIZE(slab_cache_list);
|
||||||
|
|
||||||
|
static slab_cache_t *slab_cache;
|
||||||
|
|
||||||
|
static slab_cache_t slab_cache_cache;
|
||||||
|
|
||||||
|
static slab_t *slab_create();
|
||||||
|
|
||||||
|
static slab_cache_t * slab_cache_alloc();
|
||||||
|
|
||||||
|
void slab_free(slab_cache_t *cache, void *obj);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate frames for slab space and initialize
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static slab_t * slab_space_alloc(slab_cache_t *cache, int flags)
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
slab_t *slab;
|
||||||
|
size_t fsize;
|
||||||
|
unsigned int i;
|
||||||
|
u32_t p;
|
||||||
|
|
||||||
|
data = (void*)PA2KA(core_alloc(cache->order));
|
||||||
|
if (!data) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
slab = (slab_t*)slab_create();
|
||||||
|
if (!slab) {
|
||||||
|
core_free(KA2PA(data));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in slab structures */
|
||||||
|
for (i = 0; i < ((u32_t) 1 << cache->order); i++)
|
||||||
|
frame_set_parent(ADDR2PFN(KA2PA(data)) + i, slab);
|
||||||
|
|
||||||
|
slab->start = data;
|
||||||
|
slab->available = cache->objects;
|
||||||
|
slab->nextavail = (void*)data;
|
||||||
|
slab->cache = cache;
|
||||||
|
|
||||||
|
for (i = 0, p = (u32_t)slab->start; i < cache->objects; i++)
|
||||||
|
{
|
||||||
|
*(addr_t *)p = p+cache->size;
|
||||||
|
p = p+cache->size;
|
||||||
|
};
|
||||||
|
atomic_inc(&cache->allocated_slabs);
|
||||||
|
return slab;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take new object from slab or create new if needed
|
||||||
|
*
|
||||||
|
* @return Object address or null
|
||||||
|
*/
|
||||||
|
static void * slab_obj_create(slab_cache_t *cache, int flags)
|
||||||
|
{
|
||||||
|
slab_t *slab;
|
||||||
|
void *obj;
|
||||||
|
|
||||||
|
spinlock_lock(&cache->slablock);
|
||||||
|
|
||||||
|
if (list_empty(&cache->partial_slabs)) {
|
||||||
|
/* Allow recursion and reclaiming
|
||||||
|
* - this should work, as the slab control structures
|
||||||
|
* are small and do not need to allocate with anything
|
||||||
|
* other than frame_alloc when they are allocating,
|
||||||
|
* that's why we should get recursion at most 1-level deep
|
||||||
|
*/
|
||||||
|
slab = slab_space_alloc(cache, flags);
|
||||||
|
if (!slab)
|
||||||
|
{
|
||||||
|
spinlock_unlock(&cache->slablock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
slab = list_get_instance(cache->partial_slabs.next, slab_t, link);
|
||||||
|
list_remove(&slab->link);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj = slab->nextavail;
|
||||||
|
slab->nextavail = *(void**)obj;
|
||||||
|
slab->available--;
|
||||||
|
|
||||||
|
if (!slab->available)
|
||||||
|
list_prepend(&slab->link, &cache->full_slabs);
|
||||||
|
else
|
||||||
|
list_prepend(&slab->link, &cache->partial_slabs);
|
||||||
|
|
||||||
|
spinlock_unlock(&cache->slablock);
|
||||||
|
|
||||||
|
// if (cache->constructor && cache->constructor(obj, flags)) {
|
||||||
|
/* Bad, bad, construction failed */
|
||||||
|
// slab_obj_destroy(cache, obj, slab);
|
||||||
|
// return NULL;
|
||||||
|
// }
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Map object to slab structure */
|
||||||
|
static slab_t * obj2slab(void *obj)
|
||||||
|
{
|
||||||
|
return (slab_t *) frame_get_parent(ADDR2PFN(KA2PA(obj)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Allocate new object from cache - if no flags given, always returns
|
||||||
|
memory */
|
||||||
|
void* __fastcall slab_alloc(slab_cache_t *cache, int flags)
|
||||||
|
{
|
||||||
|
eflags_t efl;
|
||||||
|
void *result = NULL;
|
||||||
|
|
||||||
|
/* Disable interrupts to avoid deadlocks with interrupt handlers */
|
||||||
|
efl = safe_cli();
|
||||||
|
|
||||||
|
// if (!(cache->flags & SLAB_CACHE_NOMAGAZINE)) {
|
||||||
|
// result = magazine_obj_get(cache);
|
||||||
|
// }
|
||||||
|
// if (!result)
|
||||||
|
result = slab_obj_create(cache, flags);
|
||||||
|
|
||||||
|
safe_sti(efl);
|
||||||
|
|
||||||
|
// if (result)
|
||||||
|
// atomic_inc(&cache->allocated_objs);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************/
|
||||||
|
/* Slab cache functions */
|
||||||
|
|
||||||
|
/** Return number of objects that fit in certain cache size */
|
||||||
|
static unsigned int comp_objects(slab_cache_t *cache)
|
||||||
|
{
|
||||||
|
if (cache->flags & SLAB_CACHE_SLINSIDE)
|
||||||
|
return ((PAGE_SIZE << cache->order) - sizeof(slab_t)) / cache->size;
|
||||||
|
else
|
||||||
|
return (PAGE_SIZE << cache->order) / cache->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return wasted space in slab */
|
||||||
|
static unsigned int badness(slab_cache_t *cache)
|
||||||
|
{
|
||||||
|
unsigned int objects;
|
||||||
|
unsigned int ssize;
|
||||||
|
size_t val;
|
||||||
|
|
||||||
|
objects = comp_objects(cache);
|
||||||
|
ssize = PAGE_SIZE << cache->order;
|
||||||
|
if (cache->flags & SLAB_CACHE_SLINSIDE)
|
||||||
|
ssize -= sizeof(slab_t);
|
||||||
|
val = ssize - objects * cache->size;
|
||||||
|
return val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Initialize allocated memory as a slab cache */
|
||||||
|
static void
|
||||||
|
_slab_cache_create(slab_cache_t *cache,
|
||||||
|
size_t size,
|
||||||
|
size_t align,
|
||||||
|
int (*constructor)(void *obj, int kmflag),
|
||||||
|
int (*destructor)(void *obj),
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
int pages;
|
||||||
|
// ipl_t ipl;
|
||||||
|
|
||||||
|
// memsetb((uintptr_t)cache, sizeof(*cache), 0);
|
||||||
|
// cache->name = name;
|
||||||
|
|
||||||
|
//if (align < sizeof(unative_t))
|
||||||
|
// align = sizeof(unative_t);
|
||||||
|
// size = ALIGN_UP(size, align);
|
||||||
|
|
||||||
|
cache->size = size;
|
||||||
|
|
||||||
|
// cache->constructor = constructor;
|
||||||
|
// cache->destructor = destructor;
|
||||||
|
cache->flags = flags;
|
||||||
|
|
||||||
|
list_initialize(&cache->full_slabs);
|
||||||
|
list_initialize(&cache->partial_slabs);
|
||||||
|
list_initialize(&cache->magazines);
|
||||||
|
// spinlock_initialize(&cache->slablock, "slab_lock");
|
||||||
|
// spinlock_initialize(&cache->maglock, "slab_maglock");
|
||||||
|
// if (! (cache->flags & SLAB_CACHE_NOMAGAZINE))
|
||||||
|
// make_magcache(cache);
|
||||||
|
|
||||||
|
/* Compute slab sizes, object counts in slabs etc. */
|
||||||
|
|
||||||
|
/* Minimum slab order */
|
||||||
|
pages = SIZE2FRAMES(cache->size);
|
||||||
|
/* We need the 2^order >= pages */
|
||||||
|
if (pages == 1)
|
||||||
|
cache->order = 0;
|
||||||
|
else
|
||||||
|
cache->order = fnzb(pages-1)+1;
|
||||||
|
|
||||||
|
while (badness(cache) > SLAB_MAX_BADNESS(cache)) {
|
||||||
|
cache->order += 1;
|
||||||
|
}
|
||||||
|
cache->objects = comp_objects(cache);
|
||||||
|
|
||||||
|
/* Add cache to cache list */
|
||||||
|
// ipl = interrupts_disable();
|
||||||
|
// spinlock_lock(&slab_cache_lock);
|
||||||
|
|
||||||
|
list_append(&cache->link, &slab_cache_list);
|
||||||
|
|
||||||
|
// spinlock_unlock(&slab_cache_lock);
|
||||||
|
// interrupts_restore(ipl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create slab cache */
|
||||||
|
slab_cache_t * slab_cache_create(
|
||||||
|
size_t size,
|
||||||
|
size_t align,
|
||||||
|
int (*constructor)(void *obj, int kmflag),
|
||||||
|
int (*destructor)(void *obj),
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
slab_cache_t *cache;
|
||||||
|
|
||||||
|
cache = (slab_cache_t*)slab_cache_alloc();
|
||||||
|
_slab_cache_create(cache, size, align, constructor, destructor, flags);
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deallocate space associated with slab
|
||||||
|
*
|
||||||
|
* @return number of freed frames
|
||||||
|
*/
|
||||||
|
static count_t slab_space_free(slab_cache_t *cache, slab_t *slab)
|
||||||
|
{
|
||||||
|
frame_free(KA2PA(slab->start));
|
||||||
|
if (! (cache->flags & SLAB_CACHE_SLINSIDE))
|
||||||
|
slab_free(slab_cache, slab);
|
||||||
|
|
||||||
|
// atomic_dec(&cache->allocated_slabs);
|
||||||
|
|
||||||
|
return 1 << cache->order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return object to slab and call a destructor
|
||||||
|
*
|
||||||
|
* @param slab If the caller knows directly slab of the object, otherwise NULL
|
||||||
|
*
|
||||||
|
* @return Number of freed pages
|
||||||
|
*/
|
||||||
|
static count_t slab_obj_destroy(slab_cache_t *cache, void *obj,
|
||||||
|
slab_t *slab)
|
||||||
|
{
|
||||||
|
int freed = 0;
|
||||||
|
|
||||||
|
if (!slab)
|
||||||
|
slab = obj2slab(obj);
|
||||||
|
|
||||||
|
// ASSERT(slab->cache == cache);
|
||||||
|
|
||||||
|
// if (cache->destructor)
|
||||||
|
// freed = cache->destructor(obj);
|
||||||
|
|
||||||
|
// spinlock_lock(&cache->slablock);
|
||||||
|
// ASSERT(slab->available < cache->objects);
|
||||||
|
|
||||||
|
*(void**)obj = slab->nextavail;
|
||||||
|
slab->nextavail = obj;
|
||||||
|
slab->available++;
|
||||||
|
|
||||||
|
/* Move it to correct list */
|
||||||
|
if (slab->available == cache->objects) {
|
||||||
|
/* Free associated memory */
|
||||||
|
list_remove(&slab->link);
|
||||||
|
// spinlock_unlock(&cache->slablock);
|
||||||
|
|
||||||
|
return freed + slab_space_free(cache, slab);
|
||||||
|
|
||||||
|
} else if (slab->available == 1) {
|
||||||
|
/* It was in full, move to partial */
|
||||||
|
list_remove(&slab->link);
|
||||||
|
list_prepend(&slab->link, &cache->partial_slabs);
|
||||||
|
}
|
||||||
|
// spinlock_unlock(&cache->slablock);
|
||||||
|
return freed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Return object to cache, use slab if known */
|
||||||
|
static void _slab_free(slab_cache_t *cache, void *obj, slab_t *slab)
|
||||||
|
{
|
||||||
|
// ipl_t ipl;
|
||||||
|
|
||||||
|
// ipl = interrupts_disable();
|
||||||
|
|
||||||
|
// if ((cache->flags & SLAB_CACHE_NOMAGAZINE) \
|
||||||
|
|| magazine_obj_put(cache, obj)) {
|
||||||
|
|
||||||
|
slab_obj_destroy(cache, obj, slab);
|
||||||
|
|
||||||
|
// }
|
||||||
|
// interrupts_restore(ipl);
|
||||||
|
// atomic_dec(&cache->allocated_objs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return slab object to cache */
|
||||||
|
void slab_free(slab_cache_t *cache, void *obj)
|
||||||
|
{
|
||||||
|
_slab_free(cache, obj, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static slab_t *slab_create()
|
||||||
|
{
|
||||||
|
slab_t *slab;
|
||||||
|
void *obj;
|
||||||
|
u32_t p;
|
||||||
|
|
||||||
|
// spinlock_lock(&cache->slablock);
|
||||||
|
|
||||||
|
if (list_empty(&slab_cache->partial_slabs)) {
|
||||||
|
/* Allow recursion and reclaiming
|
||||||
|
* - this should work, as the slab control structures
|
||||||
|
* are small and do not need to allocate with anything
|
||||||
|
* other than frame_alloc when they are allocating,
|
||||||
|
* that's why we should get recursion at most 1-level deep
|
||||||
|
*/
|
||||||
|
// spinlock_unlock(&cache->slablock);
|
||||||
|
// slab = slab_create();
|
||||||
|
|
||||||
|
void *data;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
data = (void*)PA2KA(core_alloc(0));
|
||||||
|
if (!data) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
slab = (slab_t*)((u32_t)data + PAGE_SIZE - sizeof(slab_t));
|
||||||
|
|
||||||
|
/* Fill in slab structures */
|
||||||
|
frame_set_parent(ADDR2PFN(KA2PA(data)), slab);
|
||||||
|
|
||||||
|
slab->start = data;
|
||||||
|
slab->available = slab_cache->objects;
|
||||||
|
slab->nextavail = (void*)data;
|
||||||
|
slab->cache = slab_cache;
|
||||||
|
|
||||||
|
for (i = 0,p = (u32_t)slab->start;i < slab_cache->objects; i++)
|
||||||
|
{
|
||||||
|
*(int *)p = p+slab_cache->size;
|
||||||
|
p = p+slab_cache->size;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
atomic_inc(&slab_cache->allocated_slabs);
|
||||||
|
// spinlock_lock(&cache->slablock);
|
||||||
|
} else {
|
||||||
|
slab = list_get_instance(slab_cache->partial_slabs.next, slab_t, link);
|
||||||
|
list_remove(&slab->link);
|
||||||
|
}
|
||||||
|
obj = slab->nextavail;
|
||||||
|
slab->nextavail = *((void**)obj);
|
||||||
|
slab->available--;
|
||||||
|
|
||||||
|
if (!slab->available)
|
||||||
|
list_prepend(&slab->link, &slab_cache->full_slabs);
|
||||||
|
else
|
||||||
|
list_prepend(&slab->link, &slab_cache->partial_slabs);
|
||||||
|
|
||||||
|
// spinlock_unlock(&cache->slablock);
|
||||||
|
|
||||||
|
return (slab_t*)obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static slab_cache_t * slab_cache_alloc()
|
||||||
|
{
|
||||||
|
slab_t *slab;
|
||||||
|
void *obj;
|
||||||
|
u32_t *p;
|
||||||
|
|
||||||
|
if (list_empty(&slab_cache_cache.partial_slabs)) {
|
||||||
|
/* Allow recursion and reclaiming
|
||||||
|
* - this should work, as the slab control structures
|
||||||
|
* are small and do not need to allocate with anything
|
||||||
|
* other than frame_alloc when they are allocating,
|
||||||
|
* that's why we should get recursion at most 1-level deep
|
||||||
|
*/
|
||||||
|
// spinlock_unlock(&cache->slablock);
|
||||||
|
// slab = slab_create();
|
||||||
|
|
||||||
|
void *data;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
data = (void*)(PA2KA(core_alloc(0)));
|
||||||
|
if (!data) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
slab = (slab_t*)((u32_t)data + PAGE_SIZE - sizeof(slab_t));
|
||||||
|
|
||||||
|
/* Fill in slab structures */
|
||||||
|
frame_set_parent(ADDR2PFN(KA2PA(data)), slab);
|
||||||
|
|
||||||
|
slab->start = data;
|
||||||
|
slab->available = slab_cache_cache.objects;
|
||||||
|
slab->nextavail = (void*)data;
|
||||||
|
slab->cache = &slab_cache_cache;
|
||||||
|
|
||||||
|
for (i = 0,p = (u32_t*)slab->start;i < slab_cache_cache.objects; i++)
|
||||||
|
{
|
||||||
|
*p = (u32_t)p+slab_cache_cache.size;
|
||||||
|
p = (u32_t*)((u32_t)p+slab_cache_cache.size);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
atomic_inc(&slab_cache_cache.allocated_slabs);
|
||||||
|
// spinlock_lock(&cache->slablock);
|
||||||
|
} else {
|
||||||
|
slab = list_get_instance(slab_cache_cache.partial_slabs.next, slab_t, link);
|
||||||
|
list_remove(&slab->link);
|
||||||
|
}
|
||||||
|
obj = slab->nextavail;
|
||||||
|
slab->nextavail = *((void**)obj);
|
||||||
|
slab->available--;
|
||||||
|
|
||||||
|
if (!slab->available)
|
||||||
|
list_prepend(&slab->link, &slab_cache_cache.full_slabs);
|
||||||
|
else
|
||||||
|
list_prepend(&slab->link, &slab_cache_cache.partial_slabs);
|
||||||
|
|
||||||
|
// spinlock_unlock(&cache->slablock);
|
||||||
|
|
||||||
|
return (slab_cache_t*)obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void slab_cache_init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
_slab_cache_create(&slab_cache_cache, sizeof(slab_cache_t),
|
||||||
|
sizeof(void *), NULL, NULL,
|
||||||
|
SLAB_CACHE_NOMAGAZINE | SLAB_CACHE_SLINSIDE);
|
||||||
|
|
||||||
|
/* Initialize external slab cache */
|
||||||
|
slab_cache = slab_cache_create(sizeof(slab_t),
|
||||||
|
0, NULL, NULL,SLAB_CACHE_MAGDEFERRED);
|
||||||
|
};
|
||||||
|
|
@ -468,7 +468,7 @@ term9:
|
|||||||
mov eax, [.slot]
|
mov eax, [.slot]
|
||||||
shl eax, 8
|
shl eax, 8
|
||||||
mov eax,[SLOT_BASE+eax+APPDATA.dir_table]
|
mov eax,[SLOT_BASE+eax+APPDATA.dir_table]
|
||||||
stdcall destroy_app_space, eax
|
; stdcall destroy_app_space, eax
|
||||||
|
|
||||||
mov esi, [.slot]
|
mov esi, [.slot]
|
||||||
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1
|
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1
|
||||||
|
@ -1074,7 +1074,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\
|
|||||||
mov eax, [esi+0x08] ;app_eip
|
mov eax, [esi+0x08] ;app_eip
|
||||||
mov [ebx+REG_EIP], eax ;app_entry
|
mov [ebx+REG_EIP], eax ;app_entry
|
||||||
mov [ebx+REG_CS], dword app_code
|
mov [ebx+REG_CS], dword app_code
|
||||||
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF
|
mov [ebx+REG_EFLAGS], dword EFL_IOPL3+EFL_IF
|
||||||
|
|
||||||
mov eax, [esi+0x0C] ;app_esp
|
mov eax, [esi+0x0C] ;app_esp
|
||||||
mov [ebx+REG_APP_ESP], eax ;app_stack
|
mov [ebx+REG_APP_ESP], eax ;app_stack
|
||||||
|
123
kernel/branches/kolibri_pe/core/test.c
Normal file
123
kernel/branches/kolibri_pe/core/test.c
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
typedef unsigned char u8_t;
|
||||||
|
typedef unsigned short int u16_t;
|
||||||
|
typedef unsigned int u32_t;
|
||||||
|
typedef unsigned long long u64_t;
|
||||||
|
|
||||||
|
static inline u8_t inb(u16_t port)
|
||||||
|
{
|
||||||
|
u8_t val;
|
||||||
|
if(port < 0x100)
|
||||||
|
asm volatile ("in %b0, %w1 \n" : "=a" (val) : "dN" (port) );
|
||||||
|
else
|
||||||
|
asm volatile ("in %b0, %w1 \n" : "=a" (val) : "d" (port) );
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline outb(u16_t port, u8_t val)
|
||||||
|
{
|
||||||
|
if (port < 0x100) /* GCC can optimize this if constant */
|
||||||
|
asm volatile ("out %w0, %b1" : :"dN"(port), "a"(val));
|
||||||
|
else
|
||||||
|
asm volatile ("out %w0, %b1" : :"d"(port), "a"(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Convert the integer D to a string and save the string in BUF. If
|
||||||
|
BASE is equal to 'd', interpret that D is decimal, and if BASE is
|
||||||
|
equal to 'x', interpret that D is hexadecimal. */
|
||||||
|
static void itoa (char *buf, int base, int d)
|
||||||
|
{
|
||||||
|
char *p = buf;
|
||||||
|
char *p1, *p2;
|
||||||
|
unsigned long ud = d;
|
||||||
|
int divisor = 10;
|
||||||
|
|
||||||
|
/* If %d is specified and D is minus, put `-' in the head. */
|
||||||
|
if (base == 'd' && d < 0)
|
||||||
|
{
|
||||||
|
*p++ = '-';
|
||||||
|
buf++;
|
||||||
|
ud = -d;
|
||||||
|
}
|
||||||
|
else if (base == 'x')
|
||||||
|
divisor = 16;
|
||||||
|
|
||||||
|
/* Divide UD by DIVISOR until UD == 0. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int remainder = ud % divisor;
|
||||||
|
|
||||||
|
*p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
|
||||||
|
}
|
||||||
|
while (ud /= divisor);
|
||||||
|
|
||||||
|
/* Terminate BUF. */
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
/* Reverse BUF. */
|
||||||
|
p1 = buf;
|
||||||
|
p2 = p - 1;
|
||||||
|
while (p1 < p2)
|
||||||
|
{
|
||||||
|
char tmp = *p1;
|
||||||
|
*p1 = *p2;
|
||||||
|
*p2 = tmp;
|
||||||
|
p1++;
|
||||||
|
p2--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void putc(int c)
|
||||||
|
{
|
||||||
|
while (!(inb(0x3f8+5) & 0x60));
|
||||||
|
outb(0x3f8,c);
|
||||||
|
if (c == '\n')
|
||||||
|
putc('\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
void _printf (const char *format, ...)
|
||||||
|
{
|
||||||
|
char **arg = (char **) &format;
|
||||||
|
int c;
|
||||||
|
char buf[20];
|
||||||
|
|
||||||
|
arg++;
|
||||||
|
|
||||||
|
while ((c = *format++) != 0)
|
||||||
|
{
|
||||||
|
if (c != '%')
|
||||||
|
putc(c);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
c = *format++;
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
case 'u':
|
||||||
|
case 'x':
|
||||||
|
itoa (buf, c, *((int *) arg++));
|
||||||
|
p = buf;
|
||||||
|
goto string;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
p = *arg++;
|
||||||
|
if (! p)
|
||||||
|
p = "(null)";
|
||||||
|
|
||||||
|
string:
|
||||||
|
while (*p)
|
||||||
|
putc(*p++);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
putc(*((int *) arg++));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,8 @@ $Revision$
|
|||||||
|
|
||||||
pusha
|
pusha
|
||||||
|
|
||||||
mov eax,[pg_data.pages_free]
|
call _get_free_mem
|
||||||
|
|
||||||
; 1/32
|
; 1/32
|
||||||
shr eax,5
|
shr eax,5
|
||||||
; round off up to 8 pages
|
; round off up to 8 pages
|
||||||
|
@ -46,3 +46,43 @@ static inline void safe_sti(eflags_t efl)
|
|||||||
: : "r" (efl)
|
: : "r" (efl)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline count_t fnzb(u32_t arg)
|
||||||
|
{
|
||||||
|
count_t n;
|
||||||
|
asm volatile ("xor %0, %0 \n\t"
|
||||||
|
"bsr %0, %1"
|
||||||
|
:"=&r" (n)
|
||||||
|
:"r"(arg)
|
||||||
|
);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline count_t _bsf(u32_t arg)
|
||||||
|
{
|
||||||
|
count_t n;
|
||||||
|
asm volatile ("xor %0, %0 \n\t"
|
||||||
|
"bsf %0, %1"
|
||||||
|
:"=&r" (n)
|
||||||
|
:"r"(arg)
|
||||||
|
);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _bts(u32_t *data, count_t val)
|
||||||
|
{
|
||||||
|
asm volatile ("bts %0, %1 \n\t"
|
||||||
|
:
|
||||||
|
:"g"(data), "r"(val)
|
||||||
|
:"cc"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _btr(u32_t *data, count_t val)
|
||||||
|
{
|
||||||
|
asm volatile ("btr %0, %1 \n\t"
|
||||||
|
:
|
||||||
|
:"g"(data), "r"(val)
|
||||||
|
:"cc"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -5,6 +5,9 @@ typedef struct link
|
|||||||
struct link *next;
|
struct link *next;
|
||||||
}link_t;
|
}link_t;
|
||||||
|
|
||||||
|
#define LIST_INITIALIZE(name) \
|
||||||
|
link_t name = { .prev = &name, .next = &name }
|
||||||
|
|
||||||
#define list_get_instance(link, type, member) \
|
#define list_get_instance(link, type, member) \
|
||||||
((type *)(((u8_t *)(link)) - ((u8_t *)&(((type *)NULL)->member))))
|
((type *)(((u8_t *)(link)) - ((u8_t *)&(((type *)NULL)->member))))
|
||||||
|
|
||||||
@ -48,3 +51,10 @@ static inline void list_prepend(link_t *link, link_t *head)
|
|||||||
head->next = link;
|
head->next = link;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline list_insert(link_t *old, link_t *new)
|
||||||
|
{
|
||||||
|
new->prev = old->prev;
|
||||||
|
new->next = old;
|
||||||
|
new->prev->next = new;
|
||||||
|
old->prev = new;
|
||||||
|
}
|
||||||
|
@ -22,9 +22,15 @@ typedef struct {
|
|||||||
int flags;
|
int flags;
|
||||||
} zone_t;
|
} zone_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
count_t count;
|
||||||
|
addr_t frames[18];
|
||||||
|
}phismem_t;
|
||||||
|
|
||||||
# define PA2KA(x) (((u32_t) (x)) + OS_BASE)
|
|
||||||
# define KA2PA(x) (((u32_t) (x)) - OS_BASE)
|
# define PA2KA(x) (((addr_t) (x)) + OS_BASE)
|
||||||
|
# define KA2PA(x) (((addr_t) (x)) - OS_BASE)
|
||||||
|
|
||||||
#define PAGE_SIZE 4096
|
#define PAGE_SIZE 4096
|
||||||
#define FRAME_WIDTH 12
|
#define FRAME_WIDTH 12
|
||||||
@ -50,10 +56,13 @@ static inline pfn_t ADDR2PFN(addr_t addr)
|
|||||||
|
|
||||||
void init_mm();
|
void init_mm();
|
||||||
|
|
||||||
pfn_t core_alloc(u32_t order);
|
addr_t __fastcall core_alloc(u32_t order);
|
||||||
|
void __fastcall core_free(addr_t frame);
|
||||||
|
|
||||||
pfn_t alloc_page() __attribute__ ((deprecated));
|
pfn_t alloc_page() __attribute__ ((deprecated));
|
||||||
pfn_t __stdcall alloc_pages(count_t count) __asm__ ("_alloc_pages") __attribute__ ((deprecated));
|
pfn_t __stdcall alloc_pages(count_t count) __asm__ ("_alloc_pages") __attribute__ ((deprecated));
|
||||||
|
|
||||||
void core_free(pfn_t frame);
|
|
||||||
void frame_free(pfn_t frame);
|
void frame_free(pfn_t frame);
|
||||||
|
|
||||||
|
void __fastcall frame_set_parent(pfn_t pfn, void *data);
|
||||||
|
void* __fastcall frame_get_parent(pfn_t pfn);
|
||||||
|
80
kernel/branches/kolibri_pe/include/slab.h
Normal file
80
kernel/branches/kolibri_pe/include/slab.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
typedef struct {
|
||||||
|
link_t link;
|
||||||
|
count_t busy; /**< Count of full slots in magazine */
|
||||||
|
count_t size; /**< Number of slots in magazine */
|
||||||
|
void *objs[]; /**< Slots in magazine */
|
||||||
|
} slab_magazine_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
slab_magazine_t *current;
|
||||||
|
slab_magazine_t *last;
|
||||||
|
SPINLOCK_DECLARE(lock);
|
||||||
|
} slab_mag_cache_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
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 */
|
||||||
|
u32_t order; /**< Order of frames to be allocated */
|
||||||
|
unsigned int objects; /**< Number of objects that fit in */
|
||||||
|
|
||||||
|
/* Statistics */
|
||||||
|
atomic_t allocated_slabs;
|
||||||
|
atomic_t allocated_objs;
|
||||||
|
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 */
|
||||||
|
SPINLOCK_DECLARE(slablock);
|
||||||
|
/* Magazines */
|
||||||
|
link_t magazines; /**< List o full magazines */
|
||||||
|
SPINLOCK_DECLARE(maglock);
|
||||||
|
|
||||||
|
/** CPU cache */
|
||||||
|
slab_mag_cache_t *mag_cache;
|
||||||
|
} slab_cache_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
link_t link; /**< List of full/partial slabs. */
|
||||||
|
slab_cache_t *cache; /**< Pointer to parent cache. */
|
||||||
|
count_t available; /**< Count of available items in this slab. */
|
||||||
|
void *start; /**< Start address of first item. */
|
||||||
|
void *nextavail; /**< The index of next available item. */
|
||||||
|
} slab_t;
|
||||||
|
|
||||||
|
#define SLAB_INSIDE_SIZE (4096 >> 3)
|
||||||
|
|
||||||
|
/** Maximum wasted space we allow for cache */
|
||||||
|
#define SLAB_MAX_BADNESS(cache) (((size_t) PAGE_SIZE << (cache)->order) >> 2)
|
||||||
|
|
||||||
|
/** Do not use per-cpu cache */
|
||||||
|
#define SLAB_CACHE_NOMAGAZINE 0x1
|
||||||
|
/** Have control structure inside SLAB */
|
||||||
|
#define SLAB_CACHE_SLINSIDE 0x2
|
||||||
|
/** We add magazine cache later, if we have this flag */
|
||||||
|
#define SLAB_CACHE_MAGDEFERRED (0x4 | SLAB_CACHE_NOMAGAZINE)
|
||||||
|
|
||||||
|
|
||||||
|
slab_cache_t * slab_cache_create(
|
||||||
|
size_t size,
|
||||||
|
size_t align,
|
||||||
|
int (*constructor)(void *obj, int kmflag),
|
||||||
|
int (*destructor)(void *obj),
|
||||||
|
int flags);
|
||||||
|
|
||||||
|
void* __fastcall slab_alloc(slab_cache_t *cache, int flags);
|
@ -123,6 +123,12 @@ public @balloc@4
|
|||||||
|
|
||||||
public __setvars
|
public __setvars
|
||||||
|
|
||||||
|
public _rd_base
|
||||||
|
public _rd_fat
|
||||||
|
public _rd_fat_end
|
||||||
|
public _rd_root
|
||||||
|
public _rd_root_end
|
||||||
|
|
||||||
extrn _16bit_start
|
extrn _16bit_start
|
||||||
extrn _16bit_end
|
extrn _16bit_end
|
||||||
|
|
||||||
@ -131,15 +137,22 @@ extrn _enter_bootscreen
|
|||||||
extrn _init
|
extrn _init
|
||||||
extrn _init_mm
|
extrn _init_mm
|
||||||
|
|
||||||
public _rd_base
|
extrn @init_heap@8
|
||||||
public _rd_fat
|
extrn @find_large_md@4
|
||||||
public _rd_fat_end
|
extrn @find_small_md@4
|
||||||
public _rd_root
|
extrn @phis_alloc@4
|
||||||
public _rd_root_end
|
extrn @mem_alloc@8
|
||||||
|
|
||||||
|
extrn _alloc_kernel_space@4
|
||||||
|
|
||||||
|
extrn _slab_cache_init
|
||||||
extrn _alloc_pages
|
extrn _alloc_pages
|
||||||
extrn _alloc_page
|
extrn _alloc_page
|
||||||
|
|
||||||
|
extrn _get_free_mem
|
||||||
|
|
||||||
|
alloc_kernel_space equ _alloc_kernel_space@4
|
||||||
|
|
||||||
extrn _bx_from_load
|
extrn _bx_from_load
|
||||||
|
|
||||||
section '.flat' code readable align 4096
|
section '.flat' code readable align 4096
|
||||||
@ -349,11 +362,15 @@ _high_code:
|
|||||||
|
|
||||||
; MEMORY MODEL
|
; MEMORY MODEL
|
||||||
|
|
||||||
call init_kernel_heap ; FIXME initialize heap after pager
|
|
||||||
|
|
||||||
call _init_mm
|
call _init_mm
|
||||||
mov [pg_data.pg_mutex], 0
|
mov [pg_data.pg_mutex], 0
|
||||||
|
|
||||||
|
call _slab_cache_init
|
||||||
|
|
||||||
|
mov ecx, 0x80000000
|
||||||
|
mov edx, 0x40000000
|
||||||
|
call @init_heap@8
|
||||||
|
|
||||||
mov esi, _16bit_start
|
mov esi, _16bit_start
|
||||||
mov ecx, _16bit_end
|
mov ecx, _16bit_end
|
||||||
shr ecx, 2
|
shr ecx, 2
|
||||||
@ -361,8 +378,6 @@ _high_code:
|
|||||||
cld
|
cld
|
||||||
rep movsd
|
rep movsd
|
||||||
|
|
||||||
xchg bx, bx
|
|
||||||
|
|
||||||
jmp far 0x60:_enter_bootscreen;
|
jmp far 0x60:_enter_bootscreen;
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
@ -379,8 +394,9 @@ __setvars:
|
|||||||
|
|
||||||
; SAVE & CLEAR 0-0xffff
|
; SAVE & CLEAR 0-0xffff
|
||||||
|
|
||||||
|
cld
|
||||||
xor esi, esi
|
xor esi, esi
|
||||||
mov edi,0x1F0000
|
mov edi,BOOT_VAR
|
||||||
mov ecx,0x10000 / 4
|
mov ecx,0x10000 / 4
|
||||||
rep movsd
|
rep movsd
|
||||||
xor edi, edi
|
xor edi, edi
|
||||||
@ -388,13 +404,22 @@ __setvars:
|
|||||||
mov ecx,0x10000 / 4
|
mov ecx,0x10000 / 4
|
||||||
rep stosd
|
rep stosd
|
||||||
|
|
||||||
|
mov edi, SLOT_BASE
|
||||||
|
mov ecx,0x10000 / 4
|
||||||
|
rep stosd
|
||||||
|
|
||||||
|
mov dword [_sys_pdbr], eax
|
||||||
|
mov dword [_sys_pdbr+4], eax
|
||||||
|
mov eax, cr3
|
||||||
|
mov cr3, eax
|
||||||
|
|
||||||
; SAVE REAL MODE VARIABLES
|
; SAVE REAL MODE VARIABLES
|
||||||
mov ax, [BOOT_VAR + 0x9031]
|
mov ax, [BOOT_VAR + 0x9031]
|
||||||
mov [IDEContrRegsBaseAddr], ax
|
mov [IDEContrRegsBaseAddr], ax
|
||||||
; --------------- APM ---------------------
|
; --------------- APM ---------------------
|
||||||
|
|
||||||
; init selectors
|
; init selectors
|
||||||
mov ebx, [BOOT_VAR +0x9040] ; offset of APM entry point
|
mov ebx, [BOOT_VAR +0x9040] ; offset of APM entry point
|
||||||
movzx eax, word [BOOT_VAR+0x9050] ; real-mode segment base address of
|
movzx eax, word [BOOT_VAR+0x9050] ; real-mode segment base address of
|
||||||
; protected-mode 32-bit code segment
|
; protected-mode 32-bit code segment
|
||||||
movzx ecx, word [BOOT_VAR+0x9052] ; real-mode segment base address of
|
movzx ecx, word [BOOT_VAR+0x9052] ; real-mode segment base address of
|
||||||
@ -788,7 +813,6 @@ include 'detect/disks.inc'
|
|||||||
|
|
||||||
; SET MOUSE
|
; SET MOUSE
|
||||||
|
|
||||||
;call detect_devices
|
|
||||||
stdcall load_driver, szPS2MDriver
|
stdcall load_driver, szPS2MDriver
|
||||||
; stdcall load_driver, szCOM_MDriver
|
; stdcall load_driver, szCOM_MDriver
|
||||||
|
|
||||||
@ -829,10 +853,10 @@ include 'detect/disks.inc'
|
|||||||
add esi, 0x1000
|
add esi, 0x1000
|
||||||
stdcall map_page,esi,(tss._io_map_1-OS_BASE), PG_MAP
|
stdcall map_page,esi,(tss._io_map_1-OS_BASE), PG_MAP
|
||||||
|
|
||||||
stdcall map_page,tss._io_map_0,\
|
; stdcall map_page,tss._io_map_0,\
|
||||||
(tss._io_map_0-OS_BASE), PG_MAP
|
; (tss._io_map_0-OS_BASE), PG_MAP
|
||||||
stdcall map_page,tss._io_map_1,\
|
; stdcall map_page,tss._io_map_1,\
|
||||||
(tss._io_map_1-OS_BASE), PG_MAP
|
; (tss._io_map_1-OS_BASE), PG_MAP
|
||||||
|
|
||||||
; mov ax,[OS_BASE+0x10000+bx_from_load]
|
; mov ax,[OS_BASE+0x10000+bx_from_load]
|
||||||
; cmp ax,'r1' ; if not rused ram disk - load network configuration from files {SPraid.simba}
|
; cmp ax,'r1' ; if not rused ram disk - load network configuration from files {SPraid.simba}
|
||||||
@ -842,17 +866,6 @@ include 'detect/disks.inc'
|
|||||||
|
|
||||||
; LOAD FIRST APPLICATION
|
; LOAD FIRST APPLICATION
|
||||||
|
|
||||||
cmp byte [BOOT_VAR+0x9030],1
|
|
||||||
jne no_load_vrr_m
|
|
||||||
|
|
||||||
mov ebp, vrr_m
|
|
||||||
call fs_execute_from_sysdir
|
|
||||||
|
|
||||||
cmp eax,2 ; if vrr_m app found (PID=2)
|
|
||||||
je first_app_found
|
|
||||||
|
|
||||||
no_load_vrr_m:
|
|
||||||
|
|
||||||
|
|
||||||
mov ebp, firstapp
|
mov ebp, firstapp
|
||||||
call fs_execute_from_sysdir
|
call fs_execute_from_sysdir
|
||||||
@ -1125,13 +1138,13 @@ endg
|
|||||||
|
|
||||||
set_variables:
|
set_variables:
|
||||||
|
|
||||||
mov ecx,0x100 ; flush port 0x60
|
mov ecx,0x100 ; flush port 0x60
|
||||||
.fl60: in al,0x60
|
.fl60: in al,0x60
|
||||||
loop .fl60
|
loop .fl60
|
||||||
mov [MOUSE_BUFF_COUNT],byte 0 ; mouse buffer
|
mov [MOUSE_BUFF_COUNT],byte 0 ; mouse buffer
|
||||||
mov [KEY_COUNT],byte 0 ; keyboard buffer
|
mov [KEY_COUNT],byte 0 ; keyboard buffer
|
||||||
mov [BTN_COUNT],byte 0 ; button buffer
|
mov [BTN_COUNT],byte 0 ; button buffer
|
||||||
; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y
|
; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y
|
||||||
|
|
||||||
push eax
|
push eax
|
||||||
mov ax,[BOOT_VAR+0x900c]
|
mov ax,[BOOT_VAR+0x900c]
|
||||||
@ -1142,11 +1155,11 @@ set_variables:
|
|||||||
mov [MOUSE_X],eax
|
mov [MOUSE_X],eax
|
||||||
pop eax
|
pop eax
|
||||||
|
|
||||||
mov [BTN_ADDR],dword BUTTON_INFO ; address of button list
|
mov [BTN_ADDR],dword BUTTON_INFO ; address of button list
|
||||||
|
|
||||||
;!! IP 04.02.2005:
|
;!! IP 04.02.2005:
|
||||||
mov [next_usage_update], 100
|
mov [next_usage_update], 100
|
||||||
mov byte [DONT_SWITCH], 0 ; change task if possible
|
mov byte [DONT_SWITCH], 0 ; change task if possible
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -1893,18 +1906,6 @@ sys_midi:
|
|||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
detect_devices:
|
|
||||||
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
;include 'detect/commouse.inc'
|
|
||||||
;include 'detect/ps2mouse.inc'
|
|
||||||
;include 'detect/dev_fd.inc'
|
|
||||||
;include 'detect/dev_hdcd.inc'
|
|
||||||
;include 'detect/sear_par.inc'
|
|
||||||
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
sys_end:
|
sys_end:
|
||||||
|
|
||||||
mov eax,[TASK_BASE]
|
mov eax,[TASK_BASE]
|
||||||
@ -2170,7 +2171,7 @@ sysfn_mouse_acceleration: ; 18.19 = set/get mouse features
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
sysfn_getfreemem:
|
sysfn_getfreemem:
|
||||||
mov eax, [pg_data.pages_free]
|
call _get_free_mem
|
||||||
shl eax, 2
|
shl eax, 2
|
||||||
mov [esp+32],eax
|
mov [esp+32],eax
|
||||||
ret
|
ret
|
||||||
|
@ -4,23 +4,31 @@ FASM = fasm.exe
|
|||||||
|
|
||||||
INCLUDE = include/
|
INCLUDE = include/
|
||||||
|
|
||||||
DEFS = -DUSE_SMP
|
DEFS = -DUSE_SMP -DCONFIG_DEBUG
|
||||||
|
|
||||||
CFLAGS = -c -O2 -DCONFIG_DEBUG -I $(INCLUDE) -fomit-frame-pointer -fno-builtin-printf -masm=intel
|
CFLAGS = -c -O2 -I $(INCLUDE) -fomit-frame-pointer -fno-builtin-printf -masm=intel
|
||||||
LDFLAGS = -shared -s -Map kernel.map --image-base 0x100000 --file-alignment 32
|
LDFLAGS = -shared -s -Map kernel.map --image-base 0x100000 --file-alignment 32
|
||||||
|
|
||||||
|
KERNEL_SRC:= \
|
||||||
|
kernel.asm \
|
||||||
|
core/memory.inc \
|
||||||
|
core/heap.inc \
|
||||||
|
core/taskman.inc \
|
||||||
|
core/sys32.inc \
|
||||||
|
core/dll.inc
|
||||||
|
|
||||||
KERNEL_SRC:= \
|
PE_SRC:= \
|
||||||
kernel.asm \
|
|
||||||
init.c \
|
init.c \
|
||||||
mm.c \
|
mm.c \
|
||||||
spinlock.c \
|
slab.c \
|
||||||
|
heap.c \
|
||||||
|
spinlock.c \
|
||||||
boot/boot.asm \
|
boot/boot.asm \
|
||||||
boot/start.asm
|
boot/start.asm
|
||||||
|
|
||||||
|
|
||||||
KERNEL_OBJS = $(patsubst %.s, bin/%.obj, $(patsubst %.asm, bin/%.obj,\
|
PE_OBJS = $(patsubst %.s, bin/%.obj, $(patsubst %.asm, bin/%.obj,\
|
||||||
$(patsubst %.c, bin/%.obj, $(KERNEL_SRC))))
|
$(patsubst %.c, bin/%.obj, $(PE_SRC))))
|
||||||
|
|
||||||
|
|
||||||
all: kernel.gz
|
all: kernel.gz
|
||||||
@ -28,8 +36,8 @@ all: kernel.gz
|
|||||||
kernel.gz :kernel.mnt
|
kernel.gz :kernel.mnt
|
||||||
7z a -tgzip kernel.gz kernel.mnt
|
7z a -tgzip kernel.gz kernel.mnt
|
||||||
|
|
||||||
kernel.mnt: $(KERNEL_OBJS) Makefile ld.x
|
kernel.mnt: kernel.obj $(PE_OBJS) Makefile ld.x
|
||||||
ld $(LDFLAGS) -T ld.x -o $@ $(KERNEL_OBJS)
|
ld $(LDFLAGS) -T ld.x -o $@ kernel.obj $(PE_OBJS)
|
||||||
|
|
||||||
bin/%.obj : core/%.c Makefile
|
bin/%.obj : core/%.c Makefile
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
@ -37,6 +45,9 @@ bin/%.obj : core/%.c Makefile
|
|||||||
bin/%.obj: %.asm
|
bin/%.obj: %.asm
|
||||||
$(FASM) $< $@
|
$(FASM) $< $@
|
||||||
|
|
||||||
|
kernel.obj: $(KERNEL_SRC)
|
||||||
|
$(FASM) kernel.asm
|
||||||
|
|
||||||
all: $(SUBDIRS)
|
all: $(SUBDIRS)
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
|
Loading…
Reference in New Issue
Block a user